Question

I'm having an issue removing the @Action and @Result Convention plugin annotations from an action and replacing them with the equivalent config in struts.xml.

package com.microed.cars.web;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

public class HomeAction extends ActionSupport {

    @Action(results = {
            @Result(location = "/jsp/home.jsp")
    })
    @Override
    public String execute() throws Exception {
        return super.execute();
    }
}

When these annotations are there, I can successfully access localhost:port/context/home.action

When I remove the annotations I get 'no result defined for action..... ' struts error, despite there being a 'capture all' result in struts.xml - the entire struts.xml is as follows:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
    "http://struts.apache.org/dtds/struts-2.1.dtd">

<struts>
    <constant name="struts.devMode" value="true"/>
    <constant name="struts.convention.package.locators" value="web"/>
    <constant name="struts.convention.default.parent.package" value="beetroot"/>

    <package name="beetroot" extends="json-default">

        <action name="home" class="homeAction">
            <result>/jsp/home.jsp</result>
        </action>

        <action name="cars" class="baseCarsAction">
            <result name="input" type="json">
                <param name="root">autoResults</param>
                /jsp/home.jsp
            </result>
        </action>
    </package>
</struts>

It extends json-default because I need the json result type for an autocomplete function.

I don't know why it's not picking up the action mapping for the homeAction class. I know struts.xml is being read because if I remove the action mapping "cars" then the autocomplete is disabled (but this needs the annotations which I'm trying to remove in order to validate this).

I know that 'no result defined' is a simple error, usually caused by spelling/capitalization errors but this is definitely not the case here, it's simply seems to be ignoring the whole "home" action mapping.

When stepping through DefaultActionInvocation.createResult, there are no 'results' at all for it to try to match against.

Was it helpful?

Solution

As it stands the cars action declaration isn't valid (nor does it make sense, IMO):

<action name="cars" class="baseCarsAction">
  <result name="input" type="json">
    <param name="root">autoResults</param>
    <param name="location">/jsp/home.jsp</param>
  </result>
</action>

That said: if it's a JSON result, a JSP isn't helpful, and it'll be ignored (or downright rejected, I'm not sure if it's an error or not). A single result will be either JSON, or HTML.

Turn logging up to DEBUG level to catch startup errors to narrow the range of possible causes.

If baseAction is configured in your Spring config file (which is unnecessary if you're using Spring annotations for injection) the configuration for the home action is valid.

I'd be wary of deploying the convention plugin if you're not actually using it: it changes how actions are mapped; it may have an impact on the surrounding application and cause problems. Stick with one or the other, avoid both–it makes it harder to reason about the source of application behavior.

Unrelated, but I recommend putting JSP pages under /WEB-INF to disallow direct client access.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top