Getting the result type in the Interceptor

I have Struts2 actions with different result types (HTML and JSON). They use a common interceptor.

If you need to intercept a query, how do you return a result based on a given action result type?

For example mine Action.ERROR

goes to JSP page. If the action is JSON, I want to send a JSON error.

+2


source to share


2 answers


I have Struts2 actions with different result types (HTML and JSON). They use a common interceptor. If you need to intercept a query, how do you return a result based on a given action result type?

For example my Action.ERROR will go to the JSP page. If the action is JSON, I want to send a JSON error. Please advice.

While it is true that the Action has no type, it is also true that if the Action is called in an AJAX way, as an action returning JSON, all of its results must have the same result type (JSON in this case), unless you use one action to perform different logical actions (ajax and non-ajax operations, which are anti-patterns);

However, if you want to return the correct GLOBAL error result , from within the Interceptor that is used by all your actions (each with a result type), based on their other (say: SUCCESS

assuming every action has a result SUCCESS

), this is the way to do it :

public String intercept(ActionInvocation invocation) throws Exception {

    // Get the action configuration defined in struts.xml
    ActionConfig config = invocation.getProxy().getConfig(); 

    // Get the SUCCESS result configured for that Action
    ResultConfig success = config.getResults().get("success");

    // Get the class of the SUCCESS result
    Object clazz = success.getClass(); 

    /* .... oops, some error occurred !! 
       We now need to redirect to the right global error result .... */

    if (clazz instanceof org.apache.struts2.dispatcher.ServletDispatcherResult) {
        log.debug("Struts2 Result type: CLASSIC");
        return "error";
    } else if (clazz instanceof org.apache.struts2.json.JSONResult) {
        log.debug("Struts2 Result type: JSON");
        return "jsonError";
    } else {
        log.debug("Struts2 Result type: SOMETHING ELSE, returning default ");
        return "error";
    }
}

      



While this is technically possible, I would discourage him because ... there is no real reason for this;

For your purpose, remember that every global result has a scope <package>

;

Since you could (/ should) have two different packages for classic actions (extension <package>

struts-default

) and JSON actions (a <package>

, extending json-default

), you can simply define two different global error results for each package with the same name but with a different result type ; thus, the Interceptor will call the one that packs the current Action, yielding the desired result.

0


source


In Struts2, the action is typeless. This means that you cannot customize the action type. Instead, you can customize the result types in the xml config. In the xml config file this is defined as a tag result-type

. When you customize a result with a tag result

, you specify an attribute type

that will be used to determine the appropriate result type. Let's say name="success"

or name="error"

are results of a result type dispatcher

.

When the action is intercepted, you can get the results



Map<String, ResultConfig> results =  actionInvocation.getProxy().getConfig().getResults();

      

The ResultConfig

there attribute className

, which can be used to define the type of the result.

+1


source







All Articles