日期:2014-05-17  浏览次数:20657 次

抓狂高分请教经典难题!struts2中action的type为redirect跳转时中文传参乱码问题!
项目使用的编码统一为UTF-8,服务器为tomcat6。凡是所有能想到配置字符编码的地方全部全都用上了
jsp页面、过滤器、struts2的i18n常量配置、tomcat6的server.xml配置文件等等....
现在页面提交不论是get还是post方式在接收的Action中都能得到正确的中文参数。
现在的问题是,如果这个action需要将这个参数传递到下一个action处理,且跳转时的类型不为jsp或chain,而是redirect时。如:/**/toaction?username=${param},下一个action得到的中文参数就是乱码。经过分析原来是redirect跳转时url被"ISO-8859-1"重新编码了,所以到了下一个action成了乱码。
但是能配用UTF-8编码的地方都已经配好了,为什么跳转时还要用"ISO-8859-1"编码?(java固定?不可更改?)
经过网上搜寻解决方案,都没有好的主意,最直接的解决方案就是自己用
Java code
new String(queryString.getBytes("ISO-8859-1"), "UTF-8")

重新编码,但这个方法实在不优雅,很难维护!
网上说有用过滤器的,但没用,因为action传参不知道要传几次,不知道什么时候该使用
new String(queryString.getBytes("ISO-8859-1"), "UTF-8")编码。
这个问题困扰了很久,暂时用new String(queryString.getBytes("ISO-8859-1"), "UTF-8")这个方式在程序里硬编码解决了,希望能有一个通用的解决方案。
有一个思路,但觉得无法实现:
即在拦截器中(即过去的filter)中判断参数是否为ISO-8859-1编码,如果为ISO-8859-1编码表示java(或者struts2)已经做了转码,此时再用new String(queryString.getBytes("ISO-8859-1"), "UTF-8")给转回去。
这样所有的action得到的参数都保证是UTF-8编码了,不过猜测参数的编码格式是否无法实现,这里仅做抛砖引玉,希望能有高手解决!谢谢!

------解决方案--------------------
我通常的做法是,不管是传递什么参数,自己都是写个小方法先加密然后作为参数,然后再接受端转化就行了。
比如统一转化成base64。
------解决方案--------------------
为何不用过滤器?本人认为只要在redirect时,加上一个特定的参数,就可以判断并作相应的处理了。如果传很多次,那么在过滤器处理后,移除特定的参数就可以了。
------解决方案--------------------
我的做法是,带参数传都不传中文参数,如果一定要用中文参数,都用隐藏表单传。中文参数本身就存在编码问题,所以如果要传中文参数,我认为设计或者编码上来说,可以说是个缺陷,或者设计的理念不对。
------解决方案--------------------
Redirect Action Result

This result uses the ActionMapper provided by the ActionMapperFactory to redirect the browser to a URL that invokes the specified action and (optional) namespace. This is better than the ServletRedirectResult because it does not require you to encode the URL patterns processed by the ActionMapper in to your struts.xml configuration files. This means you can change your URL patterns at any point and your application will still work. It is strongly recommended that if you are redirecting to another action, you use this result rather than the standard redirect result.


Redirect Result

Calls the {@link HttpServletResponse#sendRedirect(String) sendRedirect} method to the location specified. The response is told to redirect the browser to the specified location (a new request from the client). The consequence of doing this means that the action (action instance, action errors, field errors, etc) that was just executed is lost and no longer available. This is because actions are built on a single-thread model. The only way to pass data is through the session or with web parameters (url?name=value) which can be OGNL expressions.

自己看吧,我英文也不咋地,别误导了大家,哈哈!
------解决方案--------------------
在 URL 地址栏中传递的参数都必须得经过 URL 编码!否则乱码问题自负。

URL 编码方法:

1:JavaScript 的 encodeURI 方法
2:Java 的 java.net.URLEncoder.encode 方法
3:JSTL 的 c:url 和 c:param 合用