Skip to content
Advertisement

Getting Result type in Interceptor

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

If needed to intercept the request, how to return a result based on given action result type?

For example, my Action.ERROR forwards to JSP page. If action is JSON type I want to forward JSON error instead.

Advertisement

Answer

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

For example, my Action.ERROR forwards to JSP page. If action is JSON type I want to forward JSON error instead. Please advice.

Although is true that an Action has not a type, it’s also true that, if an Action is called in an AJAX way, like an action returning JSON, all of its results should have the same result type (JSON in this case), unless you are using a single Action to perform different logical actions (ajax and non-ajax operations, that is an anti-pattern);

That said, if you want to return the proper GLOBAL error result, from inside an Interceptor that is used by all of your Actions (each one with its result type), based on their other result type (let’s say: SUCCESS, assuming every Action has a SUCCESS result), 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";
    }
}
    

        

Although this is technically possible, i would discourage it because… there is no real reason to do it;

For your purpose, remember that each global result is scoped in its <package>;

Since you could (/should) have two different packages for Classic Actions (a <package> extending struts-default) and JSON Actions (a <package> extending json-default), you can simply define two different global error result for each package with the same name but different result type; this way the Interceptor will call the one relative to the package of the current Action, outputting the desired kind of result.

Advertisement