1. 程式人生 > >struts2和servlet共存的幾種方法

struts2和servlet共存的幾種方法

專案要求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都是沒有後綴的。

解決(四種方式):
方式一:修改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的情況。

方式二:修改攔截頁面配置,就是將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的請求。此種情況可能隨著專案的擴大,而需要再次修改此配置檔案。

方式三:修改struts.xml檔案中的字尾對映

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

方式四:自定義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>之前,這樣才能夠保證它們能夠按照正常的順序處理,否則會出錯。

而在需要引用servlet的地方,正常引用即可,如在JSP頁面中呼叫:

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