Put on steam!!

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  4 Posts :: 0 Stories :: 20 Comments :: 0 Trackbacks

作者:肖文伟

 

在网上搜了很多资料都没有搞定,一般都有以下几种说法:

方法1:在后台中先获得字符串的iso-8859-1编码形式数组,再使用此数组实例一个UTF-8编码形式String类型字符串.

页面提交的url:

leavesp?work=部门主管审批

 

后台处理:

String inStr=request.getParameter("work ");

String outStr = new String(inStr.getBytes("iso-8859-1"),"UTF-8");

 

方法2:在页面传递过来时先通过JavaScriptURL编码,再到后台进行解码:

页面部分:

<script type="text/javascript">

function dogetMethod(url)

{

        //url编码前: leavesp?work=部门主管审批

 

url=encodeURI(url);

 

//url编码后:

leavesp?work=%E9%83%A8%E9%97%A8%E4%B8%BB%E7%AE%A1%E5%AE%A1%E6%89%B9

 

window.open(uri,’’,’’);

}

</script>

后台部分:(解码)

String inStr= request.getParameter("work ");

String outStr=java.net.URLDecoder.decode(inStr);

 

尝试过两种方法后好像都不行,在后台获取到的字符还是会乱码.试完之后真想哭.*o*

使用第一种方法后发现:

在请求(request)中获得的字符串是这样的: ²¿ÃÅÖ÷¹ÜÉóÅú

使用new String(inStr.getBytes("iso-8859-1"),"UTF-8");处理后字符成了: ����������

 

没法,只能再试第二种方法了,使用后发现:

在页面中使用encodeURI(url),字符串是这样的:

%E9%83%A8%E9%97%A8%E4%B8%BB%E7%AE%A1%E5%AE%A1%E6%89%B9

好像有希望了!!!!

应该只要在后台再来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//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <script type="text/javascript">

        //开启网页对话脚本

        function openDialog(url,width,height)

        {

           var property="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="#" onclick="javascript:showork('leavesp?work=部门主管审批')">查看待办工作</a>

</td>   

        </tr>            

    </table>  

  </body>

</html>

 

页面部分就一个超连接,用来开启一个网页对话框,只是开启的这个对话框中请求的不是一个物理的页面,而是请求的一个servletleavesp),而且url中带有中文参数值(?work=部门主管审批)。

 

为了处理中文乱码部分能够在整个WEB系统中都能够使用到,所以将中文乱码处理写成了一个Filter(过滤器),并在web.xml中配置所有的请求都将经过这个Filter进行过滤。Filter部分的代码如下:

文件名:ProFilter.java

package com.util.filters;

 

import java.io.IOException;

import java.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;

import javax.servlet.http.HttpServletRequest;

import javax.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 = new String(inStr.getBytes("iso-8859-1"),"UTF-8");        

       }

       return outStr;

    }  

 

    /**

     * 中文乱码过滤处理

     */

    public void doFilter(ServletRequest svlrequest, ServletResponse svlresponse,

           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]即第一个参数值)方法转换参数值的字元编码                        

                         String vlustr=toUTF(values[0]);

                         //并将该值以属性的形式藏在request

                         request.setAttribute(name, vlustr);

                     } catch (UnsupportedEncodingException e)

                     {

                         e.printStackTrace();

                     }

                  }

                  //如果参数值集中有多个值

                  else

                  {

                     //遍历参数值集

                     for(int i=0;i<values.length;i++)

                     {

                         try

                         {

                            //回圈依次将每个值调用toUTF(values[i])方法转换参数值的字元编码

                            String vlustr=toUTF(values[i]);

                            values[i] = 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()

    {

      

    }

}

 

过滤器部分,可用来处理页面提交的postget方法产生的中文乱码问题。

Post方式提交的数据(form表单中提交的数据)只需要进行请求字符编码设置request.setCharacterEncoding("UTF-8");和响应设置response.setContentType("text/html;charset=UTF-8");设置就可以了。

Get方式提交的数据会包含在url中,(如:leavesp?work=部门主管审批),则需要取出参数名:Enumeration<String> paramNames = request.getParameterNames();(如:work)和取出参数值:String values[] = 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=%E9%83%A8%E9%97%A8%E4%B8%BB%E7%AE%A1%E5%AE%A1%E6%89%B9

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 = new String(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.       通过过滤器之后,就可以进入请求中对应leavespservlet了(servlet就不做说明了),此时在servlet中通过String work=request.getParameter(“work”);就可以获得url中传递过来的中文参数值了,结果为work=” 部门主管审批

 

看到这里,你应该也已经会处理中文乱码问题了。赶紧试试!!^_^

 

这是我个人处理中文乱码的经验,我将它拿来分享与各位,如果中间有写得不对的地方还请各位帮忙指正。谢谢。

posted on 2009-05-26 15:07 zeus.xiao 阅读(11266) 评论(4)  编辑  收藏

Feedback

# re: 处理URL传递中文乱码问题[未登录] 2009-05-26 16:06 bluesky
以前我们也遇到这种问题,如果你用的是Tomcat的话,可以在定义端口号的的地方添加一个属性:URIEncoding="GBK",你可以试试看  回复  更多评论
  

# re: 处理URL传递中文乱码问题 2009-05-27 18:51 一农
@bluesky

tomcat5 还是 5.5之后就存在这个问题。

另外如果使用spring的话,可以使用其CharacterEncodingFilter,并建议将forceEncoding设为false,这样可以接受客户端不同的编码。特别是使用ajax的时候。  回复  更多评论
  

# re: 处理URL传递中文乱码问题[未登录] 2009-05-29 14:57 zeus.xiao
回复:@一农
在处理Ajax的中文乱码问题的时候,我也出现了一些问题,但不知道怎样来处理.您有好的方法解决吗?
  回复  更多评论
  

# re: 处理URL传递中文乱码问题 2009-06-11 16:33 zeus.xiao
@bluesky
Hi bluesky:
你的提供的方法我试了一下,在Struts中证实可以解决URI传递乱码问题.
我是这样做的:
1.设定Tomcat的URI编码为"UTF-8":修改%tomcat%\conf\server.xml中的<Connector>在中间加入URIEncoding="UTF-8";
2.先在页面上encodeURI(url);
3.后台代码中直接取出来的中文参数就已经OK了.

不过这种方法用在servlet中行不通,在servlet中就必须对URI进行处理,Tomcat中有没有加入URIEncoding都没有差别.

谢谢你的建议.^_^  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: