Filter(过滤器)之字符替换和编码设置

16 篇文章 0 订阅
顾名思义,Filer的作用就是过滤,主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链.适用Filter完整的流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并响应,最后Filter再对服务器响应进行处理.
filter有以下几个种类:
1.用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求.
2.在HttpServletRequest到达Servlet之前,拦截客户的HtttpServletRequest
3.根据需要检查HtttpServletRequest,也可以修改HtttpServletRequest头和数据
4.在HtttpServletResponse到达客户端前,拦截HtttpServletResponse
5.负责解码的filter:包括对非标准编码的请求解码
6.根据需要检查HtttpServletResponse,也可以修改HtttpServletResponse头和数据
7.filter可负责拦截多个请求或响应,一个请求或响应也可被多个Filter拦截.
创建一个Filter需要两个步骤:
1.创建Filter处理类
2.web.xml文件中配置Filter

创建Filter类
创建Filter必须实现javax.servlet.Filter的初始化
void init(filterConfig config):用于完成Filter的初始化
void destroy():用于Filter销毁前,完成资源回收
void Filter(ServletRequest request,ServletResponse response,FilterChain chain);
实现过滤功能,该 方法就是对每个请求及响应增加的额外处理

案例一:实现字符替换过滤器
对于容器产生的HttpServletRequest对象,无法直接修改某些信息,如请求参数值.就需要自己写方法来实现
但是httpServletWrapper实现了HttpServlet几口,只要继承httpServletWrapper类,并编写重新定义的方法即可

如下图:

输入:
<a href="http://www.w3school.com.cn/">www.w3school.com.cn</a>
提交后:

发现文本内容变成了超链接,原本文本域输出的效果应该是:

因此这里就需要将一些html过滤掉,如将<,>角括号换为HTML实体字符&lt;与&gt,如果不想改程序,就可以直接用过滤器的方式,将用户请求参数中的角括号字符进行替换掉.

过滤替换并不需要我们来实现,可以直接适用APache Commons Lang程序库中,StringEscapeUtils.escapeHtml(String value)方法进行替换,可以从网盘下载解压放到lib文件夹中即可.

链接:https://pan.baidu.com/s/1m_Nt4LLkORpubfPGMb_Qgw 密码:4zo9
或者可以从官网下载:
在容器调用Servlet的service方法之前,Servlet并不知道有请求的到来,而在Servlet的service()方法运行后,容器真正对浏览器进行HTTP响应之前,浏览器也不会知道Servlet真正的响应是什么.Filter可拦截过滤浏览器对Servlet的请求,也可以改变Servlet对浏览器的响应.
换句话说,我们提交请求参数后,需要要让getParameter()返回过滤后的请求参数值,我们可以重写这个方法来实现.
EscapeWrapper.java(字符替换,重写getParameter()方法)
package Servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang3.StringEscapeUtils;

/**
 * Servlet implementation class EscapeWrapper
 */
@WebServlet("/EscapeWrapper")
public class EscapeWrapper extends HttpServletRequestWrapper {
    @Override
	public String getParameter(String name) {
	       String value = getRequest().getParameter(name);
	       return StringEscapeUtils.escapeHtml4(value);
	}

	/**
     * @see HttpServletRequestWrapper#HttpServletRequestWrapper(HttpServletRequest)
     */
    public EscapeWrapper(HttpServletRequest request) {
        super(request);
        // TODO Auto-generated constructor stub
    }

}

EscapeFilter.java(进行拦截,调用请求封装器进行过滤)
原理:filter接口的doFilter方法类似于Servlet接口的service()方法.当请求来到容器,而容器发现调用Servlet的service()方法前,可以应用某过滤器时,就会先调用改过滤器的doFilter()方法.filterChain运行后会以堆栈顺序返回
package javax.servlet;
import java.io.IOException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

import Servlet.EscapeWrapper;
@WebFilter("/*")
public class EscapeFilter implements Filter{

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		Filter.super.destroy();
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		Filter.super.init(filterConfig);
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		HttpServletRequest  requestWrapper = new EscapeWrapper((HttpServletRequest)request);
                 /*如果调用了FilterChain的doFilter()方法,就会运行下一个过滤器,如果没有下一个,就调用请求目标Sevlet的service()方法*/
		chain.doFilter(requestWrapper, response);
	}

}

