过滤器Filter
基本概述
Java中的Filter 并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应。 主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理,是个典型的处理链。
参考文档:http://tomcat.apache.org/tomcat-5.5-doc/servletapi/index.html
参考博客:http://blog.csdn.net/sd0902/article/details/8395641
Fiter的生命周期
过滤器从创建到销毁的过程
服务器启动的时候,服务器就会创建过滤器的对象,每次访问被拦截目标资源,过滤器中的doFilter的方法就会执行当服务器关闭的时候,服务器就会销毁Filter对象
服务器在启动时执行初始化方法, init
访问资源被拦截时执行拦截方法, doFilter 。 放行: chain.doFilter(request, response)
服务器关闭时执行销毁方法, destroy
Fiter的配置细节
url-pattern的路径匹配与Servlet一样的,可以参考Servlet入门
servlet-name的配置
可以通过servlet-name标签拦截一个Servlet的资源
dispatcher的配置
REQUEST :拦截请求,默认值。
FORWARD :拦截转发。
ERROR :拦截跳转到错误页面,全局错误页面。
INCLUDE :拦截在一个页面中包含另一个页面。
开发过滤器的步骤
1、创建
继承HttpServlet 同时实现Filter接口
默认filter不生效,需要配置.
<!-- 配置的一个filter -->
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.pc.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/*</url-pattern> /*表示对该WEB的所有网页都过滤
</filter-mapping>
2、在filter的方法中添加业务逻辑
package com.pc.filter;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.pc.domain.User;
public class MyFilter1 extends HttpServlet implements Filter {
public void doGet(HttpServletRequest request, HttpServletResponse response)hrows ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
System.out.print("myfilter1...");
//获取session
HttpServletRequest httpServletRequest=(HttpServletRequest)request;
//看看请求的资源是什么
String uri=httpServletRequest.getRequestURI();
if(uri.startsWith("/UsersManager3/imgs")||uri.startsWith("/UsersManager3/Login")){
// 该过滤器放行,进入下一个过滤器
chain.doFilter(request, response);
}else{
HttpSession session=httpServletRequest.getSession();
User user=(User) session.getAttribute("loginuser");
if(user!=null){
//该用户合法,放行
chain.doFilter(request, response);
}else{
request.setAttribute("err", "请好好登陆");
httpServletRequest.getRequestDispatcher("/LoginServlet")
.forward(request, response);
}
}
}
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
过滤器链
过滤器链的概念很容易理解,就是在配置过滤器时,多个过滤器加载进内存中时,当使用过滤器之后调用chain.doFilter(request, response);WEB服务器会按与访问地址匹配的配置顺序决定下一个调用的过滤器是什么。这就可以视为过滤器链。
案例:编码过滤器
package com.pc.user.web.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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 编码过滤器
*
* @author Switch
* @data 2016年10月24日
* @version V1.0
*/
public class EncodingFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 设置编码
req.setCharacterEncoding("utf-8");
// 使用装饰者模式,实现GET请求方式的乱码问题
HttpServletRequestEncoding requestEncoding = new HttpServletRequestEncoding(req);
// 使用自定义的Request,放行
chain.doFilter(requestEncoding, res);
}
public void init(FilterConfig fConfig) throws ServletException {
}
public void destroy() {
}
}
HttpServletRequest包装类
package com.pc.user.web.filter;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* HttpServletRequest包装类,用于编码处理
*
* @author Switch
* @data 2016年10月24日
* @version V1.0
*/
public class HttpServletRequestEncoding extends HttpServletRequestWrapper {
public HttpServletRequestEncoding(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String parameter = super.getParameter(name);
try {
if ("GET".equalsIgnoreCase(super.getMethod())) {
parameter = new String(parameter.getBytes("iso8859-1"), "utf-8");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return parameter;
}
@Override
public String[] getParameterValues(String name) {
String[] parameterValues = super.getParameterValues(name);
try {
if ("GET".equalsIgnoreCase(super.getMethod())) {
for (int i = 0; i < parameterValues.length; i++) {
parameterValues[i] = new String(parameterValues[i].getBytes("iso8859-1"), "utf-8");
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return parameterValues;
}
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> parameterMap = super.getParameterMap();
Map<String, String[]> map = new LinkedHashMap<String, String[]>();
if ("GET".equalsIgnoreCase(super.getMethod())) {
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
String parameter = entry.getKey();
String[] parameterValues = entry.getValue();
try {
parameter = new String(parameter.getBytes("iso8859-1"), "utf-8");
for (int i = 0; i < parameterValues.length; i++) {
parameterValues[i] = new String(parameterValues[i].getBytes("iso8859-1"), "utf-8");
}
map.put(parameter, parameterValues);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
return map;
}
}
web.xml配置
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.pc.user.web.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
----------参考《韩顺平.细说Servlet》
----------参考《网易云课堂.Servlet技术》