浅谈过滤器与监听器
1.过滤器:
1)概念:
过滤器:Filter;
*Filter不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应。 主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理,是个典型的处理链。
2)单过滤器执行流程:
客户端→服务器→过滤器chain.doFilter(request, response)请求到达资源之前的代码
→要访问的资源→过滤器chain.doFilter(request, response)响应到达客户端之后的代码→客户端
图示:
(1)实现基本步骤:
1、新建普通java类
2、实现 Filter接口
3、重写方法
4、配置web.xml(如果使用Servlet3.0以后就不用配置.xml可直接的使用注解)
(2)实现代码:
package com.mage.filter;
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;
public class FilterTest implements Filter {
//初始化
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化了。。。");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("请求到达资源前执行的code");
chain.doFilter(request, response);//放行
System.out.println("响应到达客户端前执行的code");
}
//销毁
@Override
public void destroy() {
System.out.println("销毁了。。。");
}
}
3)过滤器链:
1.如果有多个过滤器,会形成一个过滤器链,过滤器在链中的顺序与它在web.xml中配置的顺序有关;因此若是一个过滤器链:先配置先执行(请求时的执行顺序);响应时:以相反的顺序执行。
2.过滤器链的实现和单个过滤器实现代码一致,在配置web.xml文件时将filter所拦截的请求路径设置指向一个Srevlet
(1)过滤器链执行流程图示:
4)乱码解决:
1.GET:
(1)请求:
Tomcat8及以上,不需要处理
Tomcat7及以下,需要处理乱码
new String(request.getParameter(name).getBytes(“ISO-8859-1”),“UTF-8”);(2)响应:
response.setContentType(“text/html;charset=UTF-8”)2.POST:
(1)请求:
Tomcat8及以上,需要处理乱码,request.setCharacterEncoding(“UTF-8”);
Tomcat7及以下,需要处理乱码,request.setCharacterEncoding(“UTF-8”);
(2)响应:
response.setContentType(“text/html;charset=UTF-8”);(8)
(1)实现代码:
package com.mage.filter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
public class EncodeFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
// 设置POST请求编码以及响应编码
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
// 获取服务器版本
String serverInfo = request.getServletContext().getServerInfo();
// 得到版本号
String info = serverInfo.substring(serverInfo.indexOf("/")+1,serverInfo.indexOf("/")+2);
if(info != null && Integer.parseInt(info) <= 7){
// 获取请求方式
String method = request.getMethod();
System.out.println(method);
if("get".equalsIgnoreCase(method)){
HttpServletRequest myWrapper = new MyWrapper(request);
// 放行
chain.doFilter(myWrapper, response);
return;
}
}
chain.doFilter(request, response);
public void init(FilterConfig fConfig) throws ServletException {
}
//内部类MyWrapper,继承HttpServletRequestWrapper,重写getParameter方法,用于获取用户的参数
class MyWrapper extends HttpServletRequestWrapper{
HttpServletRequest request;
public MyWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String value = null;
try {
value = new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return value;
}
}
}
2.监听器:
1)概念:
Web监听器是由servlet规范提供的,他可以监听客户端的请求,服务端的操作,由服务器管理。
2)监听器的种类:
监听器共有三类八种
1:监听生命周期(三个域对象的创建和销毁):
实现接口 ServletRequestListener、HttpSessionListener 、ServletContextListener
2:监听值的变化(属性添加,移除,替换):实现接口 ServletRequestAttributeListener、HttpSessionAttributeListener、ServletContextAttributeListener
3:针对 session 中的对象:监听 session 中的 java 对象(javaBean),javaBean实现接口 HttpSessionBindingListener、HttpSessionActivationListener
3)实现基本步骤:
1、新建普通java类
2、实现相应的接口
3、重写接口
4、配置web.xml
4)使用监听器实现在线人数:
(5)实现代码:
//监听类:
package com.mage.listener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class Listener01 implements HttpSessionListener
int onlinePeople =0 ;
//每当有一个session创建时,在线人数需要加一
@Override
public void sessionCreated(HttpSessionEvent se) {
onlinePeople ++; se.getSession().getServletContext().setAttribute("onlinePeople", onlinePeople);
}
//每当有一个session销毁时,在线人数需要减一
@Override
public void sessionDestroyed(HttpSessionEvent se) {
onlinePeople --;
se.getSession().getServletContext().setAttribute("onlinePeople", onlinePeople);
}
}
//Servlet01类
package com.mage.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Servlet01 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 即是获取在线人数也是创建
int onlinePeople = (int) request.getSession().getServletContext().getAttribute("onlinePeople");
response.getOutputStream().write(("<h1>在线人数</h1>" + onlinePeople).getBytes("GBK"));
}
}
<!--配置.xml -->
<listener>
<listener-class>com.mage.listener.Listener01</listener-class>
</listener>
<servlet>
<description></description>
<display-name>Servlet01</display-name>
<servlet-name>Servlet01</servlet-name>
<servlet-class>com.mage.servlet.Servlet01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet01</servlet-name>
<url-pattern>/s01</url-pattern>
</servlet-mapping>