返回信息流在做一个简单的网站。
使用Tomcat + Servlet + FreeMarker。其中FreeMarker可以想象成增强版的String.format("%s",xxx)。
问题在于,Servlet的request和response的默认字符集(CharacterEncoding)都是ISO-8859-1。因此,如果从request.getParameter读东西,或者往response.getWriter()里写东西,如果有中文,都不能正常表现。FreeMarker只会往我传给它Writer对象里写String,不管字符集,所以应该不是它的问题。
暂时的解决方法是:手动给每个servlet中的request和response加上request.setCharacterEncoding("utf8");和response的类似方法,这样中文就正常了。
但是,觉得这么解决不彻底。
1. 怎么要求客户端(浏览器)发送form的时候也以utf8编码?我强制request.setCharacterEncoding("utf8"),万一人家不是utf8呢。。。
2. 有没有办法适应用户的浏览器指定的字符集呢?(HTTP头有这种信息吗?)
3. 有没有直接一次适用整个应用程序的配置方法呢?(比如web.xml?这里能设置吗?服务器的配置文件呢?找了半天没找到。)
4. 用filter,怎么样?是正确的用法吗还是误用?
这是一条镜像帖。来源:北邮人论坛 / java / #13202同步于 2010/2/3
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
Servlet和字符集
wks
2010/2/3镜像同步11 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
没错。
我用setCharacterEncoding和setContentType都设置成了utf8。所以响应方面已经解决了。
请求方面怎么办呢?浏览器会自动把请求中form的编码变成和form所在的页面的编码一样吗?
【 在 greedisgood 的大作中提到: 】
: 话说客户看到的页面不是你响应的吗?人家是不是utf8你不知道吗?注意客户端编码是你指定的。
是的
【 在 wks (cloverprince) 的大作中提到: 】
: 没错。
: 我用setCharacterEncoding和setContentType都设置成了utf8。所以响应方面已经解决了。
: 请求方面怎么办呢?浏览器会自动把请求中form的编码变成和form所在的页面的编码一样吗?
: ...................
最quick&dirty的方法:一个filter搞定/*的所有页面。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
据说会加重服务器负担,比如会给静态页面和图片什么的也加上filter,不过反正是实验性项目,就这样吧。
客户浏览器的编码格式是你指定的。所以当然“浏览器会自动把请求中form的编码变成和form所在的页面的编码” 。
request.setCharacterEncoding 和response.setCharacterEncoding是最终方法,所以“据说会加重服务器负担”是不可理解的,因为就算像你所说写在配置文件里或使用其他工具类,本质上都调用了这两个方法。
测试了一下。读出一个带form,浏览器会自动设置成http-equiv/content-type里面指定的字符集。
然后,我把浏览器上改个字符集,然后填表,submit。服务器上就收到我在浏览器上指定的字符集了(当然,是乱码,不过是用户自找麻烦……不是服务器的错)。
字符都是转义过的。这是Firefox分别用gb18030和utf-8发的post,HTTP Request头里没有说明request中的字符集,只有Accept-Charset。所以肯定是假定用户按我指定的charset来发送了,不能适应用户了。
[wks@localhost junk4]$ nc -l 9999
POST / HTTP/1.1
Host: localhost:9999
User-Agent: Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.6) Gecko/20100107 Fedora/3.5.6-1.fc12 Firefox/3.5.6
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: sessionid=e4e095d09ed9917d1c80d5077371e4de
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
key=%D6%D0%CE%C4
[wks@localhost junk4]$ nc -l 9999
POST / HTTP/1.1
Host: localhost:9999
User-Agent: Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.6) Gecko/20100107 Fedora/3.5.6-1.fc12 Firefox/3.5.6
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: sessionid=e4e095d09ed9917d1c80d5077371e4de
Content-Type: application/x-www-form-urlencoded
Content-Length: 23
key=%E4%B8%AD%E6%96%87^C
【 在 greedisgood 的大作中提到: 】
: 客户浏览器的编码格式是你指定的。所以当然“浏览器会自动把请求中form的编码变成和form所在的页面的编码” 。
: request.setCharacterEncoding 和response.setCharacterEncoding是最终方法,所以“据说会加重服务器负担”是不可理解的,因为就算像你所说写在配置文件里或使用其他工具类,本质上都调用了这两个方法。
Spring框架里面居然有这个:
<!-- Reads request input using UTF-8 encoding -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
晕死。。。