跳转路径问题,Filter,Listener,

本文深入解析Servlet中的跳转路径概念,包括绝对与相对路径的区别,以及Filter和Listener的作用与配置。涵盖过滤器的生命周期、责任链模式,设置编码实例,登录权限验证等,同时介绍监听器在获取在线人数、登录人数及服务器启动停止的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 跳转路径问题

当我们在servlet中,跳转到其他页面,会使用重定向,或请求转发,这又分为绝对路径(前面带/),相对路径

(1)绝对路径(前面带/):

  1. 请求转发request.getRequestDispatcher("/login.jsp").forward(request, response);
    则跳转后的路径是:工程目录/longin.jsp :
 例如: http://127.0.0.1:8080/项目名/login.jsp
  1. 重定向response.sendRedirect("/login.jsp");
    则跳转后的路径是:IP服务器目录/longin.jsp :
 例如: http://127.0.0.1:8080/login.jsp
  1. 对于项目名,我们可以通过String context = request.getContextPath();来获取:
 String context = request.getContextPath();
 response.sendRedirect(context+"/login.jsp");

(2) 相对路径:不是/开头,相对当前访问的目录

对于重定向与请求转发:效果是一样的

response.sendRedirect("login.jsp");
request.getRequestDispatcher("login.jsp").forward(request, response);

当前目录指的是现在访问的路径从后往前的第一个/
例如:http://127.0.0.1:8080/项目名/admin/index.jsp里进行跳转,
跳转后的路径:http://127.0.0.1:8080/项目名/admin/login.jsp

(3)其他,过滤器的过程

  1. 在一个过滤器里(@WebFilter("/admin/*")),我们对这个路径进行过滤,
  2. 没有登录不可以进入这个目录下,并跳转到项目下的login.jsp登录页面:重定向实现
	// 对于未登录,进行下面的跳转会造成死循环
	resp.sendReidrect("login.jsp")
  1. 为何会造成死循环,不符合:重定向(http://127.0.0.1:8080/项目名/admin/login.jsp),再次被过滤(再次不符合),又一次重定向…
    在这里插入图片描述
  2. 假设用请求转发实现,则如果admin/下有login.jsp页面则会跳转到那个页面,如果没有则会报404错误
  3. 因为请求转发是服务器内部跳转,而过滤器是过滤客户端访问的web资源,所以通过。
  4. 跳转到:http://127.0.0.1:8080/项目名/admin/login.jsp

二. 过滤器Filter

(1)基本配置实现(xml)

  1. 类实现Filter 接口
public class Demo implements Filter {}
  1. xml配置
	<filter>
        <filter-name>filter</filter-name>
        <filter-class>fil.Demo</filter-class>
        <init-param>
            <param-name>charset</param-name>
            <param-value>utf-8</param-value>
        </init-param>
	</filter>
	<filter-mapping>
        <filter-name>filter</filter-name>
        <url-pattern> /* </url-pattern>
	</filter-mapping>
  1. 加载时间问题
    加载时间:服务器启动时加载 实例化 初始化
    如果Servlet和Filter 谁先启动: 先Filter再Servlet
  2. chain.doFilter(request, response);作用是什么?
    chain可以被称为放行,它的作用是让其进入下一个过滤器或servlet(调用后续的过滤器或资源)

(2)生命周期

加载和实例化构造方法1次
初始化init()1次
过滤doFilter()多次
销毁destroy()1次

(3)责任链的先后顺序

什么是过滤器链?
很多Filter都是拦截所有的请求,即很多Filter的命中规则都是一样的,那么怎么办?
过滤器链中的过滤器,进入的顺序和配置映射的先后顺序有关。<filter-mapping>

(4)设置编码实例

  1. 做一个设置编码的过滤器
  2. xml配置
	<filter>
        <filter-name>filter</filter-name>
        <filter-class>fil.Demo</filter-class>
        <init-param>
            <param-name>requestCharset</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>responseCharset</param-name>
            <param-value>text/html;charset=utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
package fil;

import javax.servlet.*;
import java.io.IOException;

public class Demo implements Filter {
    private String requestCharset;
    private String responseCharset;
    @Override
    public void init(FilterConfig conf){
        requestCharset = conf.getInitParameter("requestCharset");
        responseCharset = conf.getInitParameter("responseCharset");
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        /*过滤方法 主要是对request和response进行一些处理,
        然后交给下一个过滤器或Servlet处理*/
        req.setCharacterEncoding(requestCharset);
        resp.setContentType(responseCharset);
        chain.doFilter(req,resp);
    }
}

  1. 设置一个可以过滤未登录的过滤器
