In Struts2, how to perform permanent redirects (status code 301) without having a parameter appearing in the url

I have a Struts2 web application (version 2.2.3). I am trying to redirect old links to new pages. I know I can make it through

    <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

to the final redirected url. I don't want this to happen. So I implemented some other approaches, but it didn't work.

eg. I tried to set status

in the response object before returning from the action like so:

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

      

It didn't 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 that didn't work. I was still getting 302 status for the link.

I also looked at redirect type=httpheader

. But I don't think this is exactly what I want. Since I need to submit a 301 along with the content of the redirected page i.e. the new link.

There are some mentions of subclassing org.apache.struts2.dispatcher.ServletActionRedirectResult

and then adding statusCode

to the prohibited list. But I don't know how to introduce this custom RedirectResult

into the workflow.

Any help is appreciated.

UPDATE I posted the answer below.

+3


source to share


2 answers


It looks like it is statusCode

not removed from the parameter list while processing the result.

To use your own result type, simply define it as any other result type and use it instead redirectAction

. This is discussed in the Result Tuning Docs . You should just override getProhibitedResultParams()

and add statusCode

to the list.



This list should contain the IMO status code. There's a JIRA ticket for this already .

+3


source


If anyone has the same problem as me, I solved it based on Dave's answer .

First, declare a result type in your package where you will call that result type.

    <result-types>
       <result-type name="premanentRedirectAction" 
                    class="management.dispatcher.ServletActionPermanentRedirectResult" />
    </result-types>

      

And then just just define the type of the result, like:



package management.dispatcher;
import java.util.List;
import org.apache.struts2.dispatcher.ServletActionRedirectResult;
import com.google.common.collect.Lists;

public class ServletActionPermanentRedirectResult extends ServletActionRedirectResult {

private static final long serialVersionUID = 4921150146065435746L;

@Override
protected List<String> getProhibitedResultParams() {
    List<String> prohibitedResultParams = Lists.newArrayList(super.getProhibitedResultParams());
    prohibitedResultParams.add("statusCode");

    return prohibitedResultParams;
   }
   }

      

And then wherever you want to redirect from 301 if the old activity has the following display -

    <action name="media-coverage">
        <result type="premanentRedirectAction">
            <param name="actionName">press</param>
            <param name="namespace">/</param>
            <param name="statusCode">301</param>
        </result>
    </action>

      

0


source







All Articles