今天主要介绍Servlet中的过滤器和监听器
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>listenerparam-name>
<param-value>11111111111param-value>
context-param>
HttpSession监听器:HttpSessionListener、HttpSessionAttributeListener、HttpSessionBindingListener、HttpSessionActivationListener。
HttpSessionListener:监听HttpSession对象初始化或者结束时响应的动作事件
HttpServletRequest监听器有2个监听接口:ServletRequestListener和ServletRequestAttributeListener。
监听器没有什么好说的,如果想监听Servlet容器中相关生命周期对象,只需要自定义类实现对应的监听接口并重新相应的方法,web容器会监听这些生命周期对象的一些事件,比如初始化和销毁,此时会自动调用自己实现的监听接口中的方法。
在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;
}
}