应用一:解决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中过滤器配置:
-
-
<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>
<!--将采用的字符编码配置成应用初始化参数而不是过滤器私有的初始化参数是因为在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"
- />
<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);
- }
-
-
-
-
-
-
-
public GetHttpServletRequestWrapper(HttpServletRequest request,
- String charset) {
-
super(request);
-
this.charset = charset;
- }
-
-
-
-
-
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;
- }
- }
-
- }
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方法 代码如下:
- public void doFilter(ServletRequest request, ServletResponse response,
-
FilterChain chain) throws IOException, ServletException {
-
- request.setCharacterEncoding(charset);
- response.setCharacterEncoding(charset);
-
- HttpServletRequest req = (HttpServletRequest)request;
-
-
if(req.getMethod().equalsIgnoreCase("get"))
- {
-
req = new GetHttpServletRequestWrapper(req,charset);
- }
-
-
System.out.println("----请求被"+config.getFilterName()+"过滤");
-
- chain.doFilter(req, response);
-
-
System.out.println("----响应被"+config.getFilterName()+"过滤");
-
- }
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//设置请求响应字符编码
request.setCharacterEncoding(charset);
response.setCharacterEncoding(charset);
//新增加的代码
HttpServletRequest req = (HttpServletRequest)request;
if(req.getMethod().equalsIgnoreCase("get"))
{
req = new GetHttpServletRequestWrapper(req,charset);
}
System.out.println("----请求被"+config.getFilterName()+"过滤");
//传递给目标servlet或jsp的实际上时包装器对象的引用,而不是原始的HttpServletRequest对象
chain.doFilter(req, response);
System.out.println("----响应被"+config.getFilterName()+"过滤");
}
这样一来,在servlet中调用包装器的getParameters方法来获取参数,就已经完成了字符编码的转换过程,我们就不需要在每次获取参数时来进行字符编码转换了。
分享到:
相关推荐
JAVA Web 中文乱码问题
解决Java_Web开发中Jsp存储读取MySQL数据中文乱码的问题
解决在javaweb开发的过程中遇到的乱码问题,纯属个人在学习中的总结。
Java WEB开发中的中文乱码问题解决方法.pdf
在利用Servlet/JSP技术开发java Web应用程序的时候,不可避免的会遇到中文乱码问题,本文首先介绍了Web应用中常用的编码方式,然后分析了J2EE平台下Web应用中文乱码问题产生的原因,并在此基础上针对不同情况提出了解决...
从编码角度分析了java编译后在控制台和web等终端显示乱码问题。
这里总结了我在j2ee开发过程中,中文乱码的解决方案。希望能够帮到大家!
关于Java Web中中文乱码问题的探讨.pdf
Java Web中文显示乱码问题的分析与解决方案
在java Web应用开发常见的问题中,中文的乱码问题在页面中没有统一的方法解决,造成程序员浪费大量的时间与精力且代码效率不高,因此提出了新的乱码算法,并设计了通用的乱码处理器,提高了程序员的工作效率.
很好用,很全面的解决java Web开发的解决中文乱码的文档
简单可靠的filter源码和详细配置,轻松解决web中文乱码问题,web开发者必备神器你值得拥有!
解决web项目中出现的乱码问题,很方便,只要一个java文件,同时在web.xml文件中配置该java文件就OK了 ,很方便的
Java Web项目开发中的中文乱码问题与对策.pdf
Java Web程序开发中字符乱码的原因与解决办法.pdf
Java Web开发中的乱码问题.pdf
java处理中文乱码的三中方法 1.类字符转换 2.struts配置文件处理 3.web.xml配置文件处理
Jsp输出中文的乱码问题,获取表单提交的数据时的中文乱码问题,url中的中文问题,数据库中采取的编码方式不同于utf-8怎么办
介绍解决java web 开发解决中文乱码问题的一般方法
关于Java Web技术开发中中文乱码问题的深入探讨