问题

项目要求struts2和servlet能够共存,就是struts的请求发给struts处理,servlet的请求发给servlet处理。目前web.xml文件应该是类似于如下的配置: 

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

在请求应用时,struts2将会截获所有请求,对于servlet请求将不能够正常响应;原因是struts2把servlet当成action了,因为servlet和action都是没有后缀的。

解决(四种方式)

1. 修改servlet的相关配置,统一在servlet后面加上“.servlet”

1). 修改web.xml配置文件形如:

    <servlet>   
       <servlet-name>jqueryAjaxServlet</servlet-name>   
       <servlet-class>com.clzhang.sample.struts2.servlet.jQueryAjaxServlet</servlet-class>   
    </servlet>   
 
    <servlet-mapping>   
        <servlet-name>jqueryAjaxServlet</servlet-name>   
        <url-pattern>/servlet/jqueryAjax.servlet</url-pattern>   
    </servlet-mapping>

2).修改调用servlet的地方,形如:

    <% 
    String path = request.getContextPath(); 
    %> 
    ...... 
     
    $.ajax({    
    url:'<%=path%>/servlet/jqueryAjax.servlet',    
    ......

这样就可以正常处理servlet的请求了。此种情况适合于小范围使用servlet的情况。

2. 修改拦截页面配置,就是将struts的相关拦截配置一下

修改web.xml文件如下内容:

    <filter-mapping> 
        <filter-name>struts2</filter-name> 
        <url-pattern>*.action</url-pattern> 
    </filter-mapping> 
    <filter-mapping> 
        <filter-name>struts2</filter-name> 
        <url-pattern>*.do</url-pattern> 
    </filter-mapping> 
    <filter-mapping> 
        <filter-name>struts2</filter-name> 
        <url-pattern>*.jsp</url-pattern> 
    </filter-mapping> 
    <filter-mapping> 
        <filter-name>struts2</filter-name> 
        <url-pattern>/user/*</url-pattern> 
    </filter-mapping>

这样也同样可以正常处理servlet的请求。此种情况可能随着项目的扩大,而需要再次修改此配置文件。

3. 修改struts.xml文件中的后缀映射

<constant name="struts.action.extension" value="action"></constant>

4. 自定义Filter实现过滤

1).创建实现类,代码参考如下:

package com.clzhang.sample.struts2; 
 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Arrays; 
import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.RequestDispatcher; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest; 
 
/** 
 * 这是一个过滤servlet的filter;就是拦截servlet的处理请求,自行转向处理,而不是由struts处理。 
 * 有二种过滤方式,一种是判断uri中是否包含“/servlet/”; 
 * 另一种是所有servlet在初始化参数中指定。 
 * 需要在web.xml中配置: 
    <filter> 
        <filter-name>redisp</filter-name> 
        <filter-class>com.clzhang.sample.struts2.FilterServlet</filter-class> 
        <!--如果使用第二种方式过滤,则需要下面的代码 
        <init-param> 
            <param-name>includeServlets</param-name> 
            <param-value>jqueryAjax,jsonView</param-value> 
        </init-param> 
        --> 
    </filter> 
     
    <filter-mapping> 
        <filter-name>redisp</filter-name> 
        <url-pattern>/*</url-pattern> 
    </filter-mapping> 
    并且此过滤器必须在struts2的过滤器上面。 
 * @author Administrator 
 * 
 */ 
public class FilterServlet implements Filter { 
    public void destroy() { 
    } 
     
    public void doFilter(ServletRequest req, ServletResponse resp, 
            FilterChain chain) throws IOException, ServletException { 
        HttpServletRequest request = (HttpServletRequest) req; 
         
        // 第一种方式(二选 一) 
        String target = request.getRequestURI(); 
        target = target.lastIndexOf("?") > 0 ? target.substring( 
                target.lastIndexOf("/") + 1, 
                target.lastIndexOf("?") - target.lastIndexOf("/")) : target 
                .substring(target.lastIndexOf("/") + 1); 
        if (request.getRequestURI().indexOf("/servlet/") > 0) { 
            // request.getRequestURI()格式应该形如:/st/servlet/jqueryAjax, 
            // 其中st是项目名,servlet是所有servlet都增加的前缀,用于能够判断出是servlet。 
            // if只判断请求uri是否包含/servlet/,如果包含则处理; 
            RequestDispatcher rdsp = request.getRequestDispatcher(target); 
            rdsp.forward(req, resp); 
        } else { 
            chain.doFilter(req, resp); 
        } 
 
        // 第二种方式 (二选 一) 
        /** 
        if (this.includes.contains(target)) { 
            // target取出的值则直接是jqueryAjax,在web.xml中配置即可。 
            // if判断请求uri最后的那部分是否包含在配置文件中,如果包含,则处理 
            RequestDispatcher rdsp = request.getRequestDispatcher(target); 
            rdsp.forward(req, resp); 
        } else { 
            chain.doFilter(req, resp); 
        } 
        */ 
    } 
 
    private ArrayList<String> includes = new ArrayList<String>(); 
 
    public void init(FilterConfig config) throws ServletException { 
        // 如果使用第二种方式过滤,则需要以下代码 
//        this.includes.addAll(Arrays.asList(config.getInitParameter( 
//                "includeServlets").split(","))); 
    } 
}

2).修改web.xml,类似如下格式:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
    <filter> 
        <filter-name>redisp</filter-name> 
        <filter-class>com.clzhang.sample.struts2.FilterServlet</filter-class> 
        <!--如何使用第二种方式过滤,则需要下面的代码 
        <init-param> 
            <param-name>includeServlets</param-name> 
            <param-value>jqueryAjax,jsonView</param-value> 
        </init-param> 
        --> 
    </filter> 
     
    <filter-mapping> 
        <filter-name>redisp</filter-name> 
        <url-pattern>/*</url-pattern> 
    </filter-mapping> 
 
    <filter> 
        <filter-name>struts2</filter-name> 
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> 
    </filter> 
 
    <filter-mapping> 
        <filter-name>struts2</filter-name> 
        <url-pattern>/*</url-pattern> 
    </filter-mapping> 
         
    <servlet>   
        <servlet-name>jqueryAjaxServlet</servlet-name>   
        <servlet-class>com.clzhang.sample.struts2.servlet.jQueryAjaxServlet</servlet-class>   
    </servlet>   
 
    <servlet-mapping>   
        <servlet-name>jqueryAjaxServlet</servlet-name>   
        <url-pattern>/servlet/jqueryAjax</url-pattern>   
    </servlet-mapping> 
 
    <servlet>   
        <servlet-name>jsonViewServlet</servlet-name>   
        <servlet-class>com.clzhang.sample.struts2.servlet.JsonViewServlet</servlet-class>   
    </servlet>   
     
    <servlet-mapping>   
        <servlet-name>jsonViewServlet</servlet-name>   
        <url-pattern>/servlet/jsonView</url-pattern>   
    </servlet-mapping>    
 
    <welcome-file-list> 
        <welcome-file>index.jsp</welcome-file> 
        <welcome-file>index.html</welcome-file> 
    </welcome-file-list> 
</web-app>

注意,<filter-name>redisp</filter-name>必须放置于<filter-name>struts2</filter-name>之前,这样才能够保证它们能够按照正常的顺序处理,否则会出错。

3). 而在需要引用servlet的地方,正常引用即可,如在JSP页面中调用:

    <% 
    String path = request.getContextPath(); 
    %> 
    ...... 
     
    $.ajax({    
    url:'<%=path%>/servlet/jqueryAjax',    
    ......

 

本文参考:

http://www.blogjava.net/xcp/archive/2012/08/05/384824.html

http://zhyx5017192.blog.163.com/blog/static/309251282012111985237499/

发布评论

分享到:

IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

struts2:图解action之HelloWorld示范(从action转到JSP)详解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。