Filter 即为过滤,用于在 Servlet 之外对 Request 或者 Response 进行修改。它主要用于对用户请 求进行预处理,也可以对 HttpServletResponse 进行后处理。使用 Filter 的完整流程:Filter 对用户请 求进行预处理,接着将请求交给 Servlet 进行处理并生成响应,后 Filter 再对服务器响应进行后处 理。在一个 web 应用中,可以开发编写多个 Filter,这些 Filter 组合起来称之为一个 Filter 链。
执行顺序:
单个过滤器:
客户端–服务器–过滤器–service方法–过滤器–客户端
多个过滤器:
[外链图片转存失败(img-jvD6sxl7-1568044981393)(C:\Users\22507\OneDrive\计算机\Java\MdJava笔记\images\filter.png)]
若是一个过滤器链:先配置先执行(请求时的执行顺序);响应时:以相反的顺序执行。
过滤顺序:过1–过2–过3–service方法()–过3–过2–过1
实现filter
我们可以通过实现一个叫做 javax.servlet.Fileter 的接口来实现一个过滤器,其中定义了三个方 法,init(), doFilter(), destroy() 分别在相应的时机执行。后期观察生命周期。
步骤:
- 编写 java 类实现 Filter 接口,并实现其 doFilter 方法。
- 在 web.xml 文件中对编写的 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 {
// TODO Auto-generated method stub
System.out.println("Filter01");
// 请求到达资源之前处理的代码,预处理
chain.doFilter(request, response);
// 放行,使过滤的代码文件得以执行
System.out.println("Filter01");
//响应给客户端前处理的代码,后处理
}
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("销毁");
//执行一次,系统方法,有服务器调用,正常关闭服务器时销毁
}
配置xml
<filter>
<filter-name>fil01</filter-name>
<filter-class>com.mage.filter.Filter01</filter-class>
</filter>
<filter-mapping>
<filter-name>fil01</filter-name>
<url-pattern>/ts01</url-pattern>
</filter-mapping>
tip:
toFilter(): 本质是放行,调用 doFilter 方法后,即请求可以到达资源
url-pattern 的配置:
- 配置具体路径 /index.html /TestServlet.do
- 带有通配符的配置 /* ;*.html; *.jsp
过滤器处理字符乱码
GET:
请求:
Tomcat8及以上,不需要处理
Tomcat7及以下,需要处理乱码
new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");
响应:
response.setContentType("text/html;charset=UTF-8");
POST:
请求:
Tomcat8及以上,需要处理乱码
request.setCharacterEncoding("UTF-8");
Tomcat7及以下,需要处理乱码
request.setCharacterEncoding("UTF-8");
响应:
response.setContentType("text/html;charset=UTF-8");
注意:Tomcat7 及以下的版本:上述解决 GET 乱码的方式不好,不能解决所有的问题,可以借助 HttpServletRequestWrapper 类和过滤器来完成转换乱码的问题:
定义 HttpServletRequestWrapper 的子类,并且重写 getParameter(String name) 方法,在该方法中实现乱码的处理
chain.doFilter(自定义类(HttpServletRequestWrapper 的子类),response
public void init(FilterConfig filterConfig) throws ServletException {
/* 定义内部类MyWrapper继承HttpServletRequestWrapper
* 目的:重写getParameter()
* */
}
class MyWrapper extends HttpServletRequestWrapper {
HttpServletRequest request;
public MyWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}
public String getParameter(String name) {
String value = null;
//非空判断
if(request.getParameter(name)!=null) {
try {
value = new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return value;
}
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
//基于http运行,强转,大转小
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();
System.out.println(serverInfo);
// 截取版本号,截取是左闭右开
String versionNumber = serverInfo.substring(serverInfo.indexOf("/")+1,serverInfo.indexOf("/")+2
);
//判断Tomcat版本是否是7及以下
if(versionNumber != null && Integer.parseInt(versionNumber)<=7) {
//判断请求方式
String method = request.getMethod();
System.out.println(method);
if("get".equalsIgnoreCase(method)) {
/*get请求
*Tomcat7即以下,需要处理乱码
* 常规方法:
* new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");
* 无法正常得到用户的参数,所以需要定义一个内部类MyWrapper,继承HttpServletRequestWrapper,
* 重写getParameter()方法。
* myWrapper其实就是重写了getParameter方法的request对象,而重写后的方法解决了乱码问题,
* 所以用户调用的时候就不会乱码
* */
HttpServletRequest myWrapper = new MyWrapper(request);
chain.doFilter(myWrapper, response);
return;
}
}
chain.doFilter(req, resp);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}