Monday, 16 May 2011

Custom Action Mapper (Struts 2 + Axis 2)

Consider your Web Application Deployment Descriptor is configured in such a way that all your urls (/*) are mapped to struts framework and you want the urls of the pattern "/webservice/*" to be handled using web service framework. If this is the case then your web.xml will look like this:


<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
    ......................................
    ......................................

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>AxisServlet</servlet-name>
        <display-name>Apache-Axis Servlet</display-name>
        <servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
        <load-on-startup>3</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>AxisServlet</servlet-name>
        <url-pattern>/webservice/*</url-pattern>
    </servlet-mapping>
    
    ......................................
    ......................................
</web-app>

Now to ignore the web service requests from struts side you need to write a custom action mapper:


package com.jbasics;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
import com.opensymphony.xwork2.config.ConfigurationManager;

public class CustomActionMapper extends DefaultActionMapper{

    @Override
    public ActionMapping getMapping(HttpServletRequest req,
                            ConfigurationManager configMgr) {
        String uri = getUri(req);
        if(uri != null && !uri.isEmpty() 
                        && uri.contains("/webservice"))
            return null;
        else
            return super.getMapping(req, configMgr);
    }
}
Finally you need to add an entry for this in the struts.properties file:

struts.mapper.class=com.jbasics.CustomActionMapper

4 comments:

  1. Hi Anuja,

    thanks for this useful post. I have a question for you: what do you mean when talk about "struts.properties file"?

    In my web application I have struts.xml file (where all my actions are mapped) and ApplicationResources.properties file (where all the label used in web pages are stored in the form key=value).

    Now, where (and how) do I have to add the entry you write above?

    thanks and regards,
    g

    ReplyDelete
  2. Add the following into your struts.xml file:

    <constant name="struts.mapper.class" value="com.jbasics.CustomActionMapper"/>

    Alternatively, you can create struts.properties file in the same folder where you have struts.xml file and the framework will automatically load the configurations. Please note that the struts.properties file is provided for backward-compatiblity with WebWork.

    ReplyDelete
  3. Hi Anuja,

    many thanks for your answer. Now it works fine!
    I have modified my struts.xml how you said above.

    Actually, as a workaround, I have tried to modify the struts library (struts2-core-2.2.3.jar) by adding in file \org\apache\struts2\default.properties this entry

    struts.mapper.class=

    and it works as well, but manage jar file is not a good thing! I guess your solution is better.

    Thanks and regards!

    bye,
    g

    ReplyDelete