10.3示例:AutoCorrectFilter
在Web
应用中,用户经常在单词的前面或者后面输入空格,更有甚者在单词之间也加入空格。是否很想在应用的每个Servlet
中,把多余的空格删除掉呢?本节的AutoCorrectFilter
可以帮助你搞定它。该Filter
包含了HttpServletRequestWrapper
子类AutoCorrectHttpServletRequestWrapper
,并重写了返回参数值的方法:getParameter
、getParameterValues
及getParameterMap
。
AutoCorrectFilter.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| package filter; 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.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; @WebFilter( filterName = "AutoCorrectFilter", //过滤所有的URL 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); } }
|
代码详解
doFilter方法
这个Filter
的doFilter
方法非常简单:创建ServletRequest
的修饰类实例,然后,把修饰类实例传给doFilter
:
1 2 3 4 5 6 7 8 9 10
| HttpServletRequest httpServletRequest = (HttpServletRequest) request;
AutoCorrectHttpServletRequestWrapper wrapper = new AutoCorrectHttpServletRequestWrapper( httpServletRequest);
filterChain.doFilter(wrapper, response);
|
AutoCorrectHttpServletRequestWrapper.java
AutoCorrectHttpServletRequestWrapper.java
实现了对HttpServletRequest
对象的装饰.如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
| package filter; 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;
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)); } @Override public Map<String,String[]> getParameterMap() { 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 void clear() { 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) { return parameterMap.put(key, value); } @Override public void putAll(Map<? extends String,? extends String[]> map) { parameterMap.putAll(map); } @Override public String[] remove(Object key) { return parameterMap.remove(key); } }; 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; }
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
背后的任何Servlet
获得的HttpServletRequest
都将被AutoCorrectHttpServletRequestWrapper
所封装。这个封装类很长,但很好理解。简单地说,就是它把所有获取参数方法的返回值都用autoCorrect
方法先处理删除其中的空格,然后使用autoCorrect
方法处理后的结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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(); }
|
测试
测试这个Filter
时,可以分别下面的test1.jsp
,test2.jsp
这两个页面。
test1.jsp页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <!DOCTYPE HTML> <html> <head> <title>User Form</title> <style> table { font-family: verdana, arial, sans-serif; font-size: 16px; color: #333333; border-width: 1px; border-color: #a9c6c9; border-collapse: collapse; background-color: #1f3de199; } table td { border-width: 1px; padding: 8px; border-style: solid; border-color: #a9c6c9; } </style> </head> <body> <form action="test2.jsp" method="post"> <table> <tr> <td align="right">Name:</td> <td><input name="name" /></td> </tr> <tr> <td align="right">Address:</td> <td><input name="address" /></td> </tr> <tr> <td align="center" colspan="2"> <input type="submit" value="Login" /> </td> </tr> </table> </form> </body> </html>
|
test2.jsp页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%> <!DOCTYPE HTML> <html> <head> <title>Form Values</title> <!-- 引入table CSS样式用到JS代码 --> <script type="text/javascript" src="table.js"></script> <!-- 引入table的css样式 --> <link type="text/css" rel="styleSheet" href="table.css"> </head> <body> <table class="altrowstable" id="alternatecolor"> <tr> <td align="right">Name:</td> <td> ${param.name}(length:${fn:length(param.name)}) </td> </tr> <tr> <td align="right">Address:</td> <td> ${param.address}(length:${fn:length(param.address)}) </td> </tr> </table> </body> </html>
|
运行效果
可以使用如下URL
路径访问test1.jsp
页面:
http://localhost:8080/app10a/test1.jsp
输入一个带空格的单词,无论是前面、后面,还是在单词之间,然后点击提交。接下来,在显示器上你将看到这些输入单词都被修正过来。如下图所示: