Filter
1、功能
在Servlet 被调用之前,检查Request 对象
»可以对其Request Header 和Request 内容进行审查和修改
在Servlet 调用结束之后,检查Response 对象
»可以对其Response Header 和Response 内容进行审查和修改
2、接口Filter
Filter 的初始化方法
容器创建Filter 之后将调用这个方法
使用这个方法可以读取web.xml 文件中定义的初始化参数
该方法完成实际的过滤操作
当客户请求访问与Filter 相关联的URL 时,将调用该方法
chain 用于访问后续的Filter 或Servlet
容器在销毁Filter 实例前调用该方法
该方法中可以释放该Filter 所占用的资源
Filter的创建和销毁由web服务器控制。
»服务器启动的时候,web服务器创建Filter的实例对象,并调用其init方法,完成对象的初始化功能。filter对象只会创建一次,init方法也只会执行一次。
»拦截到请求时,执行doFilter方法。可以执行多次。
»服务器关闭时,web服务器销毁Filter的实例对象。
3、接口FilterChain
doFilter(ServletRequest req,ServletResponse resp )
»负责把所有的过滤器给串联起来
»使得一个过滤器执行完后,下一个可以继续执行
»被串联的多个过滤器按照配置文件中的映射顺序依次执行
4、创建Filter
package ecut.filter.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 HelloFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
// place your code here
System.out.println( "hello" );
// pass the request along the filter chain
chain.doFilter( req, resp );
System.out.println( "world" );
}
public void destroy() {
}
}
HelloFilter
ecut.filter.filter.HelloFilter
同Servlet 一样,url-pattern 可以写多个
url-mapping匹配规则有三种:
»精确匹配 —— 如/index.html,只会匹配index.html这个URL
»路径匹配 —— 如/*,会匹配所有的URL
»后缀匹配 —— 如*.html,会匹配所有以.html为后缀的URL
HelloFilter
/*
package ecut.filter.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = -8731391727918781480L;
@Override
protected void service( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException {
System.out.println( "service" );
response.setContentType( "text/html" );
PrintWriter w = response.getWriter();
w.println( "你好 , Servlet .
" );
}
}
HelloServlet
ecut.filter.servlet.HelloServlet
HelloServlet
/filter/hello
在浏览器中访问HelloServle
运行结果如下:
hello
service
world
5、在config中指定初始化参数
CharacterEncodingFilter
ecut.filter.filter.CharacterEncodingFilter
encoding
UTF-8
在init 方法中通过FilterConfig 对象访问
字符集过滤器测试案例:
package ecut.filter.filter;
import java.io.IOException;
import java.nio.charset.Charset;
import javax.servlet.DispatcherType;
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;
public class CharacterEncodingFilter implements Filter{
private static final String ENCODING_PARAM = "encoding" ;
private static final String DEFAULT_ENCODING = "UTF-8" ;
private String encoding ;
@Override
public void init( FilterConfig filterConfig ) throws ServletException {
System.out.println( "CharacterEncodingFilter 初始化" );
// 获取 Filter 的初始化参数
encoding = filterConfig.getInitParameter( ENCODING_PARAM );
// 如果 未指定初始化参数 或 初始化参数值是 空串 则采用默认编码
encoding = ( encoding == null || encoding.trim().isEmpty() ) ? DEFAULT_ENCODING : encoding ;
// 如果指定的编码名称不被JVM所支持,则采用默认编码
// encoding = Charset.isSupported( encoding ) ? encoding : DEFAULT_ENCODING ;
/*
if( ! Charset.isSupported( encoding ) ) { // 如果指定的字符集名称是不支持的
encoding = DEFAULT_ENCODING ;
}
*/
}
@Override
public void doFilter( ServletRequest req , ServletResponse resp , FilterChain chain )
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req ;
String uri = request.getRequestURI();
DispatcherType type = request.getDispatcherType();
System.out.println( "CharacterEncodingFilter ::: DispatcherType : " + type + " , URI : " + uri );
// place your code here
req.setCharacterEncoding( encoding );
resp.setCharacterEncoding( encoding );
// pass the request along the filter chain
chain.doFilter( req , resp );
}
@Override
public void destroy() {
System.out.println( "CharacterEncodingFilter 销毁" );
}
}
运行结果:
解决中文乱码问题,使用过滤器后还需要 response.setContentType( "text/html" );否则仍然会乱码, 或者在响应中文中直接指定字符集response.setContentType( "text/html;charset=UTF-8" );
6、实现对指定的调度进行过滤
CharacterEncodingFilter
/*
REQUEST
FORWARD
INCLUDE
测试案例:
package ecut.filter.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet( "/filter/action/login" )
public class LoginActionServlet extends HttpServlet {
private static final long serialVersionUID = -7857947923197325636L;
@Override
protected void service( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException {
String username = request.getParameter( "username" );
String password = request.getParameter( "password" );
System.out.println( "username : " + username + " , password : " + password );
request.setAttribute( "username" , username );
RequestDispatcher dispatcher = request.getRequestDispatcher( "/filter/success/login" );
dispatcher.forward( request, response );
}
}
package ecut.filter.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet( "/filter/success/login" )
public class LoginSuccessServlet extends HttpServlet {
private static final long serialVersionUID = 2707448998600792264L;
@Override
protected void service( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException {
//String username = (String)request.getAttribute( "username" );
String username = request.getParameter( "username" );
System.out.println( "success : " + username );
response.setContentType( "text/html" );
response.getWriter().println( "" + username + "
" );
}
}
Filter
登录
运行结果:
hello
CharacterEncodingFilter ::: DispatcherType : REQUEST , URI : /s/filter/action/login
IdentifyBrowserFilter ::: User Agent : mozilla/5.0 (windows nt 6.1; win64; x64; rv:59.0) gecko/20100101 firefox/59.0
username : 郑 , password : 123
CharacterEncodingFilter ::: DispatcherType : FORWARD , URI : /s/filter/success/login
success : 郑
world
8、使用注解
String filterName 指定当前Filter 的名称,相当于xml 中的filter-name
String[] value 指定当前Filter 对应的url (与url-pattern 对应)
String[] urlPatterns 与value 作用相同
DispatcherType[] dispatcherTypes 指定当前Filter 关联的dispatcher 类型
»默认值是DispatcherType.REQUEST
»javax.servlet.DispatcherType 是Servlet 3.0 新定义的枚举
boolean asyncSupported 指定是否支持异步操作
WebInitParam[] initParams 用于设置Filter 初始化参数
9、使用过滤器过滤浏览器
测试案例:
package ecut.filter.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;
public class IdentifyBrowserFilter implements Filter {
@Override
public void init( FilterConfig config ) throws ServletException {
}
@Override
public void doFilter( ServletRequest req , ServletResponse resp , FilterChain chain )
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req ;
HttpServletResponse response = (HttpServletResponse) resp ;
String userAgent = request.getHeader( "user-agent" );
userAgent = userAgent.toLowerCase();
System.out.println( "IdentifyBrowserFilter ::: User Agent : " + userAgent );
// 如果在 userAgent 中找到了 trident 则说明目前正在使用 IE 访问
if( userAgent.indexOf( "trident" ) != - 1 ) {
String uri = request.getRequestURI();
System.out.println( "uri : " + uri );
int index = uri.lastIndexOf( "/" );
uri = uri.substring( 0 , index ) ;
System.out.println( "uri : " + uri );
index = uri.lastIndexOf( "/" );
uri = uri.substring( index ) ;
System.out.println( "uri : " + uri );
//解析字符串,如果访问的是IE目录下的就继续
if( "/ie".equals( uri ) ) {
chain.doFilter( req , resp );
} else {//如果访问的不是IE目录下的就重定向到ie.html
response.sendRedirect( request.getContextPath() + "/pages/filter/ie/ie.html" );
}
} else {
// 如果是 非 IE 浏览器,则可以通过 FilterChain 向后传递 请求 和 响应
chain.doFilter( req , resp );
}
}
@Override
public void destroy() {
}
}
珍爱生命,远离IE
珍爱生命,远离IE
请使用现代浏览器: Chrome 、FireFox
@CHARSET "UTF-8";
h2 {
text-align: center;
}
h2:first-child {
color: red ;
font-weight: bold ;
}
h2:last-child {
color: blue ;
}
运行结果:
转载请于明显处标明出处
http://www.cnblogs.com/AmyZheng/p/9024091.html