项目使用的编码统一为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固定?不可更改?)
经过网上搜寻解决方案,都没有好的主意,最直接的解决方案就是自己用
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编码了,不过猜测参数的编码格式是否无法实现,这里仅做抛砖引玉,希望能有高手解决!谢谢!

解决方案 »

  1.   

    我通常的做法是,不管是传递什么参数,自己都是写个小方法先加密然后作为参数,然后再接受端转化就行了。
    比如统一转化成base64。
      

  2.   

    这个问题以前也困扰了我很久, 确实有此类问题.! 没有什么别的好办法, 
    暂时new String(queryString.getBytes("ISO-8859-1"), "UTF-8")就这么搞吧.!
    struts2本身就是个不稳定因素, 我很撞上几个bug,不知道这个问题是否是个bug还! - -!
      

  3.   

    tomcat server.xml 
    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8" />
      

  4.   

    LS的哥们, 你看下人家帖子开头说的, 能配的都给配了,包括server.xml
      

  5.   

    new String(queryString.getBytes("ISO-8859-1"), "UTF-8")
      

  6.   

    为何不用过滤器?本人认为只要在redirect时,加上一个特定的参数,就可以判断并作相应的处理了。如果传很多次,那么在过滤器处理后,移除特定的参数就可以了。
      

  7.   


    哦使用redirectAction好了!可以传中文,又不会乱码。@Result(name = "testRedirect1", type = "redirectAction", location = "workload!test2" , params = {"testChinese","${testChinese}"})我测试过了,没问题。
      

  8.   

    Redirect Action ResultThis 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 ResultCalls 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.自己看吧,我英文也不咋地,别误导了大家,哈哈!
      

  9.   

    像过滤器只能处理post方式提交的数据,
    而new String(queryString.getBytes("ISO-8859-1"), "UTF-8")是用来处理get方式提交的。
    所以你传值时要看是get还是post方式,如果是get只能加此行代码。
      

  10.   

    关注中
    ,new String(queryString.getBytes("ISO-8859-1"), "XXX")
    这个语句很讨厌!
    以前项目也碰到,也是全部UTF-8,但是偏偏要加这句!受不了!让人崩溃,最后还是没解决!
      

  11.   

    在 URL 地址栏中传递的参数都必须得经过 URL 编码!否则乱码问题自负。URL 编码方法:1:JavaScript 的 encodeURI 方法
    2:Java 的 java.net.URLEncoder.encode 方法
    3:JSTL 的 c:url 和 c:param 合用
      

  12.   

    认真看了一下大家的回复,加上后来自己对代码重新的分析。
    我觉得问题的关键在于不恰当的使用了redirect
    原因如下:
    redirect就是资源重定向,一般用于跳转到其它网站访问所用。如果访问的是内部网站资源,使用redirect就是一种下策,因为redirect无法将前一个请求的参数共享给下一个网站使用,比如request中的参数。当然可以用地址参数来传递,那么问题就来了,也是本贴的主题,就是中文参数乱码问题。因为资源重定向跳转要经过客户端浏览器的重新发送(可以试验一下,重定向发送的请求在浏览器地址栏里最终显示的是重定向后的请求地址,而chain则是第一个action的请求地址),其实这也就是servlet中sendRedirect和forward(include)的区别。中文乱码的原因也就在这里,因为经过浏览器跳转后编码就不受struts2管理了。
    注:为什么经过浏览器跳转编码就变了原因很复杂,因为本贴的跳转实际还是受原网站控制的,浏览器输出时不论本地默认编码为何已经强制被改为UTF-8,按理说跳转后浏览器重新申请时应该还是UTF-8编码,但不知为什么却变成了ISO-8859-1,这里期待高人给解释一下。
    多说一点,返回类型中还有一个redirectAction,书上的解释是重定向到一个新的action,请求参数全部丢失,action处理结果也全部丢失。按这个解释,redirectAction和chain的区别就是一个跳转时丢失参数,一个不丢失。这里就让人费解了,因为chain完全可以替代redirectAction嘛。我觉得这个redirectAction的作用是不是适用于不用传参或传递简单参数的情况,这样便于系统将前面action的资源尽快释放,做到资源充分利用?这里高手给解释一下。redirectAction会不会产生中文传参乱码我没有试验,不过楼上有朋友说没有问题,那就算可以吧。
    最后总结一下:
    1、凡是网站内部资源访问的就尽量不要用redirect,而是用chain和redirectAction,至少这样可以避免中文传参乱码。
    2、chain传参方法我就不说了,就是request、parameters,但能不用session就不要用session了。
    3、使用redirect传参时,如果带中文目前好像就只有用本贴开始所说的解决方案了。有些朋友所说的过滤器并不是和本贴说的一个问题,而是指struts2框架以前浏览器提交乱码问题。
    上面有些结论只是根据别人的说法下的定义,有误之处请朋友们指正。
      

  13.   

    这个问题我也遇到过,也就是浏览器总会将链接转换成ISO-8859-1编码,struts2等等框架通过设置,某些时候处理了中文乱码问题(也就是在先编码后解码),另附加一种情况,页面中的含有中文参数的链接有时也可能出现问题,单击页面没问题,但是将链接拷贝到浏览器后就会出现问题,等等这些都是编码不一致造成的。所以只要弄清楚了什么时候是什么编码就行了。
    就是有时有点郁闷,一不小心就是一个小bug
    最后建议:
    1、中文参数尽量少用get传,用post传,因为struts2内置post中文的处理,就不会出现楼主那样的问题了。
    2、页面编码统一,搞清楚任何位置的编码环境。
    3、redirect ,redirectAction、chain,我认为有点类似servert中的request.sendRedirect(URL)何request.forward(),include();
      

  14.   

    我也遇到了这个问题不知道LZ现在解决了没有,我暂时的解决办法是不传中文,redirect的时候穿字母或数字过去,然后接受那边判断一下就行了,比如:传过来的是1就提示操作成功,传过来的是2就提示操作失败临时的解决办法求大虾给终极方案
      

  15.   

    今天遇到同样问题,解决方法如下,希望对有此类问题的同仁一些帮助。struts.xml<action name="aaction" class="com.soft.web.AAction.class">
       <result name="afterOnView">/pages/aa/aa_view.jsp</result>
       <result name="afterOnSave" type="redirect">
          <param name="location">/aaction!onView.action?am.name=${am.name}</param>
          <param name="encode">true</param>
       </result>
    </action>代码不再一行一行敲出来了,操作流程:编辑(添加)完Am对象,跳转到Am视图页面。
    在AAction里边的onView方法中,用名字取到Am对象。
      

  16.   

    <result name="xx" type="redirect">
      <param name="location">/xxxx.jsp</param>
      <param name="parameter">${parameter}</param>
    </result>
    用这种方式就可以传递中文参数了
      

  17.   

    36楼是牛B  呵呵   
    <result name="xx" type="redirect">
      <param name="location">/xxxx.jsp</param>
      <param name="parameter">${parameter}</param>
    </result>
      

  18.   

    今天也遇到这么邪恶的问题了! 使用redirectAction果断华丽丽的变成乱码了!
    兄弟那个恨啊!找了半天资料。最后改成 chain 果断的好了!
    带参数action传递方便啊
      

  19.   

    唉,似乎过滤器只能解决post方式的编码方式,如果是get方式的话,就有点麻烦了!!!
      

  20.   

    1、我最后还是从 redirectAction 换成了 chain ,目前虽然我还不明白 这个 chain 是什么,但是成功了。2、redirect 和 redirectAction 我以为只是写法不一样,没想到还扯到了 post get ,太让我收获啦,感谢,膜拜呀,各位。3、24楼,您分析得太对了,不论是复制过来的还是你自己评论的,太精彩了。4、等哈有空再回来看,深刻体会哈你们说叻,这会儿回去吃饭饭咯。
      

  21.   

    且说 我也是server.xml 和context、过滤器、各种转换 、反正能涉及到编码机问题的我都试过、
    因为使用了rediect 且action跳action传递了中文、(本来不可以传递中文的、自己也很避讳传递中文、没有办法、需要动态返回信息)、最后还是搜索到楼主的问题分享、
    无论是使用chain还是34楼、36楼的方法都可以、
      

  22.   

    这种方法可行,非常好使!<result name="input" type="redirect">
      <param name="location">/homepage.ic?loginError=${loginErro r}</param>
      <param name="encode">true</param>
    </result>
      

  23.   

    这种方法可行,非常好使!<result name="input" type="redirect">
      <param name="location">/homepage.ic?loginError=${loginErro r}</param>
      <param name="encode">true</param>
    </result>