action和servlet共存(转)

转自:http://www.cnblogs.com/nayitian/archive/2013/03/04/2942537.html

问题

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

实验了修改constant变量让action只针对拦截的指定后缀进行处理,使得servlet可以正常使用,亲测有效。其他需要时候试试。

<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‘,
    ......
时间: 2024-08-09 22:02:41

action和servlet共存(转)的相关文章

笔记01 登录、常用配置参数、Action访问Servlet API 和设置Action中对象的值、命名空间和乱码处理、Action中包含多个方法如何调用

Struts2登录 1. 需要注意:Struts2需要运行在JRE1.5及以上版本 2. 在web.xml配置文件中,配置StrutsPrepareAndExecuteFilter或FilterDispatcher 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <filter>     <filter-name>struts2</filter-name>     <filter-class>org.apache.struts2.di

struts2学习笔记之六(Action访问servlet的API以及复制项目小技巧)

action和servlet分离使得action代码更加纯洁,与servlet的耦合性也降低了 但是有时候却不得不访问servlet API,比如把数据放到session,application里, 更甚至于添加cookie(response.addCookie()) strust2提供了两种方式访问servlet api 伪访问 借助于ActionContext类 Map<String ,Object > getApplication() 模拟访问http application Map&l

让struts2和servlet共存

因为struts2默认的是拦截所有的请求 由配置文件可以看出 <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-n

在Java代码(非JSP及Action,Servlet,Controller)中获得WebRoot的物理路径

在开发Web方面的应用时, 经常需要获取 服务器中当前WebRoot的物理路径; 如果是Servlet , Action , Controller, 或则Filter , Listener , 拦截器等相关类时, 我们只需要获得ServletContext, 然后通过ServletContext.getRealPath("/")来获取当前应用在服务器上的物理地址. 如果在类中取不到ServletContext时, 有两种方式可以做到 1) 利用Java的类加载机制 调用 XXX.cla

struts2的action访问servlet API的三种方法

学IT技术,就是要学习... 今天无聊看看struts2,发现struts2的action访问servlet API的三种方法: 1.Struts2提供的ActionContext类 Object get(Object key);可以获取request属性 Map getSession():可以得到session属性 Map getAppliction():可以得到ServletContext实例 2.action类实现 ServletContextAware,ServletRequestAwa

Action访问Servlet API的三种方法

一.为什么要访问Servlet API ? Struts2的Action并未与Servlet API进行耦合,这是Struts2 的一个改良,从而方便了单独对Action进行测试.但是对于Web控制器而言,不访问action是不行的,Struts提供了一种比较简单的方式来访问Servlet API . 二.通常我们需要访问的Servlet API 是 HttpSession.HttpservletRequest.ServletContext,分别对应了JSP内置对象 session,reques

Action访问Servlet的API

Action访问Servlet的API_,主要访问如下: 1.>获取request对象 2.>获取请求参数 3.>获取response对象,可用于传递cookie 3.>获取作用域对象,request,Session,application,并设置共享数据, 访问方式一: 通过实现感知接口中的setter方法,讲其setter方法中的request参数传递到本类中来: 即,在本类中定义一个成员变量,来接收setter方法中的request. 如果,还需要获取response,Ses

struts2中Action访问servlet的两种方式

一.IoC方式 在struts2框架中,可以通过IoC方式将servlet对象注入到Action中,通常需要Action实现以下接口: a. ServletRequestAware: 实现该接口的Action可以直接访问Request对象,该接口中提供void setServletRequest(HttpServletRequest request) 方法,实现此接口的Action控制类通过setServletRequestHttpServlet(HttpServlet request)方法将r

Struts学习之路-第二天(Action与Servlet API)

Struts作为一款Web框架自然少不了与页面的交互,开发过程中我们最常用的request.application.session等struts都为我们进行了一定的封装与处理 一.通过ActionContext获取 方法 说明 void put(String key,Object value) 模拟HttpServletRequest中的setAttribute() Object get(Object key) 通过参数key查找当前ActionContext中的值 Map getApplica