包装设计模式

包装设计模式的实现

     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);
    }

}
原文地址:https://www.cnblogs.com/zhangxuesong/p/5276196.html