博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jsp 修饰 Request 及Response
阅读量:4673 次
发布时间:2019-06-09

本文共 8864 字,大约阅读时间需要 29 分钟。

 

 

  Servlet API包含4个可修饰的类,用于改变Servlet Request以及Servlet Response。这种修饰允许修改 ServletRequest以及ServletResponse或者HTTP中的等价 类(即HttpServletRequest和HttpServletResponse)中的 任务方法。这种修饰遵循Decorator模式或者Wrapper模 式,因此在使用修饰前,需要了解一下该模式的内容。

一.Decorator 模式( 装饰器模式)

  Decorator模式或者Wrapper模式允许修饰或者封装 (在字面意义中,即修改行为)一个对象,即使你没有 该对象的源代码或者该对象标识为final。

   Decorator模式适用于无法继承该类(例如,对象的 实现类使用final标识)或者无法创建该类的实例,但可 以从另外的系统中可以取得该类的实现时。例如, Servlet容器方法。只有一种方法可以修改ServletRequest 或者ServletResponse行为,即在另外的对象中封装该实 例。唯一的限制是,修饰对象必须继承一个接口,然后 实现接口以封装这些方法。

  

  

  类图说明了一个Component接口以及它 的实现类ComponentImpl。Component接口定义了A的方 法。为了修饰ComponentImpl的实例,需要创建一个 Decorator类,并实现Component的接口,然后在子类中 扩展Decorator的新行为。在类图中DecoratorA就是 Decorator的一个子类。每个Decorator实例需要包含 Component的一个实例。Decorator类代码如下(注意在 构建函数中获取了Component的实例,这意味着创建 Decorator对象只能传入Component的实例):

public class Decorator implements Component {private Component decorated;// constructor takes a Component implementationpublic Decorator(Component component) {this.decorated = component;}// undecorated method@Overridepublic void methodA(args) {decorated.methodA(args);}// decorated method@Overridepublic void methodB(args) {decorated.methodB(args)}}

  在Decorator类中,有修饰的方法就是可能在子类中 需要修改行为的方法,在子类中不需要修饰的方法可以 不需要实现。所有的方法,无论是否需要修饰,都叫作 Component中的配对方法。Decorator是一个非常简单的 类,便于提供每个方法的默认实现。修改行为在它的子 类中。

  需要牢记一点,Decorator类及被修饰对象的类需要 实现相同的接口。为了实现Decorator,可以在Decorator 中封装修饰对象,并把Decorator作为Component的一个 实现。任何Component的实现都可以在Decorator中注 入。事实上,你可以把一个修饰的对象传入另一个修饰 的对象,以实现双重的修饰。

二. Servlet封装类

  Servlet API源自于4个实现类,它很少被使用,但 是十分强大:ServletRequestWrapper、 ServletResponseWrapper以及 HttpServletRequestWrapper、 HttpServletResponseWrapper。

  ServletRequestWrapper(或者其他3个Wrapper类) 非常便于使用,因为它提供了每个方法的默认实现:即 ServletRequest封闭的配置方法。通过继承 ServletRequestWrapper,只需要实现你需要变更的方法 就可以了。如果不用ServletRequestWrapper,则需要继 承ServletRequest并实现ServletRequest中所有的方法。

  图所示为Decorator模式中 ServletRequestWrapper的类图。Servlet容器在每次 Servlet服务调用时创建ServletRequest、ContainerImpl。 直接扩展ServletRequestWrapper就可以修饰 ServletRequest了。

 

三. 示例:AutoCorrect Filter

