zoukankan      html  css  js  c++  java
  • jsp 修饰 Request 及Response

      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 implementation
    public Decorator(Component component) {
    this.decorated = component;
    }
    // undecorated method
    @Override
    public void methodA(args) {
    decorated.methodA(args);
    }
    // decorated method
    @Override
    public 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<String, String[]> getParameterMap() {
                // 得到request的 parameterMap
                final Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();
                // 重写 parameterMap
                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 void clear() {
    // this will throw an IllegalStateException
    // but let the user get the original
    // exception
                        parameterMap.clear();
                    }
    
                    @Override
                    public Set<String> keySet() {
                        return parameterMap.keySet();
                    }
    
                    @Override
                    public Collection<String[]> values() {
                        return autoCorrect(parameterMap.values());
                    }
    
                    @Override
                    public Set<Map.Entry<String, String[]>> 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<? extends String, ? extends String[]> 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<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;
        }
    }

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

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

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

    test1.jsp页面

    <!DOCTYPE html>
    <html>
    <head>
    <title>User Form</title>
    </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>

    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"%>
    <!DOCTYPE html>
    <html>
    <head>
    <title>Form Values</title>
    </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>

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

  • 相关阅读:
    关于response.getWriter()写回数据的实际发生时间点
    警惕多iframe下的同名id引起的诡异问题
    spring注入静态成员变量提示invalid setter method
    plsql+绿色版oracle连接远程数据库配置及提示缺少msvcr71.dll解决方法
    <mvc:default-servlet-handler/>导致SimpleUrlHandlerMapping失效
    maven项目下jsp文件中el表达式失效问题
    Python爬虫框架Scrapy实例(三)数据存储到MongoDB
    Python爬虫实例(五) requests+flask构建自己的电影库
    MySQL与Python交互
    Python爬虫基础(四)Requests库的使用
  • 原文地址:https://www.cnblogs.com/jiangfeilong/p/10717671.html
Copyright © 2011-2022 走看看