第十二章_请求和响应的装饰

简介:

12.1Decorator模式

即使没有某一个对象的类的源代码,甚至即便这个类是声明为final的,Decorator模式和Wrapper模式都允许装饰或包装这个对象。

Decorator模式适用于无法使用继承的情况(比如,所指对象的类为final),或者你不想亲自创建对象,而是想从另一个子系统中获取。例如,Servlet容器创建了一个ServletRequest和一个ServletResponse,并将他们传给Servletservice方法。改变ServletRequestServletResponse行为的唯一方法是将他们包在其他对象中。唯一必须满足的条件是,被装饰对象的类要实现一个接口,并且要包装的方法必须从这个接口处继承。

 

12.2Servlet Wrapper

Servlet API中提供了4个类,他们很少用到,但是功能非常强大,分别是:ServletRequestWrapperServletResponseWrapper,以及HttpServletRequestWrapperHttpServletResponseWrapper

ServletRequestWrapper使用起来非常方便,由于它为调用被包装ServletRequest中的对等方法的每一个方法都提供了默认实现。通过继承则只好直接实现ServletRequest,并为接口中的每一个方法都提供实现。

 

12.3、范例:AutoCorrect过滤器

web应用程序中,用户经常会在输入值时,在其前面或者后面添加一些空格,甚至在词与词之间也会有多余空格。你又不想到应用程序的逐个Servlet中进行检查并删除多余的空格。那么本届介绍的AutoCorrect过滤器的特性就可以帮你完成这些工作。这个过滤器中包含一个HttpServletRequestWrapper的子类,命名为AutoCorrectHttpServletRequestWrapper,并覆盖返回一个或多个参数值的下列方法:getParametergetParameterValuesgetParameterMap

AutoCorrectFilter.Java

