12.1、Decorator模式
即使没有某一个对象的类的源代码,甚至即便这个类是声明为final的,Decorator模式和Wrapper模式都允许装饰或包装这个对象。
Decorator模式适用于无法使用继承的情况(比如,所指对象的类为final),或者你不想亲自创建对象,而是想从另一个子系统中获取。例如,Servlet容器创建了一个ServletRequest和一个ServletResponse,并将他们传给Servlet的service方法。改变ServletRequest和ServletResponse行为的唯一方法是将他们包在其他对象中。唯一必须满足的条件是,被装饰对象的类要实现一个接口,并且要包装的方法必须从这个接口处继承。
12.2、Servlet Wrapper类
Servlet API中提供了4个类,他们很少用到,但是功能非常强大,分别是:ServletRequestWrapper、ServletResponseWrapper,以及HttpServletRequestWrapper和HttpServletResponseWrapper。
ServletRequestWrapper使用起来非常方便,由于它为调用被包装ServletRequest中的对等方法的每一个方法都提供了默认实现。通过继承则只好直接实现ServletRequest,并为接口中的每一个方法都提供实现。
12.3、范例:AutoCorrect过滤器
在web应用程序中,用户经常会在输入值时,在其前面或者后面添加一些空格,甚至在词与词之间也会有多余空格。你又不想到应用程序的逐个Servlet中进行检查并删除多余的空格。那么本届介绍的AutoCorrect过滤器的特性就可以帮你完成这些工作。这个过滤器中包含一个HttpServletRequestWrapper的子类,命名为AutoCorrectHttpServletRequestWrapper,并覆盖返回一个或多个参数值的下列方法:getParameter、getParameterValues和getParameterMap。
AutoCorrectFilter.Java
- package filter;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashSet;
- import java.util.Map;
- import java.util.Set;
- 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.annotation.WebFilter;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletRequestWrapper;
- @WebFilter(filterName = "AutoCorrectFilter", urlPatterns = {"/*"})
- public class AutoCorrectFilter implements Filter{
- @Override
- public void destroy() {
- // TODO Auto-generated method stub
- }
- @Override
- public void init(FilterConfig arg0) throws ServletException {
- // TODO Auto-generated method stub
- }
- @Override
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain filterChain) throws IOException, ServletException {
- HttpServletRequest httpServletRequest = (HttpServletRequest)request ;
- AutoCorrectHttpServletRequestWrapper wrapper = new
- AutoCorrectHttpServletRequestWrapper(httpServletRequest) ;
- filterChain.doFilter(wrapper, response);
- }
- class AutoCorrectHttpServletRequestWrapper extends HttpServletRequestWrapper{
- private HttpServletRequest httpServletRequest ;
- public AutoCorrectHttpServletRequestWrapper(HttpServletRequest httpServletRequest) {
- super(httpServletRequest);
- this.httpServletRequest = httpServletRequest ;
- }
- @Override
- public String getParameter(String name) {
- return autoCorrect(httpServletRequest.getParameter(name)) ;
- }
- @Override
- public String[] getParameterValues(String name) {
- // TODO Auto-generated method stub
- return autoCorrect(httpServletRequest.getParameterValues(name));
- }
- @Override
- public Map<String, String[]> getParameterMap() {
- // TODO Auto-generated method stub
- final Map<String, String[]> parameterMap = httpServletRequest.getParameterMap() ;
- Map<String, String[]> newMap = new Map<String, String[]>(){
- @Override
- public int size() {
- return parameterMap.size();
- }
- @Override
- public boolean isEmpty() {
- return parameterMap.isEmpty();
- }
- @Override
- public boolean containsKey(Object key) {
- return parameterMap.containsKey(key);
- }
- @Override
- public boolean containsValue(Object value) {
- return parameterMap.containsValue(value);
- }
- @Override
- public String[] get(Object key) {
- return autoCorrect(parameterMap.get(key));
- }
- @Override
- public String[] put(String key, String[] value) {
- return parameterMap.put(key, value);
- }
- @Override
- public String[] remove(Object key) {
- return parameterMap.remove(key);
- }
- @Override
- public void putAll(Map<? extends String, ? extends String[]> m) {
- parameterMap.putAll(m);
- }
- @Override
- public void clear() {
- parameterMap.clear();
- }
- @Override
- public Set<String> keySet() {
- return parameterMap.keySet();
- }
- @Override
- public Collection<String[]> values() {
- return autoCorrect(parameterMap.values());
- }
- @Override
- public Set<java.util.Map.Entry<String, String[]>> entrySet() {
- return autoCorrect(parameterMap.entrySet());
- }
- } ;
- return newMap ;
- }
- }
- private String autoCorrect(String value){
- if(value == null){
- return null ;
- }
- value = value.trim() ;
- int length = value.length() ;
- StringBuilder temp = new StringBuilder() ;
- boolean lastCharWasSpace = false ;
- for(int i = 0; i<length; i++){
- char c = value.charAt(i) ;
- if(c == ' '){
- if(!lastCharWasSpace){
- temp.append(c) ;
- }
- lastCharWasSpace = true ;
- }else{
- temp.append(c) ;
- lastCharWasSpace = false ;
- }
- }
- return temp.toString() ;
- }
- private String[] autoCorrect(String[] values){
- if(values != null){
- int length = values.length ;
- for(int i=0; i<length; i++){
- values[i] = autoCorrect(values[i]) ;
- }
- return values ;
- }
- return null ;
- }
- @SuppressWarnings("unused")
- private Collection<String[]> autoCorrect(Collection<String[]> valueCollection){
- Collection<String[]> newCollection = new ArrayList<String[]>() ;
- for(String[] values : valueCollection){
- newCollection.add(autoCorrect(values)) ;
- }
- return newCollection ;
- }
- private Set<Map.Entry<String, String[]>> autoCorrect(Set<Map.Entry<String, String[]>> entrySet){
- Set<Map.Entry<String, String[]>> newSet = new HashSet<Map.Entry<String, String[]>>() ;
- for(final Map.Entry<String, String[]> entry : entrySet){
- Map.Entry<String, String[]> newEntry = new Map.Entry<String, String[]>() {
- @Override
- public String getKey() {
- return entry.getKey();
- }
- @Override
- public String[] getValue() {
- return autoCorrect(entry.getValue());
- }
- @Override
- public String[] setValue(String[] value) {
- return entry.setValue(value);
- }
- };
- newSet.add(newEntry) ;
- }
- return newSet ;
- }
- }
test1.jsp
- <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
- <%
- String path = request.getContextPath();
- String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
- %>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <base href="<%=basePath%>">
- <title>User Form</title>
- <meta http-equiv="pragma" content="no-cache">
- <meta http-equiv="cache-control" content="no-cache">
- <meta http-equiv="expires" content="0">
- <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
- <meta http-equiv="description" content="This is my page">
- <!--
- <link rel="stylesheet" type="text/css" href="styles.css">
- -->
- </head>
- <body>
- <form action="test2.jsp" method="post">
- <table>
- <tr>
- <td>Name:</td>
- <td><input name="name"/></td>
- </tr>
- <tr>
- <td>Address:</td>
- <td><input name="address"/></td>
- </tr>
- <tr>
- <td colspan="2">
- <input type="submit" value="Login"/>
- </td>
- </tr>
- </table>
- </form>
- </body>
- </html>
- <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
- <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
- <%
- String path = request.getContextPath();
- String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
- %>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <base href="<%=basePath%>">
- <title>Form Values</title>
- <meta http-equiv="pragma" content="no-cache">
- <meta http-equiv="cache-control" content="no-cache">
- <meta http-equiv="expires" content="0">
- <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
- <meta http-equiv="description" content="This is my page">
- <!--
- <link rel="stylesheet" type="text/css" href="styles.css">
- -->
- </head>
- <body>
- <table>
- <tr>
- <td>Name:</td>
- <td>
- ${param.name}
- (length:${fn:length(param.name)})
- </td>
- </tr>
- <tr>
- <td>Address:</td>
- <td>
- ${param.address}
- (length:${fn:length(param.address)})
- </td>
- </tr>
- </table>
- </body>
- </html>
运行结果: