过滤器
过滤器是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件以前,经过一系列的过滤器对请求进行修改、判断等,把不符合规则的请求在中途拦截或修改。也能够对响应进行过滤,拦截或修改响应。
以下图,浏览器发出的请求先递交给第一个filter进行过滤,符合规则则放行,递交给filter链中的下一个过滤器进行过滤。过滤器在链中的顺序与它在web.xml中配置的顺序有关,配置在前的则位于链的前端。当请求经过了链中全部过滤器后就能够访问资源文件了,若是不能经过,则可能在中间某个过滤器中被处理掉。
过滤器通常用于登陆权限验证、资源访问权限控制、敏感词汇过滤、字符编码转换等等操做,便于代码的重用,没必要每一个servlet中还要进行相应的操做。
过滤器的简单应用:
一、新建一个class,实现接口Filter(注意:是javax.servlet中的Filter)。
二、重写过滤器的doFilter(request,response,chain)方法。另外两个init()、destroy()方法通常不须要重写。在doFilter方法中进行过滤操做。
三、在web.xml中配置过滤器。这里要谨记一条原则:在web.xml中,监听器>过滤器>servlet。也就是说web.xml中监听器配置在过滤器以前,过滤器配置在servlet以前,不然会出错。
<filter>
<filter-name>loginFilter</filter-name>//过滤器名称
<filter-class>com.nnngu.filter.loginFilter</filter-class>//过滤器类的包路径
<init—param> //可选
<param—name>参数名</param-name>//过滤器初始化参数
<param-value>参数值</param-value>
</init—pamm>
</filter>
<filter-mapping>//过滤器映射
<filter-name>loginFilter</filter-name>
<url—pattern>指定过滤器做用的范围</url-pattern>
</filter-mapping>
<url-pattren>处定义过滤器做用的范围。通常有如下规则:
一、做用与全部web资源:<url—pattern>/</url-pattern>。则客户端请求访问任意资源文件时都要通过过滤器的过滤,经过则能够访问,不然不能访问。
二、做用于某一文件夹下全部文件:<url—pattern>/dir/</url-pattern>
三、做用于某一种类型的文件:<url—pattern>.扩展名</url-pattern>。好比<url—pattern>.jsp</url-pattern>过滤全部对jsp文件的访问请求。
四、做用于AxiTrader返佣www.fx61.com/brokerlist/axitrader.html某一文件夹下某一类型文件:<url—pattern>/dir/.扩展名</url-pattern>
若是一个过滤器须要过滤多种文件,则能够配置多个<filter-mapping>,一个mapping定义一个url-pattern来定义过滤规则。以下:
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.nnngu.filter.loginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
例1:用过滤器实现登陆验证,没登陆则驳回访问请求并重定向到登陆页面。
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest) arg0;
HttpServletResponse response=(HttpServletResponse) arg1;
HttpSession session=request.getSession();
String path=request.getRequestURI();
Integer uid=(Integer)session.getAttribute("userid");
if(path.indexOf("/login.jsp")>-1){//登陆页面不过滤
arg2.doFilter(arg0, arg1);//递交给下一个过滤器
return;
}
if(path.indexOf("/register.jsp")>-1){//注册页面不过滤
arg2.doFilter(request, response);
return;
}
if(uid!=null){//已经登陆
arg2.doFilter(request, response);//放行,递交给下一个过滤器
}else{
response.sendRedirect("login.jsp");
}
}
例2:设置字符编码
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request2=(HttpServletRequest) request;
HttpServletResponse response2=(HttpServletResponse) response;
request2.setCharacterEncoding("UTF-8");
response2.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
建立Filter
建立一个类而后实现Filter
注意:
导入的包是javax.servlet.Filter下的包
初始化init是再启动tomcat的时候进行初始化的
doFilter中的chain.doFilter是放行的方法
建议把doFilter中的request和response转换为带协议的HttpServletRequset和HttpServletResponse
由于带协议的Http是不带协议的子类,里面的方法比父类更丰富,方便后面调用方法
下面是建立Filter的实例代码
package cn._02FilterChain;
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;br/>@WebFilter("/chain")
public class AFilter implements Filter{br/>@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stubbr/>}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest) request;
HttpServletResponse resp=(HttpServletResponse) response;
System.out.println("A放行以前+++");
chain.doFilter(req, resp);}
@Override
br/>System.out.println("A放行以后---");
}
@Override
public void destroy() {
// TODO Auto-generated method stubbr/>}
}
Filter再web.xml中的配置
配置方式有
1.再web.xml中进行配置
2.再类中加上@WebFilter("拦截路径");
filter链式的执行方式
调用方式是按照配置的<filter-mapping>来调用的
下面是web.xml的实例代码
<filter>
<filter-name>chainA</filter-name>
<filter-class>cn._02FilterChain.AFilter</filter-class>
</filter>
<filter>
<filter-name>chainB</filter-name>
<filter-class>cn._02FilterChain.BFilter</filter-class>
</filter>
<filter>
<filter-name>chainC</filter-name>
<filter-class>cn._02FilterChain.CFilter</filter-class>
</filter>
<!-- 执行顺序按照filter-mapping执行 -->
<filter-mapping>
<filter-name>chainB</filter-name>
<url-pattern>/chain</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>chainA</filter-name>
<url-pattern>/chain</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>chainC</filter-name>
<url-pattern>/chain</url-pattern>
</filter-mapping>
package com.zzxtit.common.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 CharacterEncodingFilter implements Filter{
private static String encoding = "UTF-8";
public void init(FilterConfig filterConfig) throws ServletException {
encoding = filterConfig.getInitParameter("encoding") == null ? "UTF-8" : filterConfig.getInitParameter("encoding");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding(encoding);
}
}
注 :
(1)使用getInitPamater是从web.xml里获取变量enciding的默认值
(2)chain的做用 :通常filter都是一个链,web.xml里配置了几个就有几个。一个一个连在一块儿,chain.doFilter()将请求转发给过滤器链下一个filter
代码实现
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.zzxtit.common.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>html