package fil;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebFilter(filterName = "Demo2" ,urlPatterns = "/admin/*" )
// 在项目下的admin/*目录是只有登录后才可以访问
public class Demo2 implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {

        HttpServletRequest request =  (HttpServletRequest)req;
        HttpServletResponse response =  (HttpServletResponse)resp;
        
        // 获取session参数里的true:没有session会产生一个新的session
        // false: 没有session会返回null
        HttpSession session = request.getSession(false);
        
        // 登录过的session里面会存储loginuser属性
        if (session == null || session.getAttribute("loginuser") == null){
        
            // 如果没有让其跳转到登录页面
            String context = request.getContextPath(); // 获取项目名
            System.out.println(context);
            
            //response绝对路径  /表示ip地址,从ip开始找路径资源
            response.sendRedirect(context+"/login.jsp");
        }else {
        
            // 有则放行
            chain.doFilter(req,resp);
        }
    }
}

  1. 登录控制器
/**
 * 控制器 : 登录请求
 */
@WebServlet(value = "/LoginServlet")
public class LoginServlet extends HttpServlet {

	private UserService service = new UserService();
	@Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//接收请求
		String uname = request.getParameter("username");
		String upass = request.getParameter("password");

		//封装实体类
		User user = new User();
		user.setPassword(upass);
		user.setUsername(uname);

		//调用业务
		User u = service.login(user);

		//根据结果 判断 跳转
		if(u!=null) {
			//登录成功
			HttpSession session = request.getSession(true);
			//session必须得有session? false
			session.setAttribute("loginuser", u);
			response.sendRedirect("admin/");
		}else {
			//登录失败
			request.setAttribute("msg", "用户名或密码有误!");
			request.getRequestDispatcher("login.jsp").forward(request, response);
		}
	}

	@Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

(5)作用

  1. 登录权限验证
  2. 资源访问权限控制
  3. 敏感词汇过滤
  4. 字符编码转换等等操作
	// 乱码问题:区分请求乱码和响应乱码
	request.setCharacterEncoding(charset);
	response.setContentType("text/html;charset=utf-8");

用户授权的Filter: Filter负责检查用户请求,根据请求过滤用户非法请求。
日志Filter: 详细记录某些特殊的用户请求。
负责解码的Filter: 包括对非标准编码的请求解码。
Filter可拦截多个请求或响应;一个请求或响应也可被多个请求拦截。

三. 监听器Listener

(1)获取在线人数

  1. xml配置:
<listener>
        <listener-class>listener.LisDemo1</listener-class>
    </listener>
  1. 类,监听session
    HttpSessionListener
package listener;

import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
 * session生命周期监听器
 * 在线统计人数
 * 把人数放入application上下文
 *
 * 当第一次访问jsp页面时候执行这里
 */
