struts2解决中文乱码

    技术2022-05-20  70

    原文传送门:http://blog.163.com/lotnhiro/blog/static/1379593712010712103928662/

     

    终于在自己的项目中引入struts2了,但一上来就来一个中文乱码的问题。google了半天找了几个不痛不痒的结果,很是不满意。又调试了半天,终于 解决了中文乱码的问题。总结一下,中文乱码,首先要区分是页面乱码、action乱码,还是数据库乱码。大致的原理是java使用unicode编码-- >window使用gbk(gb2312的扩展集)--mysql默认使用utf-8(unicode的一种编码方法),这样转来转去就乱码了 ^_^。解决方法如下:    1. 在struts2里面,最好将所有字符都设成utf-8。     <%@ page contentType="text/html;  charset=UTF-8"%>  <%@ page pageEncoding="UTF-8" %>    1.1 在jsp页面设定字符编码。这边有必有说明的是如果是jsp+java bean+servlet的方案,中文乱码很好解决,统一设成gb2312就可以了。    1.2 使用struts框架字符集不能设成gb2312,要改成utf-8。   2. 在struts.properties 添加:     struts.devMode=false  struts.enable.DynamicMethodInvocation=true  struts.i18n.reload=true  struts.ui.theme=simple  struts.locale=zh_CN  struts.i18n.encoding=UTF-8  struts.serve.static.browserCache=false  struts.url.includeParams=none   其中locale、encoding就是字符集的设定了。   3. 在web.xml加个filter       <!-- zh-cn encoding -->      <filter>           <filter-name>struts-cleanup</filter-name>          <filter-class>               org.apache.struts2.dispatcher.ActionContextCleanUp          </filter-class>      </filter>        <filter-mapping>           <filter-name>struts-cleanup</filter-name>           <url-pattern>/*</url-pattern>      </filter-mapping>        跟上述方法,类似还有在action中设定字符编符.          HttpServletResponse response = null;     response = ServletActionContext.getResponse();     request.setCharacterEncoding("utf-8");     response.setContentType("text/html;charset=utf-8");           通过上述方法,基本就可以搞定中文乱码的问题了。当然,也有例外(如web server的版本/数据库的版本等等)。象在我的一个项目碰到一个中文乱码,tomcate5.5是会乱码的,而在tomcate6中就不会。这边就涉 及到tomcate connector字符的设置了。         <Connector port="80"  maxHttpHeaderSize="8192"                  maxThreads="150" minSpareThreads="25"  maxSpareThreads="75"                  enableLookups="false" redirectPort="8443" acceptCount="100"                  connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK"   />    --------------------------------------------------------------------  后记之一:在使用struts2时,仍是遇到一种乱码。后来调试才发现,struts2的web.xml配置是有顺序的。   在web.xml中EncodingFilter的位置应该在Struts2的FilterDispatcher之前,因为要先调整字符集,然后进入Action。  按照Struts2的API,filter的顺序是struts-cleanup filterSiteMesh filterFilterDispatcher--------------------------------------------------------------------   后记之二:这个方法是下下策了,只有在前面的方法都无效时才使用。在action中直接使用request.getParameter()时;还是出现乱码。原因分析如下:   1、getParameter()是有带字符参数的。例:String s = (String)request.getParameter("txt").getBytes("iso-8859-1");   2、String也可以带有字符参数。String(byte[] bytes,String charsetName) 构造一个新的 String,方法是使用指定的字符集解码指定的字节数组。例:String s = new String("中文","utf-8");   3、综合上述两点,编写一个类来完成此项任务        public class ConvertCharacter{          public String Convert(String  s){               String result;               byte[] temp ;              try{                   temp = s.getBytes("iso-8859-1");                   result =  new String(temp,"utf-8");              }               return result;          }     }     在网上搜了很多资料都没有搞定,一般都有以下几种说法: 方法1:在后台中先获得字符串的iso-8859-1编码形式数组,再使用此数组实例一个UTF-8编码形式String类型字符串. 页面提交的url为: leavesp?work=部门主管审批 后台处理: String inStr=request.getParameter("work"); String outStr = newString(inStr.getBytes("iso-8859-1"),"UTF-8"); 方法2:在页面传递过来时先通过JavaScript将URL编码,再到后台进行解码: 页面部分: <scripttype="text/javascript">function dogetMethod(url){       //url编码前: leavesp?work=部门主管审批url=encodeURI(url);  //url编码后:leavesp?work=部门主管审批window.open(uri,’’,’’);}</script> 后台部分:(解码) String inStr=request.getParameter("work "); StringoutStr=java.net.URLDecoder.decode(inStr); 尝试过两种方法后好像都不行,在后台获取到的字符还是会乱码.试完之后真想哭.*o* 使用第一种方法后发现: 在请求(request)中获得的字符串是这样的: ²¿ÃÅÖ÷¹ÜÉóÅú 使用newString(inStr.getBytes("iso-8859-1"),"UTF-8");处理后字符成了: ??????????

    没法,只能再试第二种方法了,使用后发现: 在页面中使用encodeURI(url)后,字符串是这样的: 部门主管审批 好像有希望了!!!! 应该只要在后台再来decoder一下就行了吧,偶是这样想的,也是这样做的: 在后台中:       String inStr= request.getParameter("work "); outStr=java.net.URLDecoder.decode(inStr); 在请求中获得的字符串是这样的: 部门主管审批 decoder处理后得出的字符串为: 部门主管审批

    这时候真想哭啊!!%#$%@@!@$$##

    革命尚未成功,还需努力!!!

    从第二种方法中发现: 在请求中获得的字符串已经乱码了,用decoder处不处理值都是一个样!! 明明我在页面传过来的值是已经encode过了的字符,而后来取出来却….,这是为什么呢?

    难倒是页面编码设置得有问题? 看了一下页面编码是: pageEncoding="UTF-8" 改了!改成: pageEncoding="iso-8859-1"试试. 浏览页面上,发现页面上的中文变成了很多鿉之类的字符,不管了,再试下,还是一样的结果.涛声依旧! 

    忽然想到应该是在获得字符串之前,也就是在request. getParameter("work ");这之前的某个地方已经将URL进行了decoder,并且将获得的字符用Iso-8859-1的编码方式存储过了. 所以在request中会得到这些类似于鿉之类的字符,这种字符应该就是中文的iso-8859-1的形式!! 有办法了,既然已经获得了iso-8859-1编码形式的中文,那就只要再使用第一种方法(先获得字符串的iso-8859-1数组,再将它实例成UTF-8的字符串)来进行处理不就OK了! 试过之后果然OK!!!  处理中文乱码代码实现部分: jsp页面: <%@ page language="java"pageEncoding="UTF-8"%>   <!DOCTYPE HTML PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN"> <html>  <head>    <script type="text/javascript">        //开启网页对话脚本        function openDialog(url,width,height)        {           varproperty="status:no;center:yes;resizable:yes;scroll:yes;dialogWidth:"+width+"px;dialogHeight:"+height+"px;";             var ret=window.showModalDialog(url,'modalDialogwin',property);                             if (ret == null || ret == "")           {return false;}           return true;        }

           //查看待办工作脚本        function showork(url)        {            //将url地址进行编码                             url=encodeURI(url);           //alert(url);           //调用openDialog方法开启网页对话框           openDialog(url,900,500)        }    </script>     <title>待办工作查看</title>    </head>      <body>  <!-- 部分代码略 -->    <table border="1" align="center">        <tr>           <td> <a href="#"οnclick="javascript:showork('leavesp?work=部门主管审批')">查看待办工作</a> </td>           </tr>                </table>    </body> </html>   页面部分就一个超连接,用来开启一个网页对话框,只是开启的这个对话框中请求的不是一个物理的页面,而是请求的一个servlet(leavesp),而且url中带有中文参数值(?work=部门主管审批)。   为了处理中文乱码部分能够在整个WEB系统中都能够使用到,所以将中文乱码处理写成了一个Filter(过滤器),并在web.xml中配置所有的请求都将经过这个Filter进行过滤。Filter部分的代码如下: 文件名:ProFilter.java package com.util.filters;   import java.io.IOException; importjava.io.UnsupportedEncodingException; import java.util.Enumeration;   import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse;   public class ProFilter implements Filter {        protected FilterConfig filterConfig;    /**     * 初始化     */    public void init(FilterConfig filterConfig) throws ServletException     {       this.filterConfig=filterConfig;     }    /**     * 将inStr转为UTF-8的编码形式     * @param inStr 输入字符串     * @return UTF-8的编码形式的字符串     * @throws UnsupportedEncodingException     */    private String toUTF(String inStr) throws UnsupportedEncodingException     {       String outStr = "";       if(inStr != null)       {           //outStr=java.net.URLDecoder.decode(inStr);//不用decode了,到这的时候就已经自动decode过了           //将字符串转为UTF-8编码形式           outStr = newString(inStr.getBytes("iso-8859-1"),"UTF-8");               }       return outStr;    }        /**     * 中文乱码过滤处理     */    public void doFilter(ServletRequest svlrequest, ServletResponsesvlresponse,           FilterChain chain) throws IOException, ServletException     {       //将Servlet请求与响应对象转换成HttpServlet请求与响应对象       HttpServletRequest request=(HttpServletRequest)svlrequest;       HttpServletResponse response=(HttpServletResponse)svlresponse;             //获得请求的方式(1.post or 2.get),根据不同请求方式进行不同处理       String method = request.getMethod();       //1.以post方式提交的请求,直接设置编码为UTF-8       if(method.equalsIgnoreCase("post"))       {           try           {              request.setCharacterEncoding("UTF-8");           } catch (UnsupportedEncodingException e)           {               e.printStackTrace();           }       }       //2.以get方式提交的请求       else       {           //取出客户提交的参数集           Enumeration<String> paramNames = request.getParameterNames();           //遍历参数集取出每个参数的名称及值           while(paramNames.hasMoreElements())           {               String name = paramNames.nextElement();//取出参数名称               String values[] =request.getParameterValues(name);//根据参数名称取出其值               //如果参数值集不为空               if(values != null)               {                   //如果参数值集中只有一个值                   if(values.length == 1)                   {                      try                      {                          //调用toUTF(values[0])函数,(values[0]即第一个参数值)方法转换参数值的字元编码                                                  Stringvlustr=toUTF(values[0]);                         //并将该值以属性的形式藏在request                         request.setAttribute(name, vlustr);                      } catch(UnsupportedEncodingException e)                      {                          e.printStackTrace();                      }                   }                   //如果参数值集中有多个值                   else                   {                      //遍历参数值集                      for(inti=0;i<values.length;i++)                      {                          try                          {                             //回圈依次将每个值调用toUTF(values)方法转换参数值的字元编码                             Stringvlustr=toUTF(values);                             values = vlustr;                          } catch(UnsupportedEncodingException e)                          {                            e.printStackTrace();                          }                      }                      //将该值以属性的形式藏在request                      request.setAttribute(name,values);                   }               }           }         }        //设置响应方式和支持中文的字元集       response.setContentType("text/html;charset=UTF-8");          //继续执行下一个filter,无一下个filter则执行请求       chain.doFilter(request, response);     }        /**     * 销毁方法     */    public void destroy()     {           } }   过滤器部分,可用来处理页面提交的post和get方法产生的中文乱码问题。 Post方式提交的数据(form表单中提交的数据)只需要进行请求字符编码设置request.setCharacterEncoding("UTF-8");和响应设置response.setContentType("text/html;charset=UTF-8");设置就可以了。 Get方式提交的数据会包含在url中,(如:leavesp?work=部门主管审批),则需要取出参数名:Enumeration<String> paramNames = request.getParameterNames();(如:work)和取出参数值:Stringvalues[] = request.getParameterValues(name);(如:部门主管审批),然后再将参数值进行编码转换:outStr = new String(inStr.getBytes("iso-8859-1"),"UTF-8");   过滤器写好这后就需要到web.xml中<web-app>与</web-app>之间进行配置了,web.xml中配置如下: <!-- 配置过滤器 -->    <filter>       <description>处理中文乱码过滤器</description>       <filter-name>ProFilter</filter-name>       <filter-class> com.util.filters.ProFilter</filter-class>     </filter>    <filter-mapping>       <filter-name>ProFilter</filter-name>       <url-pattern>*</url-pattern><!-- 过滤所有请求,注:tomcat5请用/* -->    </filter-mapping>   这样配置之后只要页面有任何请求都会通过ProFilter进行中文处理了,就不会再发生中文乱码问题了。   那一串通过get传递过来的中文处理过程如下: 1.      在jsp页面的JavaScript里面进行编码处理: url=encodeURI(‘leavesp?work=部门主管审批’) 编码后结果:url=leavesp?work=部门主管审批 2.      因为在web.xml过滤器配置为<url-pattern>*</url-pattern>所以所有请求将会通过过滤器进行处理,此过滤器处理过程如下: 2.1获得参数名集合: Enumeration<String> paramNames =request.getParameterNames(); String name = paramNames.nextElement(); 2.1结果中有name=’work’;一值。   2.2通过参数名获得参数值: String values[] =request.getParameterValues(name); 因work的值只有一个所以2.2的结果为:values[0]=’ 部门主管审批’;(此处得到的是字符串:“部门主管审批”的iso-8859-1编码格式字符)   2.3获得字符串的UTF-8编码格式字符: outStr = newString(inStr.getBytes("iso-8859-1"),"UTF-8"); 2.3中获得的结果为outStr=“部门主管审批”. 至此中文已经正常了。   不过过滤器还没处理结束,还得将参数名对应的值(已经处理的值)再重新藏到请求中去。 2.4将参数名对应结果藏入请求中: request.setAttribute(name, outStr); 通过2.4处理后,请求中的work的值就变成了:部门主管审批   2.5 继续执行下一个filter,无一下个filter则执行请求 chain.doFilter(request, response); 3.      通过过滤器之后,就可以进入请求中对应leavesp的servlet了(servlet就不做说明了),此时在servlet中通过String work=request.getParameter(“work”);就可以获得url中传递过来的中文参数值了,结果为work=”部门主管审批”。   看到这里,你应该也已经会处理中文乱码问题了。赶紧试试!!^_^   这是我个人处理中文乱码的经验,我将它拿来分享与各位,如果中间有写得不对的地方还请各位帮忙指正。谢谢。


    最新回复(0)