过滤器Filter

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() 分别在相应的时机执行。后期观察生命周期。

步骤:

  1. 编写 java 类实现 Filter 接口,并实现其 doFilter 方法。
  2. 在 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 的配置:

  1. 配置具体路径 /index.html /TestServlet.do
  2. 带有通配符的配置 /* ;*.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
		
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值