Search code examples
javahttp-redirectstruts2http-status-code-301

In Struts2 how to do permanent redirects (status code 301) without having the parameter appearing in the URL


I have a Struts2 (version 2.2.3) web application. I am trying to redirect old links to new pages. I know I can do this via

    <action name="old-action" class="MVRActionClass">
        <result type="redirectAction">
            <param name="actionName">new-action</param>
            <param name="namespace">/new-action-namespace</param>
            <param name="statusCode">301</param>
        </result>
    </action>  

But this adds a parameter statusCode=301 in the final redirected url. I do not want this to happen. So I implemented some other approaches but it did not work out.

E.g. I tried to set the status in the response object before returning from the action like so -

@Override
public String execute() {
    ...     
    ((HttpServletResponse) response).setStatus(301);
    return SUCCESS;
}

This did not work. I was still getting 302 status for the link. Then I created an Interceptor and added a PreResultListener to it like so -

public class MyInterceptor extends AbstractInterceptor {

@Override
public String intercept(ActionInvocation invocation) throws Exception {

  invocation.addPreResultListener(new PreResultListener() { 
    @Override
    public void beforeResult(ActionInvocation invocation, String resultCode) {

      try {
    ActionContext actionContext = invocation.getInvocationContext();

    HttpServletResponse response = (HttpServletResponse).actionContext.get(StrutsStatics.HTTP_RESPONSE);

     response.setStatus(301);
     actionContext.put(StrutsStatics.HTTP_RESPONSE, response);


      } catch(Exception e) {
        invocation.setResultCode("error");
      }
    }
  });

  // Invocation Continue
      return invocation.invoke();
    }
  }
}

Even this did not work. I was still getting 302 status for the link.

I also looked in to redirect type=httpheader. But I dont think it is what I want exactly. Since I need to send 301 along with content of the redirectedTo page i.e. new link.

There is some mention of subclassing org.apache.struts2.dispatcher.ServletActionRedirectResult and then adding statusCode to the prohibited list. But I do not know how to inject this custom RedirectResult in the workflow.

Any help is appreciated.

UPDATE I have posted the answer below.


Solution

  • It looks like statusCode isn't removed from the parameter list during result processing.

    To use your own result type, just define it as any other result type and use it instead of redirectAction. This is discussed in the Result Configuration docs. You should just be able to override getProhibitedResultParams() and add statusCode to the list.

    IMO statusCode should be on that list. There's a JIRA ticket for this already.