包装设计模式的实现
1.首先看需要被增强对象继承了什么接口或父类,编写一个类也去继承这些接口或父类。
2.在类中定义一个变量,变量类型即需增强对象的类型。
3.在类中定义一个构造函数,接收需增强的对象。
4.覆盖需增强的方法,编写增强的代码。
例子
使用Decorator设计模式增强request对象
Servlet API 中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper,HttpServletRequestWrapper 类实现了request 接口中的所有方法,但这些方法的内部实现都 是仅仅调用了一下所包装的的 request 对象的对应方法,以避免用户在对request对象进行增强时需要实现request接口中的所有方法。
2.1、使用Decorator模式包装request对象解决get和post请求方式下的中文乱码问题
编写一个用于处理中文乱码的过滤器CharacterEncodingFilter,代码如下:
package me.gacl.web.filter; import java.io.IOException; 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.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; /** * @ClassName: CharacterEncodingFilter * @Description: 此过滤器用来解决解决get、post请求方式下的中文乱码问题 * @author: 孤傲苍狼 * @date: 2014-8-31 下午11:09:37 * */ public class CharacterEncodingFilter implements Filter { private FilterConfig filterConfig = null; //设置默认的字符编码 private String defaultCharset = "UTF-8"; public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; //得到在web.xml中配置的字符编码 String charset = filterConfig.getInitParameter("charset"); if(charset==null){ charset = defaultCharset; } request.setCharacterEncoding(charset); response.setCharacterEncoding(charset); response.setContentType("text/html;charset="+charset); MyCharacterEncodingRequest requestWrapper = new MyCharacterEncodingRequest(request); chain.doFilter(requestWrapper, response); } public void init(FilterConfig filterConfig) throws ServletException { //得到过滤器的初始化配置信息 this.filterConfig = filterConfig; } public void destroy() { } } /** * @ClassName: MyCharacterEncodingRequest * @Description: Servlet API中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper, * (HttpServletRequestWrapper类实现了request接口中的所有方法,但这些方法的内部实现都是仅仅调用了一下所包装的的 request对象的对应方法) * 以避免用户在对request对象进行增强时需要实现request接口中的所有方法。 * 所以当需要增强request对象时,只需要写一个类继承HttpServletRequestWrapper类,然后在重写需要增强的方法即可 * @author: 孤傲苍狼 * @date: 2014-9-2 下午10:42:57 * 1.实现与被增强对象相同的接口 2、定义一个变量记住被增强对象 3、定义一个构造函数,接收被增强对象 4、覆盖需要增强的方法 5、对于不想增强的方法,直接调用被增强对象(目标对象)的方法 */ class MyCharacterEncodingRequest extends HttpServletRequestWrapper{ //定义一个变量记住被增强对象(request对象是需要被增强的对象) private HttpServletRequest request; //定义一个构造函数,接收被增强对象 public MyCharacterEncodingRequest(HttpServletRequest request) { super(request); this.request = request; } /* 覆盖需要增强的getParameter方法 * @see javax.servlet.ServletRequestWrapper#getParameter(java.lang.String) */ @Override public String getParameter(String name) { try{ //获取参数的值 String value= this.request.getParameter(name); if(value==null){ return null; } //如果不是以get方式提交数据的,就直接返回获取到的值 if(!this.request.getMethod().equalsIgnoreCase("get")) { return value; }else{ //如果是以get方式提交数据的,就对获取到的值进行转码处理 value = new String(value.getBytes("ISO8859-1"),this.request.getCharacterEncoding()); return value; } }catch (Exception e) { throw new RuntimeException(e); } } }
在web.xml文件中配置CharacterEncodingFilter
<!--配置字符过滤器,解决get、post请求方式下的中文乱码问题--> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>me.gacl.web.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
编写jsp测试页面,如下:
<%@ page language="java" pageEncoding="UTF-8"%>
<%--引入jstl标签库 --%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML>
<html>
<head>
<title>使用字符过滤器解决解决get、post请求方式下的中文乱码问题</title>
</head>
<body>
<%--使用c:url标签构建url,构建好的url存储在servletDemo1变量中--%>
<c:url value="/servlet/ServletDemo1" scope="page" var="servletDemo1">
<%--构建的url的附带的中文参数 ,参数名是:username,值是:笨小孩--%>
<c:param name="username" value="笨小孩"></c:param>
</c:url>
<%--使用get的方式访问 --%>
<a href="${servletDemo1}">超链接(get方式请求)</a>
<hr/>
<%--使用post方式提交表单 --%>
<form action="${pageContext.request.contextPath}/servlet/ServletDemo1" method="post">
用户名:<input type="text" name="username" value="笨小孩" />
<input type="submit" value="post方式提交">
</form>
</body>
</html>
编写处理用户请求的ServletDemo1
package me.gacl.web.controller; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletDemo1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //接收参数 String username = request.getParameter("username"); //获取请求方式 String method = request.getMethod(); //获取输出流 PrintWriter out = response.getWriter(); out.write("请求的方式:"+method); out.write("<br/>"); out.write("接收到的参数:"+username); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }