过滤器Filter
过滤器Filter是Servlet技术中最实用的技术之一
对客户端访问资源的过滤,符合条件放行,不符合条件不放行,
并且可以对目标资源访问前后进行逻辑处理
一个自定义的简单Filter
1)自定义的简单MyFilter类实现Filter接口
2)实现接口中尚未实现的方法(着重实现doFilter方法)
初始化init方法/销毁destroy方法/doFilter方法
3)在web.xml中进行配置(主要是配置要对哪些资源进行过滤)
<filter>
<filter-name>filter</filter-name>
<filter-class>com.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
public class MyFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("MyFilter running....");
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
当请求到达服务器会被过滤器拦截,经过过滤器的doFilter方法进行
业务处理后将这个请求放行后后续的处理这个请求的servlet中
过滤器的doFilter方法拦截后必须放行请求,不然后续servlet无法接受到这个请求
servlet3.0后的Filter
servlet3.0以后只需要在过滤器类上方加上注解@WebFilter(" 请求路径 ")就表示这个类是过滤器
@WebFilter注解的属性
属性value:指定资源请求地址,例如@WebFilter(value="/some")
只有一个value属性时,value可以省略不谢,只写资源地址即可
属性urlPatterns:设置url-pattern值,@WebServlet(urlPatterns ={ "/some",“/other”,"/xxx"});
urlPatterns可以与value互换,功能相同,两者只能使用一个
属性name:<Filter-name>标签的值
@WebServlet(value ={ "/some",“/other”,"/xxx"} , name = "some-Filter")
属性initParams:指定初始化参数.是WebInitParam数组类型,WebInitParam是一个注解,它有name和value属性
@WebFilter(value ={ "/some",“/other”,"/xxx"} ,name = "some-Filter" , initParams={@WebInitParam(name="company",value="bjpowermode")
属性dispatcherTypes:设置对什么类型的请求过滤
@WebFilter(value=" /* ",dispatcherTypes=DispatcherType.FORWARD);
DispatcherType是一个枚举类,有5个常量
FORWARD, 拦截请求转发的请求
INCLUDE, 拦截包含访问的资源
REQUEST, 拦截浏览器发送的请求 (默认),重定向时会执行2次
ASYNC, 拦截异步访问的请求
ERROR 拦截错误跳转的请求
dispatcher属性可以出现多次
@WebFilter(value = "url" ,dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.FORWARD})
@WebFilter("/some")
public class MyFilter implements Filter {
public MyFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
请求达到真正资源地址前可能经过多个Filter(过滤器链)
过滤器链中只有有一个没有放行,请求就无法达到最终的资源请求地址
Filter中的方法
Filter接口有三个方法,并且这个三个都是与Filter的生命相关的方法
init(FilterConfig fConfig):代表filter对象初始化方法 filter对象创建时执行
doFilter(ServletRequest,ServletResponse,FilterCha):代表filter执行过滤的核心方法,如果某资源在已经被配置到这个filter进行过滤的话,
那么每次访问这个资源都会执行doFilter方法
destory():代表是filter销毁方法 当filter对象销毁时执行该方法
初始化方法init(FilterConfig fConfig)的参数FilterConfig包含了过滤器的配置信息
fConfig.getFilterName()获取web.xml中配置的filter-name标签的值,servlet3.0中默认是 filter.当前过滤器类名
fConfig.getInitParameter("name")获取web.xml中配置的Init-param标签的子标签param-value的值
Filter的创建与销毁
Filter何时创建:服务器启动时就创建filter对象(监听器优于过滤器运行)
Filter何时销毁:服务器关闭时filter销毁
利用Filter增强getParameter方法
servlet的doGet方法中可以使用request的getParameter
来获取前端传递的数据
这些数据有时会出现乱码
对于post形式的乱码直接在filter中设置即可
@WebFilter("/* ")
public class MyFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
}
对于get形式的乱码,需要获取参数后再次解码与编码
这时可以使用装饰者模式对参数ServletRequest request的getParameter方法进行增强
使用装饰者模式的前提
1、增强类与被增强的类要实现统一接口
2、在增强类中传入被增强的类
3、需要增强的方法重写
HttpServletRequestWrapper是HttpServletRequest的一个实现类
装饰类
class MyRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public MyRequest (HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String parameter = request.getParameter(name);
try {
parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return parameter;
}
}
在filter中调用
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
MyRequest request = new MyRequest (req);
chain.doFilter(request, response);
}