Scripts 学盟
标题:
关于 Tomcat 上的应用中使用 GET 方式提交参数的那些事
[打印本页]
作者:
Alvin
时间:
2011-5-5 16:50:02
标题:
关于 Tomcat 上的应用中使用 GET 方式提交参数的那些事
我们都知道,在 Tomcat 默认的配置情况下, 使用 request.setCharacterEncoding 对于使用 GET 方式提交的参数是无效的。
这个问题可以说是困扰哦。。。
好多人好多时候,明明加了请求过滤器,给 request.setCharacterEncoding 设置上一千遍。。。
request.getParameter(...) 还是得到一堆看不懂的符号。
如何是好哇....
呵呵,偷偷告诉你,
可以打开 %TOMCAT_HOME%\conf\server.xml
在 HTTP 连接器的配置节点中,加入一个属性 URIEncoding="UTF-8"
<Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"
URIEncoding="UTF-8"
/>
当然了。。。如果你的项目中不是应用 UTF-8 编码格式来传递请求数据的,就不要写上 "UTF-8" 啦。。。写 gbk, big5 .... 你懂的啦。
再看一下,是不是大功告破,问题解决了呢。
一般情况下,这么也就把问题给解决了哈。。。
但是有些人有时候,还是又郁闷了一把啊。。。他的 Tomcat 里要布署多个应用啊,有些是应用 UTF-8, 有些是 GBK, 还有些是韩文,日文,徳文,法文。。。什么什么文的一大堆啊
使用了各种不同的各地区语言专用编码啊。。。
写上 URIEncoding="UTF-8", GBK 项目挂了啊
写上 URIEncoding="GBK", UTF-8 项目挂了啊
。。。
伤得起么,伤得起么
呵呵,再偷偷告诉你,
再打开 %TOMCAT_HOME%\conf\server.xml
在 HTTP 连接器的配置节点中,不写 URIEncoding="xxx" 了啊,写 useBodyEncodingForURI="true" 啊
<Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"
useBodyEncodingForURI="true"
/>
马上测试一下哈。。。
request.setCharacterEncoding(xxx) 是不是对 GET 方式提交的参数也起作用了哈
对于,绝大部分的人来说,这是非常不错的解决办法了呀
可是,还有那么很小一部分人 ,还是在郁闷呐。。。
他购买了虚拟主机啊,服务器不是自个完全控制啊。。。 tomcat 的配置没法改啊。。。
什么 URIEncoding...
什么 useBodyEncodingForURI...
都是浮云啊
这没法活了呀。。。
难道回去修改代码,把所有接收 GET 提交的参数的地方都加上
parameterValue = new String(parameterValue.getBytes("iso-8859-1"), xxxx);
唉。。。改吧。。。
呵呵,最后再偷偷告诉你
这里有个过滤器,用下面的过滤器过滤请求
不配置 URIEncoding, useBodyEncodingForURI 都可以修正 request.setCharacterEncoding(...) 对 GET 方式提交的参数无效的问题
过滤器代码如下:
package org.iscripts.common.web;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* @author 林俊海(ialvin.cn) 广东·普宁·里湖
*/
public class FixedEncodingForURI implements Filter {
public void doFilter(ServletRequest req, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
request = new RequestWrapper(request);
chain.doFilter( request, response );
}
public void destroy() { }
public void init(FilterConfig filterConfig) throws ServletException { }
}
class RequestWrapper extends HttpServletRequestWrapper {
private String characterEncoding = null;
private Map<String, String[]> parameterMap = null;
public RequestWrapper(HttpServletRequest request) {
super(request);
this.characterEncoding = request.getCharacterEncoding();
}
@Override
public String getParameter(String name) {
String[] values = this.getParameterValues(name);
if (values.length < 1) return "";
return values[0];
}
@Override
public String[] getParameterValues(String name) {
String[] values = this.getParameterMap().get(name);
return values == null ? new String[0] : values;
}
@Override
public Enumeration<String> getParameterNames() {
return new Enumeration_<String>( this.getParameterMap().keySet().iterator() );
}
@Override
@SuppressWarnings("unchecked")
public Map<String, String[]> getParameterMap() {
if (parameterMap != null) return parameterMap;
parameterMap = new HashMap<String, String[]>();
try {
super.setCharacterEncoding("iso-8859-1");
Map<String, String[]> map = super.getParameterMap();
super.setCharacterEncoding(characterEncoding);
if (map == null) return parameterMap;
for (String key : map.keySet()) {
String[] values = map.get(key);
key = RequestWrapper.reDecode(key, this.getCharacterEncoding());
values = RequestWrapper.reDecode(values, this.getCharacterEncoding());
parameterMap.put(key, values);
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return parameterMap;
}
@Override
public String getCharacterEncoding() {
return characterEncoding;
}
@Override
public void setCharacterEncoding(String characterEncoding) {
this.characterEncoding = characterEncoding;
}
// ---------- private ----------
private static String[] reDecode(String[] strs, String charset) {
if (strs == null) return new String[0];
String[] values = new String[strs.length];
for (int i=0, length=strs.length; i<length; i++)
values[i] = RequestWrapper.reDecode(strs[i], charset);
return values;
}
private static String reDecode(String str, String charset) {
if (str == null) return "";
if ("iso-8859-1".equalsIgnoreCase(charset)) return str;
try {
return new String(str.getBytes("iso-8859-1"), charset);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
class Enumeration_<E> implements Enumeration<E> {
private Iterator<E> iterator = null;
Enumeration_(Iterator<E> iterator) {
this.iterator = iterator;
}
public boolean hasMoreElements() {
return iterator.hasNext();
}
public E nextElement() {
return iterator.next();
}
}
复制代码
原理很简单,request 来到这个过滤器中,会被包装了一下
request.getParameter
request.getParameterValues
request.getParameterNames
request.getParameterMap
这四个方法会被重写。 所以后面就.... 大家懂的啦.
不过,注意哦,使用这个过滤器后仍然需要 request.setCharacterEncoding
也就是说,它只是修正在 tomcat 服务中 request.setCharacterEncoding 对 GET 方式提交的参数无效的问题.
如果你使用另一个过滤器 B 来完成 request.setCharacterEncoding 的工作,那么这个过滤器在过滤器链的次序中,必须在 B 的前面。
---------------------------
哈哈,这下可以了吧,如果你能配置 tomcat , 那么,你可以配置下 useBodyEncodingForURI="true"
如果你没有权限去配置 tomcat,那么,在应用中加上这个过滤器
当然,为了增加应用发布后的兼容性,并且降低配置来配置去的麻烦,可以统一就加上这个过滤器,哈哈。。。。
--------------------------
附:这里还有个视频,关于提交参数的编码问题
http://www.iscripts.org/bbs/viewthread.php?tid=98
作者:
Yisin
时间:
2011-5-7 21:17:42
不会Java
作者:
那个谁
时间:
2011-5-12 16:36:08
表示什么乱码都是浮云的。路过。。。
作者:
Alvin
时间:
2011-5-15 04:35:41
浮云
欢迎光临 Scripts 学盟 (http://www.iscripts.org/)
Powered by Discuz! X2