jspservletsstruts2actionresultvaluestack

How to redirect request after logoff in Struts 2


The project has a servlet which is called when a person logs out.

public class LogonServlet extends HttpServlet {

private static final long serialVersionUID = -4899047924930198118L;

public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    setFirmAndRedirect(request, response);
}

public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    setFirmAndRedirect(request, response);
}

private void setFirmAndRedirect(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
    String firm;
    String serverPath = request.getServletPath();

    firm = serverPath.replaceAll("/", "").replaceAll(".logon", "").trim()
                     .toLowerCase();

    request.setAttribute("firm", firm);

    RequestDispatcher dispatcher = request.getRequestDispatcher("/logon.do");
    dispatcher.forward(request, response);
}
}

The servlet tries to forward the request to logon.do action of Struts.

Following is my web.xml file:

<web-app>
  <context-param>
    <param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
    <param-value>/WEB-INF/tiles-defs.xml</param-value>
  </context-param>
    
  <filter>
    <filter-name>HibernateSessionFilter</filter-name>
    <filter-class>com.rolfeandnolan.ccp.filters.HibernateSessionFilter</filter-class>
  </filter>

    <!-- Struts 2 -->
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  
  <!-- Should only apply to Alerts Direct requests -->
  <filter-mapping>
    <filter-name>HibernateSessionFilter</filter-name>
    <url-pattern>*.do</url-pattern>
  </filter-mapping>
  
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <servlet>
    <servlet-name>logon</servlet-name>
    <servlet-class>com.rolfeandnolan.ccp.servlets.LogonServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>logon</servlet-name>
    <url-pattern>*.logon</url-pattern>
  </servlet-mapping>

The LogonServlet is used to serve the logout requests as per following struts.xml:

   <action name="logoff"
           class="com.rolfeandnolan.ccp.struts.actions.LogoffAction">
           <param name="allowedRoles">admin,margin,alerts,limitadmin,workfloweditor,eval,theocalc,stress,alertscustomer,useradmin</param>
       <result name="success">/logon.jsp</result>
       <result name="firmlogon" type="dispatcher">
        <param name="location">${firm}.logon</param>
       </result>
    
   </action>

On forwarding, it is giving 404 error:

HTTP Status 404 - /ccpserver/logon.do type Status report message /ccpserver/logon.do description The requested resource (/ccpserver/logon.do) is not available. JBoss Web/2.1.3.GA

While hitting the direct URL http://localhost:8080/ccpserver/logon.do, it is working fine.


Solution

  • If you have firm value in the valueStack then you don't need a servlet. After log off you should redirect to the login action using a redirect type result.

    Redirect Action Result

    This result uses the ActionMapper provided by the ActionMapperFactory to redirect the browser to a URL that invokes the specified action and (optional) namespace. This is better than the ServletRedirectResult because it does not require you to encode the URL patterns processed by the ActionMapper in to your struts.xml configuration files. This means you can change your URL patterns at any point and your application will still work. It is strongly recommended that if you are redirecting to another action, you use this result rather than the standard redirect result.

    See examples below for an example of how request parameters could be passed in.

    <package name="passingRequestParameters" extends="struts-default" namespace="/passingRequestParameters">
       <!-- Pass parameters (reportType, width and height) -->
       <!--
       The redirectAction url generated will be :
       /genReport/generateReport.action?reportType=pie&amp;width=100&amp;height=100#summary
       -->
       <action name="gatherReportInfo" class="...">
          <result name="showReportResult" type="redirectAction">
             <param name="actionName">generateReport</param>
             <param name="namespace">/genReport</param>
             <param name="reportType">pie</param>
             <param name="width">100</param>
             <param name="height">100</param>
             <param name="empty"></param>
             <param name="suppressEmptyParameters">true</param>
             <param name="anchor">summary</param>
          </result>
       </action>
    </package>
    

    See ActionMapper for more details.


    You can code something

    <result name="firmlogon" type="redirectAction">
        <param name="actionName">logon</param>
        <param name="namespace">/</param>
        <param name="firm">${firm}</param>
    </result>