@WebListener
// @WebListener 注册监视器,告知容器,观察者模式
public class LisDemo1 implements HttpSessionListener {
    /**
     * session被创建时候执行这里
     */
     @Override
     public void sessionCreated(HttpSessionEvent se) {
         HttpSession session = se.getSession();
         System.out.println("session创建了---"+session.getId());
//         获取上下文对象
         ServletContext application = session.getServletContext();
         Integer count = (Integer) application.getAttribute("onlineCount");
         if (count == null){
             count = 0;
         }
         count++;
         application.setAttribute("onlineCount",count);
     }
    /**
     * session被销毁时候,超时执行这里
     */
     @Override
     public void sessionDestroyed(HttpSessionEvent se) {
         HttpSession session = se.getSession();
         System.out.println("session销毁了======="+session.getId());
         ServletContext application =  session.getServletContext();
         Integer count =  (Integer)application.getAttribute("onlineCount");
         if(count != null) {
             count--;
         }
         application.setAttribute("onlineCount", count);
     }
}
  1. 在xml设置全局session超时(失效)时间
<!--设置session最大超时时间,单位为分钟-->
    <session-config>
        <session-timeout>1</session-timeout>
 </session-config>

(2)获取登录人数

实体类实现接口HttpSessionBindingListener
User implements HttpSessionBindingListener

package cn.mvc.entity;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

/**
 * valueUnbound的触发条件是以下三种情况:
 * 1. 执行session.invalidate()时。
 * 2. session超时,自动销毁时。
 * 3. 执行session.setAttribute("loginuser", "其他对象");
 *  或session.removeAttribute("loginuser");将listener从session中删除时。
 */
public class User implements HttpSessionBindingListener {
    private String username;
    private String password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    // 绑定值时候执行,即登录成功(会员人数)
    // session.setAttribute("loginuser", user);
     @Override
     public void valueBound(HttpSessionBindingEvent event) {
         HttpSession session = event.getSession();
         System.out.println("session---放入了值user"+session.getId()+"----"+session.getAttribute("loginuser"));
//         获取上下文对象
         ServletContext application = session.getServletContext();
         Integer count = (Integer) application.getAttribute("loginuser");
         if (count == null){
             count = 0;
         }
         count++;
         application.setAttribute("loginuser",count);
     }
    // 解除值时候执行
    // 在执行销毁session时候,就会执行remove,相当于对象不在了,对象的属性也不存在
    // session.removeAttribute("loginuser);
     @Override
     public void valueUnbound(HttpSessionBindingEvent event) {
         HttpSession session = event.getSession();
         System.out.println("session销毁了=======放入了值user"+session.getId()+"----"+session.getAttribute("loginuser"));
         ServletContext application =  session.getServletContext();
         Integer count =  (Integer)application.getAttribute("loginuser");
         if(count != null) {
             count--;
         }
         application.setAttribute("loginuser", count);
     }
}

(3) 监听服务器启动和停止

ServletContextListener

/**
 *  监听服务器启动和停止
 *
 */