  在Web应用中,用户经常在单词的前面或者后面输 入空格,更有甚者在单词之间也加入空格。是否很想在 应用的每个Servlet中,把多余的空格删除掉呢?本节的 AutoCorrect Filter可以帮助你搞定它。该Filter包含了 HttpServletRequestWrapper子类 AutoCorrectHttpServletRequestWrapper,并重写了返回 参数值的方法:getParameter、getParameterValues及 getParameterMap。代码如下所示。

AutoCorrectFilter 类

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;// urlPatterns={"/*"}  不能过滤链接@WebFilter(filterName = "AutoCorrectFilter", urlPatterns = { "*" })public class AutoCorrectFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @Override    public void destroy() {    }    @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) {            return autoCorrect(httpServletRequest.getParameterValues(name));        }                //用匿名内部类 重写 getParameterMap() 方法        @Override        public Map
getParameterMap() { // 得到request的 parameterMap final Map
parameterMap = httpServletRequest.getParameterMap(); // 重写 parameterMap Map
newMap = new Map
() { @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 void clear() {// this will throw an IllegalStateException// but let the user get the original// exception parameterMap.clear(); } @Override public Set
keySet() { return parameterMap.keySet(); } @Override public Collection
values() { return autoCorrect(parameterMap.values()); } @Override public Set
> entrySet() { return autoCorrect(parameterMap.entrySet()); } @Override public String[] put(String key, String[] value) {// this will throw an IllegalStateException// but let the user get the original// exception return parameterMap.put(key, value); } @Override public void putAll(Map
map) {// this will throw an IllegalStateException// but let// the user get the original exception parameterMap.putAll(map); } @Override public String[] remove(Object key) {// this will throw an IllegalStateException,// but let// the user get the original exception return parameterMap.remove(key); } }; //返回一个新的map return newMap; } } private String autoCorrect(String value) { if (value == null) { return null; } // 去除String头尾空格 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 == ' ') { // 如果是空格且是最后一个字符 就添加到temp if (!lastCharWasSpace) { temp.append(c); } lastCharWasSpace = true; } else { // 不是空格的字符直接添加到temp 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; } private Collection
autoCorrect(Collection
valueCollection) { Collection
newCollection = new ArrayList
(); for (String[] values : valueCollection) { newCollection.add(autoCorrect(values)); } return newCollection; } private Set
> autoCorrect(Set
> entrySet) { Set
> newSet = new HashSet
>(); for (final Map.Entry
entry : entrySet) { Map.Entry
newEntry = new Map.Entry
() { @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; }}

  这个Filter的doFilter方法非常简单:创建 ServletRequest的修饰实现,然后,把修饰类传给 doFilter

HttpServletRequest httpServletRequest =(HttpServletRequest) request;AutoCorrectHttpServletRequestWrapper wrapper = newAutoCorrectHttpServletRequestWrapper(httpServletRequest);filterChain.doFilter(wrapper, response);

  在这个Filter背后的任何Servlet获得的 HttpServletRequest都将被AutoCorrectHttp ServletRequestWrapper 所封装。这个封装类很长,但很 好理解。简单地说,就是它把所有获取参数的响应都调 用了一下autoCorrect方法:

test1.jsp页面

User Form
Name:
Address:

 

 

test2.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>Form Values    
Name: ${param.name} (length:${fn:length(param.name)})
Address: ${param.address} (length:${fn:length(param.address)})

   输入一个带空格的单词,无论是前面、后面,还是 在单词之间,然后点击提交。接下来,在显示器上你将 看到这些输入单词都被修正过来

转载于:https://www.cnblogs.com/jiangfeilong/p/10717671.html

你可能感兴趣的文章
黑客dos命令大全
查看>>
https soap链接示例
查看>>
八LWIP学习笔记之用户编程接口(NETCONN)
查看>>
Git Day02,工作区,暂存区,回退,删除文件
查看>>
Windows Phone 7 Coding4Fun控件简介
查看>>
Nginx 常用命令总结
查看>>
hall wrong behavior
查看>>
Markdown test
查看>>
Collection集合
查看>>
int最大值+1为什么是-2147483648最小值-1为什么是2147483647
查看>>
【C++】const在不同位置修饰指针变量
查看>>
github新项目挂历模式
查看>>
编写jquery插件
查看>>
敏捷开发笔记
查看>>
神秘海域:顶级工作室“顽皮狗”成长史(下)
查看>>
C++指针、引用知多少?
查看>>
services 系统服务的启动、停止、卸载
查看>>
Fiddler 网页采集抓包利器__手机app抓包
查看>>
Number and String
查看>>
java中的值传递和引用传递2<原文:http://blog.csdn.net/niuniu20008/article/details/2953785>...
查看>>