jsp 修饰 Request 及Response
Posted 飞龙dragon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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>
输入一个带空格的单词,无论是前面、后面,还是 在单词之间,然后点击提交。接下来,在显示器上你将 看到这些输入单词都被修正过来
以上是关于jsp 修饰 Request 及Response的主要内容,如果未能解决你的问题,请参考以下文章
JSP request.setAttribute()详解及实例
request.getRequestDispatcher("**.jsp").forward(request,response);乱码的解决
response.sendRedirect()与request.getRequestDispatcher("/index.jsp").forward(request, respon