zoukankan      html  css  js  c++  java
  • filter高级应用

    Filter高级应用:
     Decorator模式 
     1)包装类需要和被包装对象 实现相同接口,或者继承相同父类
     2)包装类需要持有 被包装对象的引用 
      在包装类中定义成员变量,通过包装类构造方法,传入被包装对象 
     3)在包装类中,可以控制原来那些方法需要加强
     不需要加强 ,调用被包装对象的方法
     需要加强,编写增强代码逻辑 
     ServletRequestWrapper 和 HttpServletRequestWrapper 
     提供对request对象进行包装的方法,但是默认情况下每个方法都是调用原来request对象的方法,
     也就是说包装类并没有对request进行增强 
     如果要增强就可以在这两个包装类基础上,继承HttpServletRequestWrapper 和 HttpServletRequestWrapper 覆盖需要增强的方法即可
     6.完全解决get和post乱码的过滤器 
     在Filter中,对request对象进行包装,增强获得参数的方法 
     getParameter 
     getParameterValues
     getParameterMap
     参考代码:

     1 public class GenericEncodingFilter implements Filter {
     2     @Override
     3     public void destroy() {
     4     }
     5     @Override
     6     public void doFilter(ServletRequest request, ServletResponse response,
     7             FilterChain chain) throws IOException, ServletException {
     8         // 转型为与协议相关对象
     9         HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    10         // 对request包装增强
    11         HttpServletRequest myrequest = new MyRequest(httpServletRequest);
    12         chain.doFilter(myrequest, response);
    13     }
    14     @Override
    15     public void init(FilterConfig filterConfig) throws ServletException {
    16     }
    17 }
     1 // 自定义request对象
     2 class MyRequest extends HttpServletRequestWrapper {
     3 
     4     private HttpServletRequest request;
     5 
     6     private boolean hasEncode;
     7 
     8     public MyRequest(HttpServletRequest request) {
     9         super(request);// super必须写
    10         this.request = request;
    11     }
    12     // 对需要增强方法 进行覆盖
    13     @Override
    14     public Map getParameterMap() {
    15         // 先获得请求方式
    16         String method = request.getMethod();
    17         if (method.equalsIgnoreCase("post")) {
    18             // post请求
    19             try {
    20                 // 处理post乱码
    21                 request.setCharacterEncoding("utf-8");
    22                 return request.getParameterMap();
    23             } catch (UnsupportedEncodingException e) {
    24                 e.printStackTrace();
    25             }
    26         } else if (method.equalsIgnoreCase("get")) {
    27             // get请求
    28             Map<String, String[]> parameterMap = request.getParameterMap();
    29             if (!hasEncode) { // 确保get手动编码逻辑只运行一次
    30                 for (String parameterName : parameterMap.keySet()) {
    31                     String[] values = parameterMap.get(parameterName);
    32                     if (values != null) {
    33                         for (int i = 0; i < values.length; i++) {
    34                             try {
    35                                 // 处理get乱码
    36                                 values[i] = new String(values[i]
    37                                         .getBytes("ISO-8859-1"), "utf-8");
    38                             } catch (UnsupportedEncodingException e) {
    39                                 e.printStackTrace();
    40                             }
    41                         }
    42                     }
    43                 }
    44                 hasEncode = true;
    45             }
    46             return parameterMap;
    47         }
    48         return super.getParameterMap();
    49     }
    50     @Override
    51     public String getParameter(String name) {
    52         Map<String, String[]> parameterMap = getParameterMap();
    53         String[] values = parameterMap.get(name);
    54         if (values == null) {
    55             return null;
    56         }
    57         return values[0]; // 取回参数的第一个值
    58     }
    59     @Override
    60     public String[] getParameterValues(String name) {
    61         Map<String, String[]> parameterMap = getParameterMap();
    62         String[] values = parameterMap.get(name);
    63         return values;
    64     }
    65 }

    增强Response对象,对响应数据进行压缩
     先说一下在Tomcat服务器内,提供对响应压缩 配置实现 
     在conf/server.xml 中 
     <Connector port="80" protocol="HTTP/1.1" 
                   connectionTimeout="20000" 
                   redirectPort="8443"/> 添加 compressableMimeType="text/html,text/xml,text/plain" compression="on"

     1 public class GzipFilter implements Filter {
     2     @Override
     3     public void destroy() {
     4     }
     5     @Override
     6     public void doFilter(ServletRequest request, ServletResponse response,
     7             FilterChain chain) throws IOException, ServletException {
     8         // 自定义缓冲区,重写response的getWriter和getOutputStream
     9         HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    10         // 字节缓存区
    11         // 将数据写入内存数组中
    12         final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    13         HttpServletResponse myresponse = new HttpServletResponseWrapper(
    14                 httpServletResponse) {
    15             private PrintWriter out;
    16             @Override
    17             // 重写getWriter 流获得是对 getOutputStream 编码获得
    18             public PrintWriter getWriter() throws IOException {
    19                 System.out.println("getWriter...");
    20                 if (out == null) {
    21                     // 确保PrintWriter只有一个对象,flushbuffer中输出缓冲区内容
    22                     out = new PrintWriter(new OutputStreamWriter(
    23                             byteArrayOutputStream, getCharacterEncoding()));
    24                 }
    25                 return out;
    26             }
    27             @Override
    28             public ServletOutputStream getOutputStream() throws IOException {
    29                 System.out.println("getOutputStream...");
    30                 return new ServletOutputStream() {
    31                     @Override
    32                     // 将数据写到哪
    33                     public void write(int b) throws IOException {
    34                         // 将响应数据 写入自定义缓存区
    35                         byteArrayOutputStream.write(b);
    36                     }
    37                 };
    38             }
    39             @Override
    40             public void flushBuffer() throws IOException {
    41                 getOutputStream().flush();
    42                 getWriter().flush();
    43             }
    44         };
    45         // 目标资源执行,只有目标资源执行后,才有响应数据
    46         chain.doFilter(request, myresponse);
    47         myresponse.flushBuffer();
    48         // 目标资源已经执行过,数据已经在 byteArrayOutputStream 缓存区
    49         byte[] data = byteArrayOutputStream.toByteArray(); // data是未压缩数据
    50         System.out.println("未压缩数据长度:" + data.length);
    51         // 读data数据进行压缩
    52         byte[] gzipData = gzip(data);// gzipData是压缩后数据
    53         System.out.println("压缩后数据长度:" + gzipData.length);
    54         // 原来response 目的地是客户端浏览器
    55         httpServletResponse.setHeader("Content-Encoding", "gzip");
    56         httpServletResponse.setContentLength(gzipData.length);
    57         httpServletResponse.getOutputStream().write(gzipData);
    58         httpServletResponse.getOutputStream().flush();
    59     }
    60     // 对data数据进行gzip压缩
    61     public byte[] gzip(byte[] data) {
    62         // 定义字节缓存区,用gzip方式向缓存区写数据
    63         ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
    64         try {
    65             GZIPOutputStream gzipOutputStream = new GZIPOutputStream(
    66                     arrayOutputStream);
    67             gzipOutputStream.write(data);// 将原数据 压缩gzip格式写入新的缓存区
    68             gzipOutputStream.close();
    69             arrayOutputStream.flush();
    70             return arrayOutputStream.toByteArray();// 返回压缩后的内容
    71         } catch (IOException e) {
    72             e.printStackTrace();
    73             throw new RuntimeException("压缩失败!");
    74         }
    75     }
    76     @Override
    77     public void init(FilterConfig filterConfig) throws ServletException {
    78     }
    79 }

    天下代码一般仿写:http://blog.csdn.net/javadaddy/article/details/8142559

  • 相关阅读:
    TensorFlow gfile文件操作详解
    ROS学习之日志消息
    typeid().name()获取类型名
    Ubuntu Qt配置QVTKWidget控件
    python-pcl简易文档(不包含自建函数与pcl_grabber包)
    ros源码之初始化函数init()调用的几个初始化函数
    奇异值分解(SVD)原理
    ROS节点的初始化及退出详解(ros::init、SIGINT、ros::ok、ros::NodeHandle)
    ROS Nodehandle句柄
    C++可变参数模板
  • 原文地址:https://www.cnblogs.com/huzi007/p/4572384.html
Copyright © 2011-2022 走看看