[html]  view plain  copy
 print ?
  1. package filter;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.ArrayList;  
  5. import java.util.Collection;  
  6. import java.util.HashSet;  
  7. import java.util.Map;  
  8. import java.util.Set;  
  9.   
  10. import javax.servlet.Filter;  
  11. import javax.servlet.FilterChain;  
  12. import javax.servlet.FilterConfig;  
  13. import javax.servlet.ServletException;  
  14. import javax.servlet.ServletRequest;  
  15. import javax.servlet.ServletResponse;  
  16. import javax.servlet.annotation.WebFilter;  
  17. import javax.servlet.http.HttpServletRequest;  
  18. import javax.servlet.http.HttpServletRequestWrapper;  
  19. @WebFilter(filterName = "AutoCorrectFilter"urlPatterns = {"/*"})  
  20. public class AutoCorrectFilter implements Filter{  
  21.   
  22.     @Override  
  23.     public void destroy() {  
  24.         // TODO Auto-generated method stub  
  25.           
  26.     }  
  27.       
  28.     @Override  
  29.     public void init(FilterConfig arg0) throws ServletException {  
  30.         // TODO Auto-generated method stub  
  31.           
  32.     }  
  33.   
  34.     @Override  
  35.     public void doFilter(ServletRequest request, ServletResponse response,  
  36.             FilterChain filterChain) throws IOException, ServletException {  
  37.         HttpServletRequest httpServletRequest = (HttpServletRequest)request ;  
  38.         AutoCorrectHttpServletRequestWrapper wrapper = new   
  39.                 AutoCorrectHttpServletRequestWrapper(httpServletRequest) ;  
  40.         filterChain.doFilter(wrapper, response);  
  41.     }  
  42.       
  43.     class AutoCorrectHttpServletRequestWrapper extends HttpServletRequestWrapper{  
  44.         private HttpServletRequest httpServletRequest ;  
  45.         public AutoCorrectHttpServletRequestWrapper(HttpServletRequest httpServletRequest) {  
  46.             super(httpServletRequest);  
  47.             this.httpServletRequest = httpServletRequest ;  
  48.         }  
  49.         @Override  
  50.         public String getParameter(String name) {  
  51.             return autoCorrect(httpServletRequest.getParameter(name)) ;  
  52.         }  
  53.         @Override  
  54.         public String[] getParameterValues(String name) {  
  55.             // TODO Auto-generated method stub  
  56.             return autoCorrect(httpServletRequest.getParameterValues(name));  
  57.         }  
  58.         @Override  
  59.         public Map<String, String[]> getParameterMap() {  
  60.             // TODO Auto-generated method stub  
  61.             final Map<String, String[]> parameterMap = httpServletRequest.getParameterMap() ;  
  62.             Map<String, String[]> newMap = new Map<String, String[]>(){  
  63.                 @Override  
  64.                 public int size() {  
  65.                     return parameterMap.size();  
  66.                 }  
  67.   
  68.                 @Override  
  69.                 public boolean isEmpty() {  
  70.                     return parameterMap.isEmpty();  
  71.                 }  
  72.   
  73.                 @Override  
  74.                 public boolean containsKey(Object key) {  
  75.                     return parameterMap.containsKey(key);  
  76.                 }  
  77.   
  78.                 @Override  
  79.                 public boolean containsValue(Object value) {  
  80.                     return parameterMap.containsValue(value);  
  81.                 }  
  82.   
  83.                 @Override  
  84.                 public String[] get(Object key) {  
  85.                     return autoCorrect(parameterMap.get(key));  
  86.                 }  
  87.   
  88.                 @Override  
  89.                 public String[] put(String key, String[] value) {  
  90.                     return parameterMap.put(key, value);  
  91.                 }  
  92.   
  93.                 @Override  
  94.                 public String[] remove(Object key) {  
  95.                     return parameterMap.remove(key);  
  96.                 }  
  97.   
  98.                 @Override  
  99.                 public void putAll(Map<? extends String, ? extends String[]> m) {  
  100.                     parameterMap.putAll(m);  
  101.                 }  
  102.   
  103.                 @Override  
  104.                 public void clear() {  
  105.                     parameterMap.clear();  
  106.                 }  
  107.   
  108.                 @Override  
  109.                 public Set<String> keySet() {  
  110.                     return parameterMap.keySet();  
  111.                 }  
  112.   
  113.                 @Override  
  114.                 public Collection<String[]> values() {  
  115.                     return autoCorrect(parameterMap.values());  
  116.                 }  
  117.   
  118.                 @Override  
  119.                 public Set<java.util.Map.Entry<String, String[]>> entrySet() {  
  120.                     return autoCorrect(parameterMap.entrySet());  
  121.                 }  
  122.                   
  123.             } ;  
  124.             return newMap ;  
  125.         }  
  126.           
  127.     }   
  128.     private String autoCorrect(String value){  
  129.         if(value == null){  
  130.             return null ;  
  131.         }  
  132.         value = value.trim() ;  
  133.         int length = value.length() ;  
  134.         StringBuilder temp = new StringBuilder() ;  
  135.         boolean lastCharWasSpace = false ;  
  136.         for(int i = 0; i<length; i++){  
  137.             char c = value.charAt(i) ;  
  138.             if(c == ' '){  
  139.                 if(!lastCharWasSpace){  
  140.                     temp.append(c) ;  
  141.                 }  
  142.                 lastCharWasSpace = true ;  
  143.             }else{  
  144.                 temp.append(c) ;  
  145.                 lastCharWasSpace = false ;  
  146.             }  
  147.         }  
  148.         return temp.toString() ;  
  149.     }  
  150.     private String[] autoCorrect(String[] values){  
  151.         if(values != null){  
  152.             int length = values.length ;  
  153.             for(int i=0; i<length; i++){  
  154.                 values[i] = autoCorrect(values[i]) ;  
  155.             }  
  156.             return values ;  
  157.         }  
  158.         return null ;  
  159.     }  
  160.     @SuppressWarnings("unused")  
  161.     private Collection<String[]> autoCorrect(Collection<String[]> valueCollection){  
  162.         Collection<String[]> newCollection = new ArrayList<String[]>() ;  
  163.         for(String[] values : valueCollection){  
  164.             newCollection.add(autoCorrect(values)) ;  
  165.         }  
  166.         return newCollection ;  
  167.     }  
  168.     private Set<Map.Entry<String, String[]>> autoCorrect(Set<Map.Entry<String, String[]>> entrySet){  
  169.         Set<Map.Entry<String, String[]>> newSet = new HashSet<Map.Entry<String, String[]>>() ;  
  170.         for(final Map.Entry<String, String[]> entry : entrySet){  
  171.             Map.Entry<String, String[]> newEntry = new Map.Entry<String, String[]>() {  
  172.                 @Override  
  173.                 public String getKey() {  
  174.                     return entry.getKey();  
  175.                 }  
  176.                 @Override  
  177.                 public String[] getValue() {  
  178.                     return autoCorrect(entry.getValue());  
  179.                 }  
  180.                 @Override  
  181.                 public String[] setValue(String[] value) {  
  182.                     return entry.setValue(value);  
  183.                 }  
  184.             };  
  185.             newSet.add(newEntry) ;  
  186.         }  
  187.         return newSet ;  
  188.     }  
  189. }  

