前言
在上篇博文中,我们已经讲解了过滤器的基本概念,使用以及简单的Servlet应用了。这篇博文主要讲解过滤器的高级应用。。
编码过滤器
目的:解决全站的乱码问题
开发过滤器
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //将request和response强转成http协议的 HttpServletRequest httpServletRequest = (HttpServletRequest) req; HttpServletResponse httpServletResponse = (HttpServletResponse) resp; httpServletRequest.setCharacterEncoding("UTF-8"); httpServletResponse.setCharacterEncoding("UTF-8"); httpServletResponse.setContentType("text/html;charset=UTF-8"); chain.doFilter(httpServletRequest, httpServletResponse); }
第一次测试
Servlet1中向浏览器回应中文数据,没有出现乱码。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().write("看完博客点赞!"); }
分析
上面的过滤器是不完善的,因为浏览器用get方式提交给服务器的中文数据,单单靠上面的过滤器是无法完成的!
那么我们需要怎么做呢??我们之前解决get方式的乱码问题是这样的:使用request获取传递过来的数据,经过ISO 8859-1反编码获取得到不是乱码的数据(传到Servlet上的数据已经被ISO 8859-1编码过了,反编码就可以获取原来的数据),再用UTF-8编码,得到中文数据!
参考我之前的博文:Servlet第四篇【request对象常用方法、应用】
在Servlet获取浏览器以GET方式提交过来的中文是乱码的根本原因是:getParameter()方法是以ISO 8859-1的编码来获取浏览器传递过来的数据的,得到的是乱码
既然知道了根本原因,那也好办了:过滤器传递的request对象,使用getParameter()方法的时候,获取得到的是正常的中文数据
也就是说,sun公司为我们提供的request对象是不够用的,因为sun公司提供的request对象使用getParameter()获取get方式提交过来的数据是乱码,于是我们要增强request对象(使得getParameter()获取得到的是中文)!
增强request对象
增强request对象,我们要使用包装设计模式!
包装设计模式的五个步骤:
- 1、实现与被增强对象相同的接口
- 2、定义一个变量记住被增强对象
- 3、定义一个构造器,接收被增强对象
- 4、覆盖需要增强的方法
- 5、对于不想增强的方法,直接调用被增强对象(目标对象)的方法
sun公司也知道我们可能对request对象的方法不满意,于是提供了HttpServletRequestWrapper类给我们实现(如果实现HttpServletRequest接口的话,要实现太多的方法了!)
class MyRequest extends HttpServletRequestWrapper { private HttpServletRequest request; public MyRequest(HttpServletRequest request) { super(request); this.request = request; } @Override public String getParameter(String name) { String value = this.request.getParameter(name); if (value == null) { return null; } //如果不是get方法的,直接返回就行了 if (!this.request.getMethod().equalsIgnoreCase("get")) { return null; } try { //进来了就说明是get方法,把乱码的数据 value = new String(value.getBytes("ISO8859-1"), this.request.getCharacterEncoding()); return value ; } catch (UnsupportedEncodingException e) { e.printStackTrace(); throw new RuntimeException("不支持该编码"); } } }
将被增强的request对象传递给目标资源,那么目标资源使用request调用getParameter()方法的时候,获取得到的就是中文数据,而不是乱码了!
//将request和response强转成http协议的 HttpServletRequest httpServletRequest = (HttpServletRequest) req; HttpServletResponse httpServletResponse = (HttpServletResponse) resp; httpServletRequest.setCharacterEncoding("UTF-8"); httpServletResponse.setCharacterEncoding("UTF-8"); httpServletResponse.setContentType("text/html;charset=UTF-8"); MyRequest myRequest = new MyRequest(httpServletRequest); //传递给目标资源的request是被增强后的。 chain.doFilter(myRequest, httpServletResponse);
第二次测试
- 使用get方式传递中文数据给服务器
<form action="${pageContext.request.contextPath}/Servlet1" method="get"> <input type="hidden" name="username" value="中国"> <input type="submit" value="提交"> </form>
敏感词的过滤器
如果用户输入了敏感词(傻b、尼玛、操蛋等等不文明语言时),我们要将这些不文明用于屏蔽掉,替换成符号!
要实现这样的功能也很简单,用户输入的敏感词肯定是在getParameter()获取的,我们在getParameter()得到这些数据的时候,判断有没有敏感词汇,如果有就替换掉就好了!简单来说:也是要增强request对象
增强request对象
class MyDirtyRequest extends HttpServletRequestWrapper { HttpServletRequest request; //定义一堆敏感词汇 private List<String> list = Arrays.asList("傻b", "尼玛", "操蛋"); public MyDirtyRequest(HttpServletRequest request) { super(request); this.request = request; } @Override public String getParameter(String name) { String value = this.request.getParameter(name); if (value == null) { return null; } //遍历list集合,看看获取得到的数据有没有敏感词汇 for (String s : list) { if (s.equals(value)) { value = "*****"; } } return value ; } }
开发过滤器
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //将request和response强转成http协议的 HttpServletRequest httpServletRequest = (HttpServletRequest) req; HttpServletResponse httpServletResponse = (HttpServletResponse) resp; MyDirtyRequest dirtyRequest = new MyDirtyRequest(httpServletRequest); //传送给目标资源的是被增强后的request对象 chain.doFilter(dirtyRequest, httpServletResponse); }