[javaweb]Java过滤器与包装设计模式的实用案例.
在filter中可以得到代表用户请求和响应的request、response对象,因此在编程中可以使用Decorator(装饰器)模式对request、response对象进行包装,再把包装对象传给目标资源,从而实现一些特殊需求。 当某个对象的方法不适应业务需求时,通常有2种方式可以对方法进行增强:
在阎宏博士的《JAVA与模式》一书中开头是这样描述装饰(Decorator)模式的:装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。 那么在实际应用中遇到需增强对象的方法时,到底选用哪种方式比较好呢?这个没有具体的定式,只能是根据具体的需求来采用具体的方式,不过有一种情况下,必须使用Decorator设计模式:即被增强的对象,开发人员只能得到它的对象,无法得到它的class文件。比如request、response对象,开发人员之所以在servlet中能通过sun公司定义的HttpServletRequestresponse接口去操作这些对象,是因为Tomcat服务器厂商编写了request、response接口的实现类。web服务器在调用servlet时,会用这些接口的实现类创建出对象,然后传递给servlet程序。此种情况下,由于开发人员根本不知道服务器厂商编写的request、response接口的实现类是哪个?在程序中只能拿到服务器厂商提供的对象,因此就只能采用Decorator设计模式对这些对象进行增强。 1.首先看需要被增强对象继承了什么接口或父类,编写一个类也去继承这些接口或父类。 2.在类中定义一个变量,变量类型即需增强对象的类型。 3.在类中定义一个构造函数,接收需增强的对象。 4.覆盖需增强的方法,编写增强的代码。 Servlet API 中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper,HttpServletRequestWrapper 类实现了request 接口中的所有方法,但这些方法的内部实现都是仅仅调用了一下所包装的的 request 对象的对应方法,以避免用户在对request对象进行增强时需要实现request接口中的所有方法。 编写一个用于处理中文乱码的过滤器CharacterEncodingFilter,代码如下:
CharacterEncodingFilter
FilterConfig filterConfig =
String defaultCharset = "UTF-8"
FilterChain chain)
HttpServletRequest request = HttpServletResponse response =
String charset = filterConfig.getInitParameter("charset" (charset== charset = response.setContentType("text/html;charset="+
MyCharacterEncodingRequest requestWrapper =
init(FilterConfig filterConfig)
.filterConfig =
MyCharacterEncodingRequest
.request =
String value= (value==
(!.request.getMethod().equalsIgnoreCase("get" }
value = String(value.getBytes("ISO8859-1"), } }
??? 在web.xml文件中配置CharacterEncodingFilter: ???? 编写jsp测试页面,如下: <%@ page language="java" pageEncoding="UTF-8"%>
<%--引入jstl标签库 --%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%--使用post方式提交表单 --%> 编写处理用户请求的ServletDemo1 ServletDemo1
String username = request.getParameter("username"
String method =
PrintWriter out = out.write("请求的方式:"+ out.write("
" out.write("接收到的参数:"+ } 这样,无论是get请求方式还是post请求方式,中文乱码问题都可以完美解决了。 编写一个html转义过滤器,代码如下: HtmlFilter
FilterChain chain)
HttpServletRequest request = HttpServletResponse response =
MyHtmlRequest myrequest =
init(FilterConfig filterConfig)
MyHtmlRequest
.request =
String value = (value ==
(message == content[] = message.getChars(0,message.length(),content,0 StringBuffer result = StringBuffer(content.length + 50 ( i = 0; i < content.length; i++ '<' result.append("<" '>' result.append(">" '&' result.append("&" '"' result.append(""" }
在web.xml文件中配置HtmlFilter 编写jsp测试页面,如下: <%@ page language="java" ="java.util.*" pageEncoding="UTF-8"%>
编写处理用户请求的ServletDemo2 ServletDemo2
String message = request.getParameter("message" response.getWriter().write("您上次的留言是:
" + } 这样,所有的html标签都被转义输出了。 编写一个敏感字符过滤器,代码如下: DirtyFilter
FilterConfig config =
init(FilterConfig filterConfig) .config =
FilterChain chain)
HttpServletRequest request = HttpServletResponse response = DirtyRequest dirtyrequest =
List
在web.xml文件中配置DirtyFilter ????? 当用户填写的内容包含一些敏感字符时,在DirtyFilter过滤器中就会将这些敏感字符替换掉。 我们如果将上述的CharacterEncodingFilter、HtmlFilter、DirtyFilter这三个过滤器联合起来使用,那么就相当于是把request对象包装了3次,request对象的getParameter方法经过3次重写,使得getParameter方法的功能大大增强,可以同时解决中文乱码,html标签转义,敏感字符过滤这些需求。 在实际开发中完全可以将上述的三个过滤器合并成一个,让合并后的过滤器具有解决中文乱码,html标签转义,敏感字符过滤这些功能,例如: AdvancedFilter
FilterConfig filterConfig =
String defaultCharset = "UTF-8"
init(FilterConfig filterConfig)
.filterConfig =
FilterChain chain) HttpServletRequest request = HttpServletResponse response =
String charset = filterConfig.getInitParameter("charset" (charset== charset = response.setContentType("text/html;charset="+
AdvancedRequest requestWrapper =
AdvancedRequest
List |