Filter过滤器介绍&解决get/post乱码过滤器

什么是Filter

  • Filter及其作用介绍
    Filter是sun公司中servlet2.3后增加的一个新功能.
    Servlet规范中三个技术 Servlet Listener Filter
    在javaEE中定义了一个接口 javax.servlet.Filter来描述过滤器
    通过Filter可以拦***问web资源的请求与响应操作(get/post).
    WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
  • Filter API介绍
    Filter是javax.servlet包下的一个接口主要有以下三个方法
    1. void destroy()
    2. void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
    3. void init(FilterConfig filterConfig)

Filter入门

  • 创建步骤介绍
    1. 创建一个类实现javax.servlet.Filter接口
    2. 得写接口方法
    3. 在web.xml文件中配置Filter
  • Filter在web.xml文件中配置的目的:
    1. 配置拦截什么样的资源。
    2. Filter初始化
    <filter>
    	<filter-name>demo1Filter</filter-name>
    	<filter-class>cn.itcast.web.filter.Demo1Filter</filter-class>
    </filter>
    <filter-mapping>
    	<filter-name>demo1Filter</filter-name>
    	<url-pattern>/demo1</url-pattern>
    </filter-mapping>
  • 演示Filter的拦截操作

注意:在Filter的doFilter方法内如果没有执行chain.doFilter(request,response),那么资源是不会被访问到的

  • FilterChain功能介绍
    FilterChain 是 servlet 容器为开发人员提供的对象,它提供了对某一资源的已过滤请求调用链的视图。过滤器使用 FilterChain 调用链中的下一个过滤器,如果调用的过滤器是链中的最后一个过滤器,则调用链末尾的资源。
    void doFilter(ServletRequest request,ServletResponse response,FilterChain chain){
    chain.doFilter(request,response);
    }

三、Filter链与生命周期

  • Filter链介绍
    多个Filter对同一个资源进行了拦截,那么当我们在开始的Filter中执行
    chain.doFilter(request,response)时,是访问下一下Filter,直到最后一个Filter执行
    时,它后面没有了Filter,才会访问web资源。
  • 关于多个FIlter的访问顺序问题
    如果有多个Filter形成了Filter链,那么它们的执行顺序是怎样确定的?
    它们的执行顺序取决于在web.xml文件中配置的先后顺序。
  • Filter生命周期
    当服务器启动,会创建Filter对象,并调用init方法,只调用一次.
    当访问资源时,路径与Filter的拦截路径匹配,会执行Filter中的doFilter方法,
    这个方法是真正拦截操作的方法.
    当服务器关闭时,会调用Filter的destroy方法来进行销毁操作.

四、FilterConfig介绍

  • FilterConfig介绍
  1. FilterConfig功能介绍
    在Filter中的init方法上有一个参数叫FilterConfig
    FilterConfig是Filter的配置对象
    它的作用:
    1.获取Filter的名称
    2.获取初始化参数
    3.获取ServletContext对象
  2. FilterConfig常用API

五、Filter配置详解

  1. Filter基本配置介绍
<filter>
					<filter-name>filter名称</filter-name>
					<filter-class>filter类全名</filter-class>
				</filter>
				<filter-mapping>
					<filter-name>filter名称</filter-name>
					<url-pattern>映射路径</url-pattern>
				</filter-mapping>
  1. 关于url-pattern配置
    1.完全匹配
    要求必须以"/“开始.
    2.目录匹配
    要求必须以”/"开始,以结束.
    3.扩展名匹配
    不能以"/"开始,以
    .xxx结束.
  2. 关于servlet-name配置
    针对于servlet拦截的配置 配置
    在Filter中它的配置项上有一个标签
    它用于设置当前Filter拦截哪一个servlet。
    是通过servlet的name来确定的。
  3. 关于dispatcher配置
    可以取的值有 REQUEST FORWARD ERROR INCLUDE
    它的作用是:当以什么方式去访问web资源时,进行拦截操作.
    1.REQUEST 当是从浏览器直接访问资源,或是重定向到某个资源时进行拦截方式配置的 它也是默认值
    2.FORWARD 它描述的是请求转发的拦截方式配置
    3.ERROR 如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
    4.INCLUDE 如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用

六、解决get/post乱码过滤器

package com.book.web.filter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

@WebFilter(filterName="/EncodingFilter",urlPatterns={"/encodingFilter"})
public class EncodingFilter implements Filter {
	public void destroy() {
	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//处理请求乱码
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		HttpServletRequest myRequest = new MyRequest(httpServletRequest);
		//处理响应代码
		response.setContentType("text/html;charset=utf-8");
		chain.doFilter(request, response);
	}

	public void init(FilterConfig fConfig) throws ServletException {
	}
}
class MyRequest extends HttpServletRequestWrapper{
	//自定义request对象
	private HttpServletRequest request;
	private boolean hasEncode;
	
	public MyRequest(HttpServletRequest request) {
		super(request);
		this.request = request;
	}
	//对所需方法进行增强,进行覆盖
	@Override
	public Map getParameterMap() {
		//获得请求方式get/post
		String method = request.getMethod();
		if(method.equalsIgnoreCase("post")){
			try {
				//处理post乱码
				request.setCharacterEncoding("utf-8");
				return super.getParameterMap();
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}else if(method.equalsIgnoreCase("get")){
			Map<String, String[]> parameterMap = request.getParameterMap();
			if(!hasEncode){//确保get手动编码只进行一次
				for (String parameterName : parameterMap.keySet()){
					String[] values = parameterMap.get(parameterName);
					if(values != null){
						for (int i = 0; i < values.length; i++) {
							try {
								values[i] = 
								new String(values[i].getBytes("IOS-8859-1"),"utf-8");
							} catch (UnsupportedEncodingException e) {
								e.printStackTrace();
							}
						}
					}
				}
				hasEncode = true;
			}
			return parameterMap;
		}
		return super.getParameterMap();
	}
	@Override
	public String getParameter(String name) {
		Map<String, String[]> parameterMap = getParameterMap();
		String[] values = parameterMap.get(name);
		if (values == null) {
			return null;
		}
		return values[0]; // 取回参数的第一个值
	}
@Override
	public String[] getParameterValues(String name) {
		Map<String, String[]> parameterMap = getParameterMap();
		String[] values = parameterMap.get(name);
		return values;
	}
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务