Servlet技术-03

博客主要介绍了Servlet中的过滤器和监听器。监听器可监听HttpServletRequest、HttpSession、ServletContext对象的生命周期事件,通过自定义类实现监听接口方法即可。过滤器在Servlet前执行,可拦截、过滤请求和改变响应,在Servlet中实现需实现Filter接口并配置。

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

今天主要介绍Servlet中的过滤器和监听器

1、监听器

web容器提供了很多监听接口,每个监听接口里面规定了一些监听方法,专门用来监听HttpServletRequest、HttpSession、ServletContext对象的生成、运行和销毁的生命周期事件,当某个事件触发时,应用服务器会自动调用对应的监听方法,我们只需要自定义类实现某个监听接口里面的监听方法就行了。
监听接口和监听事件
在这里插入图片描述
与ServletContext事件相关的有2个监听接口:ServletContextListener和ServletContextAttributeListener
ServletContextListener:监听Web程序初始化或者结束时响应的动作事件。

package com.wen.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

/**
 * @author hw
 * @version 1.0
 * @date 2021/1/9 20:16
 */
@WebListener
public class MyServletContextListener implements ServletContextListener{
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        ServletContext servletContext = servletContextEvent.getServletContext();
        String listener = servletContext.getInitParameter("listener");
        System.out.println(listener);
        System.out.println("Tomcat正在启动中。。。");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("Tomcat正在关闭中。。。");
    }
}

若需要初始化参数,则只能在web.xml中配置

<context-param>
    <param-name>listener</param-name>
    <param-value>11111111111</param-value>
  </context-param>

在这里插入图片描述
HttpSession监听器:HttpSessionListener、HttpSessionAttributeListener、HttpSessionBindingListener、HttpSessionActivationListener。
HttpSessionListener:监听HttpSession对象初始化或者结束时响应的动作事件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
HttpServletRequest监听器有2个监听接口:ServletRequestListener和ServletRequestAttributeListener。
在这里插入图片描述
在这里插入图片描述
监听器没有什么好说的,如果想监听Servlet容器中相关生命周期对象,只需要自定义类实现对应的监听接口并重新相应的方法,web容器会监听这些生命周期对象的一些事件,比如初始化和销毁,此时会自动调用自己实现的监听接口中的方法。

2、过滤器

在Web应用程序中,过滤器是在Servlet前面执行,可以拦截、过滤浏览器的请求,也可以改变对浏览器的响应。相当于客户端和服务端的中间者,对二者之间的数据进行过滤。
在这里插入图片描述
在这里插入图片描述
一般在web应用程序中,使用过滤器链实现如下功能:
在这里插入图片描述
在Servlet实现过滤器必须实现Filter接口,并使用注解或者web.xml方法进行配置就行了。
@WebFilter注解的主要属性说明如下
在这里插入图片描述
注意:request.setCharacterEncoding(encoding)只对消息体中的数据有效,也就是对POST起作用,对get请求URI中带参数不起作用,需要自定义请求包装类继承HttpServletRequestWrapper

package com.wen.servlet;

import org.apache.log4j.Logger;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;


@WebFilter(
		asyncSupported = true,
		description = "字符编码过滤器",
		filterName = "encodingFilter", 
		urlPatterns = { "/*" },
		initParams = { 
			@WebInitParam(name = "ENCODING", value = "UTF-8")
		} 
	)
public class EncodingFilter implements Filter{

	private static Logger log = Logger.getLogger("EncodingFilter");
	private String encoding="";
	private String filterName="";
	private String url=null;
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		//通过filterConfig获得初始化中的编码值
		encoding = filterConfig.getInitParameter("ENCODING");
		filterName = filterConfig.getFilterName();
		if(encoding==null||"".equals(encoding)){
			encoding="UTF-8";
		}
		System.out.println("获得编码值");
	}
	
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
						 FilterChain chain) throws IOException, ServletException {
		//分别对请求和响应进行编码设置
		HttpServletRequest req = (HttpServletRequest)request;
		url = req.getRequestURL().toString();
		System.out.println(url+"请求被"+filterName+"过滤");
		if("GET".equals(req.getMethod())){
			req = new RequestEncodingWrapper(req,encoding);
		}else{
			request.setCharacterEncoding(encoding);
		}
		response.setCharacterEncoding(encoding);
		//传输给过滤器链过滤
		chain.doFilter(req, response);
		System.out.println(url+"响应被"+filterName+"过滤");
	}

	@Override
	public void destroy() {
		System.out.println(url+"请求销毁");
	}
}

package com.wen.servlet;

import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class RequestEncodingWrapper extends HttpServletRequestWrapper{

    private String encoding="";
    public RequestEncodingWrapper(HttpServletRequest request) {
        //必须调用父类构造方法
        super(request);
    }
    public RequestEncodingWrapper(HttpServletRequest request,String encoding) {
        //必须调用父类构造方法
        super(request);
        this.encoding = encoding;
    }
    //重新定义getParameter方法
    @Override
    public String getParameter(String name){
        String value = getRequest().getParameter(name);
        try {
            //将参数值进行编码转换
            if(value!=null&&!"".equals(value))
                value = new String(value.trim().getBytes("ISO-8859-1"), encoding);
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return value;
    }
}

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值