主要是基于这么一个思路解决我的问题:
<meta http-equiv="Content-Type" content="text/html; charset=gbk"/>
...
<form method="post" action="/servlet" accept-charset="utf-8">
<input type="hidden" name="_charset_"/>
<input type="text" name="text"/>
<input type="submit" value="Submit"/>
</form>
这个表单配合原来在weblogic下写的filter代码,在IE和firefox下运行正常。但既然遵循servlet规范,不能在filter中通过_charset_这个request参数来获取浏览器对post body的真实编码,只能想点歪门邪道了。向jsessionid取经,这个表单改成这样:(关于URL中的分号,请参考RFC1738,这里有个中文版)
<meta http-equiv="Content-Type" content="text/html; charset=gbk"/>
...
<form method="post" action="/servlet;_charset_=utf-8" accept-charset="utf-8">
<input type="hidden" name="_charset_"/>
<input type="text" name="text"/>
<input type="submit" value="Submit"/>
</form>
filter的改造就略了,无非是hack下request uri。幸好遗留应用并不需要url中重写jsessionid。
测试,运行,firefox正常了,IE又不正常。哦,恍然大雾啊,原来firefox是严格的根据accept-charset来编码,若accept-charset不存在,则按response或者meta http-equiv="Content-Type"中的声明来编码,最后把编码方式放到_charset_隐藏域。而IE还是顽固的只按照response或者meta http-equiv="Content-Type"中的声明来编码,并把编码方式放到_charset_隐藏域。原来IE无视accept-charset的存在。我原先一直以为_charset_隐藏域只是IE对accept-charset的一个强制辅助呢,又一个一知半解的典型...
得了,只能让firefox和IE同流合污了。最终,表单变成这样:
<meta http-equiv="Content-Type" content="text/html; charset=gbk"/>
...
<form method="post" action="/servlet;_charset_=gbk">
<input type="text" name="text"/>
<input type="submit" value="Submit"/>
</form>
在IE和firefox下均测试通过。