项目中遇到一个情况,就是Tomcat下中文乱码的问题,最开始解决的时候用的是过滤器加修改%tomcat%\conf\server.xml的方式,以便应对Get和Post两种情况下提交表单都不会出现乱码,但是对于系统中使用的某些平台(诸如工作流引擎等),在将URIEncoding="GB2312"加入到server.xml中的Connector配置中之后就不能正常工作了。看来最好是不要改动服务器的配置才好,于是在自定义的过滤器中我分别对Post请求和Get请求做了不同的处理,如果是Post请求则直接调用request.setCharacterEncoding("GBK"),否则如果是Get请求的话需要对Request进行包装才可以解决乱码的问题。
如下是定制过滤器的完整源代码:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang.StringUtils;
/**
* 此过滤器是为了解决Tomcat在处理Get和Post不同请求时的中文乱码问题而定制的
* @author leisure
*/
public class TomcatCharsetEncodingFilter implements Filter{
private String charsetEncoding="GBK";
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest=(HttpServletRequest)request;
String method=httpRequest.getMethod();
if("POST".equalsIgnoreCase(method)){
httpRequest.setCharacterEncoding(charsetEncoding);
}else{
httpRequest=new CharsetEncodingFixedRequest(httpRequest);
}
chain.doFilter(httpRequest, response);
}
public void init(FilterConfig config) throws ServletException {
String charset=config.getInitParameter("charsetEncoding");
if(StringUtils.isNotBlank(charset)){
this.charsetEncoding=charset;
}
}
class CharsetEncodingFixedRequest extends HttpServletRequestWrapper{
private String fixedCharset="iso8859-1";
private Map paramMap=new HashMap();
public CharsetEncodingFixedRequest(HttpServletRequest request) {
super(request);
try {
super.setCharacterEncoding(fixedCharset);
Enumeration nameEnum=request.getParameterNames();
while(nameEnum.hasMoreElements()){
String paramName=(String)nameEnum.nextElement();
String[] values=request.getParameterValues(paramName);
if(values.length>0){
List valueList=new ArrayList();
for(int i=0;i<values.length;i++){
String value=values[i];
valueList.add(encode(request.getCharacterEncoding(),value));
}
paramMap.put(paramName, valueList.toArray(new String[valueList.size()]));
}
}
System.out.println();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public String getParameter(String name) {
String[] values=getParameterValues(name);
if(values!=null && values.length>0) return values[0];
else return null;
}
public String[] getParameterValues(String name) {
return (String[])paramMap.get(name);
}
public Map getParameterMap() {
return this.paramMap;
}
public Enumeration getParameterNames() {
final Iterator it=paramMap.keySet().iterator();
return new Enumeration(){
public boolean hasMoreElements() {
return it.hasNext();
}
public Object nextElement() {
return it.next();
}
};
}
//
private String encode(String oldCharset,String src){
if(StringUtils.isBlank(src)) return src;
if(StringUtils.isBlank(oldCharset)){
oldCharset=this.fixedCharset;
}
try {
return new String(src.getBytes(oldCharset),charsetEncoding);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return src;
}
}
}
}
其中在自定义的请求包装类中对请求参数做了一个缓存处理,即后续对getParameter(String paramName)以及其它与请求参数有关的调用不会再对包装的请求进行调用,这主要是为了从根本上保证自定义的请求包装类CharsetEncodingFixedRequest能全权负责与请求参数相关的编码工作。否则在遇到需要对请求进行转发的情况(典型的是在struts的Action类中调用mapping.findForward(String forwardName))时要转发到的目标组件在获取请求参数时依旧会出现乱码,这主要是与tomcat在处理转发时需要对请求重新进行包装以及解包装有关系,如果对这一过程有特别的兴趣可以看看org.apache.catalina.core.ApplicationDispatcher的源码,就会明白此中奥妙了。
相比起修改服务器配置文件的方案来说,配置过滤器更加灵活,可以控制对某些URL进行过滤而对某些则不进行过滤,但是如果是修改了
%tomcat%\conf\server.xml的话,tomcat会对所有的请求都进行指定字符集的编码,这在某些情况下是非常有害的,毕竟ISO8859-1是国际的标准。
分享到:
相关推荐
TOMCAT在默认情况下下载.rar的文件是把文件当作text打开,以至于IE打开RAR文件为乱码,如果遇到这种情况时不必认为是浏览器的问题,大多数浏览器应该不会死皮赖脸地把二进制文件当作文本打开,一般都是服务器给什么...
开发环境 eclipse java EE 4.5.0,jdk 1.7,Tomcat 7.0,Quercus 4.0.39 由Eclipse-jee生成的Dymanic Web...php调用java时遇到中文乱码问题,在DEMO中也有提出我的解决方案,如果有更好的解决方案也请大家不吝惜指教。
服务器等软件的配制 Jsp中文乱码解决方案 上传与下载 Hibernate 参数设置.txt MD5_Encoding.java Struts2中三种表达式符号的用法.txt
1.3 Tomcat服务器的下载,安装和运行(可选) 26 1.4 JBoss 服务器的下载,安装和运行(可选) 28 1.5 MySQL 5数据库服务器下载,安装和运行(可选) 31 1.5.1 MySQL 5 官方版本的下载和安装,运行 32 1.5.2 MySQL 5...
全书一共被压缩为5个rar,这是第二个!...21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化与本地化 621 21.5.1 locale 621.. 21.5.2 资源包 623 ...
全书一共被压缩为5个rar,这是第五个!...21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化与本地化 621 21.5.1 locale 621.. 21.5.2 资源包 623 ...
全书一共被压缩为5个rar,这是第四个!...21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化与本地化 621 21.5.1 locale 621.. 21.5.2 资源包 623 ...
全书一共被压缩为5个rar,这是第三个!...21.2 中文乱码问题的解决方案 614 21.3 使用过滤器解决中文问题 616 21.4 让tomcat支持中文文件名 620 21.5 国际化与本地化 621 21.5.1 locale 621.. 21.5.2 资源包 623 ...
常见问题 读取Properties文件出现中文乱码 182 第9章 Java异常处理与反射机制 183 实例73 运用throws、throw、try与catch 183 实例74 throws声明异常的实例 185 实例75 自定义异常类 187 实例76 使用finally...