请求和响应的装饰——装饰器设计模式

一、装饰器设计模式

即使没有某一个对象的类的源代码,甚至即便这个类是声明为final的,Decorator模式和Wrapper模式都允许装饰或者包装(说白了,就是修改)这个对象的行为。

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

二、Decorator模式的UML


解释:

Component接口就好比ServletRequest

ConcreteComponent就好比HttpServletRequest

Decorator就好比ServletRequestWrapper

而ConcreterDecorator就好比HttpServletRequestWraper

其中Operation()方法是在Component接口中定义的方法。

因此呢,可以在HttpServletRequestWrapper中对其公有方法进行修改


三、具体实例:自动校验过滤器

功能描述:该过滤器能够对用户输入的变量进行检验,过滤掉字符串开始和结束部分的空白字符。

四、源代码:

package com.tanjie.decorator;

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;

/**
 * Servlet Filter implementation class AutoCorrectFilter
 */
public class AutoCorrectFilter implements Filter {

    /**
     * Default constructor. 
     */
    public AutoCorrectFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpServletRequest = (HttpServletRequest)request;
		AutoCorrectHttpServletRequestWrapper wrapper = new AutoCorrectHttpServletRequestWrapper(httpServletRequest);
		chain.doFilter(wrapper, response);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

package com.tanjie.decorator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;


public class AutoCorrectHttpServletRequestWrapper extends HttpServletRequestWrapper {
	HttpServletRequest httpServletRequest;

	public AutoCorrectHttpServletRequestWrapper(HttpServletRequest httpServletRequest) {
		super(httpServletRequest);
		this.httpServletRequest = httpServletRequest;
	}
	
	public String getParameter(String name){
		return autoCorrect(httpServletRequest.getParameter(name));
	}
	public String[] getParameterValues(String name){
		return autoCorrect(httpServletRequest.getParameterValues(name));
	}
	public Map<String, String[]> getParameterMap(){
		final Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();
		Map<String, String[]> newMap = new Map<String, String[]>(){

			public int size() {
				return parameterMap.size();
			}

			public boolean isEmpty() {
				// TODO Auto-generated method stub
				return parameterMap.isEmpty();
			}

			public boolean containsKey(Object key) {
				return parameterMap.containsKey(key);
			}

			public boolean containsValue(Object value) {
				return parameterMap.containsValue(value);
			}

			public String[] get(Object key) {
				return autoCorrect(parameterMap.get(key));
			}

			public String[] remove(Object key) {
				// TODO Auto-generated method stub
				return null;
			}

			public void putAll(Map<? extends String, ? extends String[]> map) {
				
				parameterMap.putAll(map);
			}
			
			public void clear() {
				// TODO Auto-generated method stub
				parameterMap.clear();
			}

			public Set<String> keySet() {
				// TODO Auto-generated method stub
				return parameterMap.keySet();
			}

			public Collection<String[]> values() {
				// TODO Auto-generated method stub
				return autoCorrect(parameterMap.values());
			}	

			public Set<java.util.Map.Entry<String, String[]>> entrySet() {
				// TODO Auto-generated method stub
				return autoCorrect(parameterMap.entrySet());
			}
			
			public String[] put(String key, String[] value){
				return parameterMap.put(key, value);
			}
			
		};
		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);
				}else{
					lastCharWasSpace = true;
				}	
			}else{
				temp.append(c);
				lastCharWasSpace = false;
			}
		}*/
		//return temp.toString();
		return value;
	}
	
	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;
	} 
	
	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[]>() {

				public String getKey() {
					// TODO Auto-generated method stub
					return entry.getKey();
				}

				public String[] getValue() {
					// TODO Auto-generated method stub
					return autoCorrect(entry.getValue());
				}

				public String[] setValue(String[] value) {
					// TODO Auto-generated method stub
					return entry.setValue(value);
				}
			};
			newSet.add(newEntry);
		}
		return newSet;	
	}
}

	

五、总结

ServletAPI中提供了4个包装类,分别是ServletRequestWrapper、ServletResponseWrapper、HttpServletRequestWrapper、HttpServletResponseWrapper。可以使用继承它们来装饰Servlet请求和Servlet响应。之后,可以利用过滤器或者监听器创建一个包装类,并将它传递给Servlet的service方法。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值