通过HttpServletRequestWrapper(装饰模式的应用)增强HttpServletRequest的功能
来源:互联网 发布:core java第十版中文版 编辑:程序博客网 时间:2024/05/29 06:56
应用一:解决tomcat下中文乱码问题(先来个简单的)
在tomcat下,我们通常这样来解决中文乱码问题:
过滤器代码:
package filter;import java.io.*;import javax.servlet.*;import javax.servlet.http.*;import wrapper.GetHttpServletRequestWrapper;public class ContentTypeFilter implements Filter {private String charset = "UTF-8";private FilterConfig config;public void destroy() { System.out.println(config.getFilterName()+"被销毁");charset = null;config = null;}public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException { //设置请求响应字符编码request.setCharacterEncoding(charset);response.setCharacterEncoding(charset); HttpServletRequest req = (HttpServletRequest)request;System.out.println("----请求被"+config.getFilterName()+"过滤");//执行下一个过滤器(如果有的话,否则执行目标servlet)chain.doFilter(req, response);System.out.println("----响应被"+config.getFilterName()+"过滤");}public void init(FilterConfig config) throws ServletException { this.config = config; String charset = config.getServletContext().getInitParameter("charset"); if( charset != null && charset.trim().length() != 0) { this.charset = charset; }}}
web.xml中过滤器配置:
Xml代码
- <!--将采用的字符编码配置成应用初始化参数而不是过滤器私有的初始化参数是因为在JSP和其他地方也可能需要使用-->
- <context-param>
- <param-name>charset</param-name>
- <param-value>UTF-8</param-value>
- </context-param>
- <filter>
- <filter-name>ContentTypeFilter</filter-name>
- <filter-class>filter.ContentTypeFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>ContentTypeFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
request.setCharacterEncoding(charset); 必须写在第一次使用request.getParameter()之前,这样才能保证参数是按照已经设置的字符编码来获取。
response.setCharacterEncoding(charset);必须写在PrintWriter out = request.getWriter()之前,这样才能保证out按照已经设置的字符编码来进行字符输出。
通过过滤器,我们可以保证在Servlet或JSP执行之前就设置好了请求和响应的字符编码。
但是这样并不能完全解决中文乱码问题:
对于post请求,无论是“获取参数环节”还是“输出环节"都是没问题的;
对于get请求,"输出环节"没有问题,但是"获取参数环节"依然出现中文乱码,所以在输出时直接将乱码输出了。
原因是post请求和get请求存放参数位置是不同的:
post方式参数存放在请求数据包的消息体中。get方式参数存放在请求数据包的请求行的URI字段中,以?开始以param=value¶me2=value2的形式附加在URI字段之后。而request.setCharacterEncoding(charset); 只对消息体中的数据起作用,对于URI字段中的参数不起作用,我们通常通过下面的代码来完成编码转换:
- String paramValue = request.getParameter("paramName");
- paramValue = new String(paramValue.trim().getBytes("ISO-8859-1"), charset);
String paramValue = request.getParameter("paramName");paramValue = new String(paramValue.trim().getBytes("ISO-8859-1"), charset);
但是每次进行这样的转换实在是很麻烦,有没有统一的解决方案呢?
解决方案1: 在tomcat_home\conf\server.xml 中的Connector元素中设置URIEncoding属性为合适的字符编码
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
这样做的缺点是,同一个tomcat下的其他应用也将受到影响。而其每次部署时都需要类修改配置也很麻烦。
解决方案2:自定义请求包装器包装请求,将字符编码转换的工作添加到getParameter()方法中
package wrapper;import java.io.UnsupportedEncodingException;import java.net.URLDecoder;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper {private String charset = "UTF-8";public GetHttpServletRequestWrapper(HttpServletRequest request) {super(request);}/** * 获得被装饰对象的引用和采用的字符编码 * @param request * @param charset */public GetHttpServletRequestWrapper(HttpServletRequest request,String charset) {super(request);this.charset = charset;}/** * 实际上就是调用被包装的请求对象的getParameter方法获得参数,然后再进行编码转换 */public String getParameter(String name) {String value = super.getParameter(name);value = value == null ? null : convert(value);return value;}public String convert(String target) {System.out.println("编码转换之前:" + target);try {return new String(target.trim().getBytes("ISO-8859-1"), charset);} catch (UnsupportedEncodingException e) {return target;}}}
修改过滤器的doFilter方法 代码如下:
- 通过HttpServletRequestWrapper(装饰模式的应用)增强HttpServletRequest的功能
- 通过HttpServletRequestWrapper(装饰模式的应用)增强HttpServletRequest的功能解决乱码
- 通过HttpServletRequestWrapper(装饰模式的应用)增强HttpServletRequest的功能
- 【HttpServletRequestWrapper的增强】
- 利用装饰者模式通过层层封装以达到动态增强类的功能。
- 装饰者模式对HttpServletRequest进行增强
- 装饰模式的应用
- 装饰模式的应用
- 装饰者模式的应用
- Java 装饰模式的应用
- 通过自建代理服务器增强 Applet 的功能
- HttpServletRequest的应用
- HttpServletRequest的应用
- HttpServletRequest的应用
- HttpServletRequest的应用
- (补)HttpServletRequest的应用 .
- HttpServletRequest的应用
- HttpServletRequest的应用
- 求21位水仙花数算法(C++实现)
- Remove Duplicates from Sorted Array
- SVN添加文件时的错误处理:...\conf\svnserve.conf:12: Option expected
- DIJKSTRA
- DIJKSTRA堆优化
- 通过HttpServletRequestWrapper(装饰模式的应用)增强HttpServletRequest的功能
- C#可以写驱动程序吗?
- android的异步加载与UI
- Java正则表达式识别中文
- Fitnesse使用
- 执行SQL
- DOM案例-----实现多附件上传
- 深入浅出学习struts1框架(四):从MVC模式代码认识struts1框架
- 腾讯php程序员面试题