testFilter.jsp(提交文本域)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="TestFilter" method="post">
<input type="text" name="text">
<input type="submit" value="提交">

</form>
</body>
</html>

showText.jsp(显示文本域信息)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%=request.getAttribute("name") %>
</body>
</html>
TestFilter.java(控制器)
package 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;

/**
 * Servlet implementation class TestFilter
 */
@WebServlet("/TestFilter")
public class TestFilter extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public TestFilter() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String name = request.getParameter("text");
		request.setAttribute("name", name);
        request.getRequestDispatcher("showText.jsp").forward(request, response);
	}

}

运行后如下图:


点击提交:
可以看到过滤器已经实现了字符替换,这个应用可以载入留言功能时,防止用户借助留言板广告.
根据上述代码的实现,便能了解过滤器用在字符替换上的作用了.

案例二:实现编码设置过滤器
前面为了防止中文乱码,也废了不少劲去设置编码问题,虽然解决了,但是存在缺陷:每一次页面的编写,遇到编码问题,都要依次进行设置,当工程量大的时候,这些重复的代码设置就是冗余的.所以可以通过过滤器实现一次性过滤,这样更加方便.
同样,我们也需要提前拦截请求参数进行封装处理.


testEncodingFilter.jsp(提交请求)
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="TestEncodingServlet" method="post">

		<input type="text" name="name"> <input type="submit" value="提交">

	</form>
</body>
</html>
showEncoding.jsp(显示)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%=request.getAttribute("name") %>
</body>
</html>

TestEncodingServlet.java(控制器)
package 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;

/**
 * Servlet implementation class TestEncodingFilter
 */
@WebServlet("/TestEncodingServlet")
public class TestEncodingServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public TestEncodingServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		String name = request.getParameter("name");
		request.setAttribute("name", name);
		request.getRequestDispatcher("showEncoding.jsp").forward(request, response);
	}

}

EncodingWrapper.java(包装)

package Servlet;

import java.io.UnsupportedEncodingException;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.sound.sampled.AudioFormat.Encoding;

import org.apache.commons.lang3.StringEscapeUtils;

/**
 * Servlet implementation class EscapeWrapper
 */
@WebServlet("/EscapeWrapper")
public class EncodingWrapper extends HttpServletRequestWrapper {

	private String EnCODING;

	@Override
	public String getParameter(String name) {
		String value = getRequest().getParameter(name);
		value = StringEscapeUtils.escapeHtml4(value);
		if (value != null) {

			try {
				byte[] b = value.getBytes("ISO-8859-1");
				value = new String(b, EnCODING);

			} catch (UnsupportedEncodingException e) {
				// TODO: handle exception
				throw new RuntimeException(e);
			}

		}
		return value;
	}

	/**
	 * @see HttpServletRequestWrapper#HttpServletRequestWrapper(HttpServletRequest)
	 */
	public EncodingWrapper(HttpServletRequest request, String ENCODING) {
		super(request);
		// TODO Auto-generated constructor stub]
		this.EnCODING = ENCODING;
	}

}

EncodingFilter.java()
package javax.servlet;

import java.io.IOException;

import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;

import Servlet.EncodingWrapper;

@WebFilter(
		urlPatterns={"/*"},
		initParams={
				@WebInitParam(name="ENCODING",value="UTF-8")
				
		}
		
		)
public class EncodingFilter implements Filter{
  private String ENCODING;
	@Override
	public void destroy() {
	
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		ENCODING = filterConfig.getInitParameter("ENCODING");//读取初始化参数
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		HttpServletRequest  requestWrapper =(HttpServletRequest)request;
		if ("GET".equals(requestWrapper.getMethod())) {
			requestWrapper =new EncodingWrapper(requestWrapper,ENCODING);
			
		} else {

			requestWrapper.setCharacterEncoding(ENCODING);
		}
		chain.doFilter(requestWrapper, response);
	}

}

若是不添加编码过滤器,程序中也没有处理,运行后如下图:

点击提交(就会有乱码):



添加过滤器后:

提交(因为有过滤器的存在,所以不会有乱码):

不过,到最后想把编码过滤器和字符替换一起放在项目中,就会出现问题,tomcat会报错,无法正常启动.目前没找出原因.
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值