test1.jsp
[html]  view plain  copy
 print ?
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  5. %>  
  6.   
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  8. <html>  
  9.   <head>  
  10.     <base href="<%=basePath%>">  
  11.       
  12.     <title>User Form</title>  
  13.       
  14.     <meta http-equiv="pragma" content="no-cache">  
  15.     <meta http-equiv="cache-control" content="no-cache">  
  16.     <meta http-equiv="expires" content="0">      
  17.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  18.     <meta http-equiv="description" content="This is my page">  
  19.     <!-- 
  20.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  21.     -->  
  22.   
  23.   </head>  
  24.     
  25.   <body>  
  26.     <form action="test2.jsp" method="post">  
  27.         <table>  
  28.             <tr>  
  29.                 <td>Name:</td>  
  30.                 <td><input name="name"/></td>  
  31.             </tr>  
  32.             <tr>  
  33.                 <td>Address:</td>  
  34.                 <td><input name="address"/></td>  
  35.             </tr>  
  36.             <tr>  
  37.                 <td colspan="2">  
  38.                     <input type="submit" value="Login"/>  
  39.                 </td>  
  40.             </tr>  
  41.         </table>  
  42.     </form>  
  43.   </body>  
  44. </html>  
test2.jsp

[html]  view plain  copy
 print ?
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>  
  3. <%  
  4. String path = request.getContextPath();  
  5. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  6. %>  
  7.   
  8. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  9. <html>  
  10.   <head>  
  11.     <base href="<%=basePath%>">  
  12.       
  13.     <title>Form Values</title>  
  14.       
  15.     <meta http-equiv="pragma" content="no-cache">  
  16.     <meta http-equiv="cache-control" content="no-cache">  
  17.     <meta http-equiv="expires" content="0">      
  18.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  19.     <meta http-equiv="description" content="This is my page">  
  20.     <!-- 
  21.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  22.     -->  
  23.   
  24.   </head>  
  25.     
  26.   <body>  
  27.     <table>  
  28.             <tr>  
  29.                 <td>Name:</td>  
  30.                 <td>  
  31.                     ${param.name}  
  32.                     (length:${fn:length(param.name)})  
  33.                 </td>  
  34.             </tr>  
  35.             <tr>  
  36.                 <td>Address:</td>  
  37.                 <td>  
  38.                     ${param.address}  
  39.                     (length:${fn:length(param.address)})  
  40.                 </td>  
  41.             </tr>  
  42.         </table>  
  43.   </body>  
  44. </html>  

运行结果:


目录
相关文章
|
网络协议 网络架构
数据从发出到接收的细节介绍{封装与解封装}
本文将介绍了详细的封装在每一层的具体的操作,可以让大家学习到数据从发出到收到的具体过程。
多个装饰器,执行顺序,以及自己编写响应以及请求
多个装饰器,执行顺序,以及自己编写响应以及请求
|
5月前
|
Java 开发者
深入Java多态:从“一个消息”到“多种响应”的进化之路
【6月更文挑战第17天】Java多态性简化教育软件开发:通过抽象Course类定义teach()方法,子类如MathCourse、EnglishCourse和ScienceCourse重写该方法,实现特定教学内容。在CourseManagementSystem中,多态允许通过Course引用调用不同课程的teach(),展示“一个消息,多种响应”的能力,增强代码灵活性和可维护性,是面向对象编程的关键。
32 2
|
6月前
|
前端开发
AJAX发送请求方法封装和请求函数底层刨析以及axios二次封装
AJAX发送请求方法封装和请求函数底层刨析以及axios二次封装
|
6月前
|
存储 JSON 前端开发
【工作中问题解决实践 十二】使用@JsonTypeInfo实现请求数据对象多态
【工作中问题解决实践 十二】使用@JsonTypeInfo实现请求数据对象多态
276 0
|
前端开发
前端工作小结11-封装请求
前端工作小结11-封装请求
112 0
|
JSON API 数据格式
「造个轮子」——设计 HTTP 请求全局上下文(下)
本次 Cicada 已经更新到了 v1.0.3。 主要是解决了两个 issue,#9(Boss线程数好像设置有误 ) #8(怎么返回纯字符串内容不要JSON格式?)。 所以本次的主要更新为: Cicada 采用合理的线程分配来处理接入请求线程以及 IO 线程。 支持多种响应方式(以前只有 json,现在支持 text)。 为了满足上者引入了 context。 优雅停机。 其中我觉得最核心也最有用的就是这个 Context,并为此重构了大部分代码。
|
存储 JSON API
「造个轮子」——设计 HTTP 请求全局上下文(上)
本次 Cicada 已经更新到了 v1.0.3。 主要是解决了两个 issue,#9(Boss线程数好像设置有误 ) #8(怎么返回纯字符串内容不要JSON格式?)。 所以本次的主要更新为: Cicada 采用合理的线程分配来处理接入请求线程以及 IO 线程。 支持多种响应方式(以前只有 json,现在支持 text)。 为了满足上者引入了 context。 优雅停机。 其中我觉得最核心也最有用的就是这个 Context,并为此重构了大部分代码。