@WebListener
public class GlobalListener implements ServletContextListener {
    /**
     * 服务器停止时 执行这里
     */
    @Override
    public void contextDestroyed(ServletContextEvent sce)  {
        System.out.println("=======%%%%% 服务器停止 %%%%=========");
    }
    /**
     * 服务器启动时执行这里
     */
    @Override
    public void contextInitialized(ServletContextEvent sce)  {
        System.out.println("$$$$$$$$$$$$$ 服务器启动了 $$$$$$$$$$");
        //获取上下文
        ServletContext application =  sce.getServletContext();
        //获取上下路径
        String contextPath = application.getContextPath();
        System.out.println(">>>>==="+contextPath);
        application.setAttribute("contextPath", contextPath);
        //加载
        loadConfig();
    }
    /**
     * 加载配置文件
     */
    private void loadConfig() {
        InputStream in = this.getClass().getResourceAsStream("/db.properties");
//        Properties p = new Properties();
//        try {
//            p.load(in);
//
//            Config.driver = p.getProperty("driver");
//            Config.url = p.getProperty("url");
//            Config.username = p.getProperty("username");
//            Config.password = p.getProperty("password");
//
//        } catch (IOException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
    }
}

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name></display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:applicationContext*.xml classpath*:*Context.xml </param-value> </context-param> <context-param> <param-name>webAppRootKey</param-name> <param-value>rms.root</param-value> </context-param> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/classes/log4j.properties</param-value> </context-param> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>60</param-value> </context-param> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>com.hg.filter.UrlAuthListen</listener-class> </listener> <listener> <listener-class>com.hg.filter.WebConfigListener</listener-class> </listener> <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter </filter-class> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</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> <filter> <filter-name>XssFilter</filter-name> <filter-class>com.hg.aop.XssFilter</filter-class> </filter> <filter-mapping> <filter-name>XssFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- dwr 配置 --> <servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>crossDomainSessionSecurity</param-name> <param-value>false</param-value> </init-param> <init-param> <description>How quickly do scriptSessions timeout?</description> <param-name>scriptSessionTimeout</param-name> <param-value>1800000</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> <listener> <listener-class>org.directwebremoting.servlet.EfficientShutdownServletContextAttributeListener</listener-class> </listener> <!-- dwr 配置 --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>具体解释一下web.xml的配置
最新发布
07-08
<think>好的,我现在需要解释用户提供的web.xml配置文件的具体内容。首先,我需要回忆一下web.xml的基本结构和各个元素的作用。用户提供的这个配置文件是一个标准的Java Web应用的部署描述符,版本是3.0,所以可能使用了一些Servlet 3.0的特性,但这里主要是传统的配置方式。 首先看根元素<web-app>,它的命名空间和schemaLocation指定了使用的规范版本,这里是3.0。接下来是<display-name>,这里为空,可能是应用的显示名称。 接下来是多个<context-param>元素,这些是上下文参数,由Servlet容器(如Tomcat)加载,供应用中的组件使用。第一个context-param的param-name是contextConfigLocation,param-value指定了Spring应用上下文的配置文件位置,这里包括classpath下所有以applicationContext开头的XML文件和所有以Context结尾的XML文件,这样Spring的ContextLoaderListener会加载这些配置来初始化ApplicationContext。 第二个context-param是webAppRootKey,设置为rms.root,这通常用于将Web应用的根路径(如Tomcat的webapps下的应用目录)设置为一个系统属性,方便其他组件(如日志配置)引用,例如log4j中可能用${rms.root}获取路径。 第三个和第四个context-param是log4j的配置,log4jConfigLocation指定log4j的配置文件路径在/WEB-INF/classes/log4j.properties,log4jRefreshInterval设置为60秒,即每隔60秒自动刷新log4j的配置,这样修改日志配置后不需要重启应用。 接下来是<listener>元素,定义了多个监听器。第一个是Log4jConfigListener,用于初始化log4j的配置,读取前面的log4j相关context-param。第二个是ContextLoaderListener,这是Spring的监听器,负责根据contextConfigLocation加载Spring的应用上下文,是Spring Web应用的核心监听器。后面两个监听器是自定义的,com.hg.filter.UrlAuthListen和WebConfigListener,可能用于URL权限验证和Web配置初始化。 然后是<filter>和<filter-mapping>配置。第一个filter是openSessionInViewFilter,类是Spring ORM Hibernate4的OpenSessionInViewFilter,用于解决Hibernate的“延迟加载在视图层失败”的问题。设置singleSession为true,表示每个请求使用一个Hibernate Session,通常在Web应用中用于在请求处理期间保持Session打开,直到视图渲染完成。 第二个filter是struts2的StrutsPrepareAndExecuteFilter,这是Struts 2的核心过滤器,负责处理所有请求,解析Action、执行拦截器链等,url-pattern为/*,表示所有请求都由Struts处理。 第三个filter是自定义的XssFilter(跨站脚本攻击过滤器),类是com.hg.aop.XssFilter,用于过滤请求中的XSS攻击,例如转义特殊字符,保护应用安全,同样映射到所有URL。 接下来是dwr(Direct Web Remoting)的配置,这是一个用于JavaJavaScript互操作的库。定义了一个名为dwr-invoker的Servlet,类是DwrServlet,配置了debug模式(允许调试)、activeReverseAjaxEnabled(启用反向Ajax,服务器向客户端推送)、crossDomainSessionSecurity(跨域会话安全,这里设为false)、scriptSessionTimeout(脚本会话超时时间,1800000毫秒即30分钟)。load-on-startup设置为1,表示Servlet容器启动时立即加载这个Servletservlet-mapping将/dwr/*的请求映射到这个Servlet,处理DWR相关的请求。同时还有一个EfficientShutdownServletContextAttributeListener监听器,用于DWR的高效关闭,释放资源。 最后是<welcome-file-list>,指定默认的欢迎文件为index.jsp,当访问应用根路径时,会默认访问这个文件。 现在需要检查是否有遗漏的部分,比如各个元素的作用是否解释清楚,特别是监听器、过滤器Servlet的配置目的。另外,需要注意一些细节,比如openSessionInViewFilter的作用,Struts2过滤器的职责,XssFilter的用途,DWR的配置参数含义等。确保每个配置项的解释准确,并且符合Web应用开发的常见实践。 </think> 这个`web.xml`是Java Web应用的部署描述符(Servlet 3.0版本),定义了应用的初始化参数、监听器、过滤器Servlet及欢迎文件等配置。以下是各部分的详细解释: ### **1. 根元素与基本信息** ```xml <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> ``` - 声明使用Servlet 3.0规范,`xsi:schemaLocation`指定了XML模式文件的位置,用于验证配置格式。 ### **2. 上下文参数(`<context-param>`)** 上下文参数由Servlet容器(如Tomcat)加载,供全局组件(如监听器、过滤器)使用。 #### (1)`contextConfigLocation` ```xml <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:applicationContext*.xml classpath*:*Context.xml </param-value> </context-param> ``` - **作用**:指定Spring应用上下文(`ApplicationContext`)的配置文件路径。 - **含义**:加载类路径(`classpath`)下所有以`applicationContext`开头或包含`Context`的XML文件(如`applicationContext-datasource.xml`、`springContext.xml`),用于初始化Spring IoC容器。 #### (2)`webAppRootKey` ```xml <context-param> <param-name>webAppRootKey</param-name> <param-value>rms.root</param-value> </context-param> ``` - **作用**:将Web应用的根路径(如`/usr/local/tomcat/webapps/应用名/`)设置为系统属性,供其他组件(如日志框架)引用。 - **示例**:在`log4j.properties`中可通过`${rms.root}`获取应用根路径。 #### (3)`log4jConfigLocation` 与 `log4jRefreshInterval` ```xml <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/classes/log4j.properties</param-value> </context-param> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>60</param-value> </context-param> ``` - **作用**:配置Log4j日志框架的属性文件路径及自动刷新间隔。 - **含义**: - `log4jConfigLocation`:指定Log4j配置文件路径为`/WEB-INF/classes/log4j.properties`(通常存放类路径下的资源)。 - `log4jRefreshInterval`:设置日志配置的自动刷新间隔为60秒,修改`log4j.properties`后无需重启应用即可生效。 ### **3. 监听器(`<listener>`)** 监听器用于监听Servlet容器的生命周期事件(如应用启动/销毁)。 #### (1)`Log4jConfigListener` ```xml <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> ``` - **作用**:初始化Log4j日志框架,读取前面定义的`log4jConfigLocation`和`log4jRefreshInterval`参数,完成日志配置的加载和定时刷新。 #### (2)`ContextLoaderListener` ```xml <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> ``` - **作用**:Spring的核心监听器,负责根据`contextConfigLocation`参数加载Spring应用上下文(`ApplicationContext`),是Spring与Web容器集成的关键。 #### (3)自定义监听器(`UrlAuthListen`、`WebConfigListener`) ```xml <listener> <listener-class>com.hg.filter.UrlAuthListen</listener-class> </listener> <listener> <listener-class>com.hg.filter.WebConfigListener</listener-class> </listener> ``` - **作用**:用户自定义的监听器,可能用于: - `UrlAuthListen`:URL权限校验(如应用启动时加载权限规则)。 - `WebConfigListener`:Web应用初始化配置(如加载全局参数、缓存初始化)。 #### (4)DWR的`EfficientShutdownServletContextAttributeListener` ```xml <listener> <listener-class>org.directwebremoting.servlet.EfficientShutdownServletContextAttributeListener</listener-class> </listener> ``` - **作用**:DWR(Direct Web Remoting)库的监听器,用于在应用销毁时高效释放DWR相关资源(如反向Ajax连接)。 ### **4. 过滤器(`<filter>`与`<filter-mapping>`)** 过滤器用于拦截请求/响应,执行预处理或后处理逻辑。 #### (1)`OpenSessionInViewFilter`(Hibernate会话管理) ```xml <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` - **作用**:解决Hibernate的“延迟加载在视图层失败”问题(`LazyInitializationException`)。 - **原理**:在HTTP请求开始时打开Hibernate `Session`,请求结束时关闭,确保视图渲染(如JSP)时仍可访问延迟加载的关联对象。 - `singleSession=true`:每个请求使用一个共享的`Session`(默认行为)。 #### (2)Struts 2核心过滤器(`StrutsPrepareAndExecuteFilter`) ```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> ``` - **作用**:Struts 2框架的核心过滤器,负责处理所有HTTP请求,完成以下任务: - 解析请求URL,匹配对应的Action。 - 执行拦截器链(如参数绑定、验证)。 - 调用Action的业务逻辑。 - 转发到结果视图(如JSP、Freemarker)。 - `url-pattern=/*`:所有请求(包括静态资源)都由Struts处理(需注意静态资源过滤配置,避免被错误拦截)。 #### (3)自定义XSS过滤器(`XssFilter`) ```xml <filter> <filter-name>XssFilter</filter-name> <filter-class>com.hg.aop.XssFilter</filter-class> </filter> <filter-mapping> <filter-name>XssFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` - **作用**:防御跨站脚本攻击(XSS),对请求参数、请求体中的恶意脚本(如`<script>`标签)进行转义或过滤。 - **实现逻辑**:通常通过重写`HttpServletRequest`的`getParameter()`等方法,对输入内容进行安全处理。 ### **5. DWR Servlet配置** DWR(Direct Web Remoting)是一个允许Java代码在浏览器端通过JavaScript调用的库,用于简化前后端交互。 #### (1)`dwr-invoker` Servlet定义 ```xml <servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>crossDomainSessionSecurity</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>scriptSessionTimeout</param-name> <param-value>1800000</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> ``` - **核心参数解释**: - `debug=true`:启用DWR调试模式(开发阶段使用,生产环境应关闭)。 - `activeReverseAjaxEnabled=true`:启用反向Ajax(服务器主动向客户端推送消息)。 - `crossDomainSessionSecurity=false`:关闭跨域会话安全校验(允许跨域请求)。 - `scriptSessionTimeout=1800000`:设置DWR脚本会话的超时时间为30分钟(单位:毫秒)。 - `load-on-startup=1`:Servlet容器启动时立即加载此Servlet(优先级较高)。 - **映射路径**:所有`/dwr/*`的请求由`DwrServlet`处理(如`/dwr/engine.js`用于加载DWR客户端脚本)。 ### **6. 欢迎文件列表(`<welcome-file-list>`)** ```xml <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> ``` - **作用**:当访问应用根路径(如`http://localhost:8080/应用名/`)时,默认跳转的页面为`index.jsp`。 ### 总结 此`web.xml`整合了Spring、Struts 2、Hibernate、Log4j、DWR等框架,定义了应用的初始化参数、监听器(用于框架启动和资源管理)、过滤器(用于请求处理和安全防护)、Servlet(用于DWR交互)及默认访问页面,是传统Java EE Web应用的典型配置。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值