作者:肖文偉
在網(wǎng)上搜了很多資料都沒(méi)有搞定,一般都有以下幾種說(shuō)法:
方法1:在后臺(tái)中先獲得字符串的iso-8859-1編碼形式數(shù)組,再使用此數(shù)組實(shí)例一個(gè)UTF-8編碼形式String類型字符串.
頁(yè)面提交的url為:
leavesp?work=部門主管審批
后臺(tái)處理:
String inStr=request.getParameter("work ");
String outStr = new String(inStr.getBytes("iso-8859-1"),"UTF-8");
方法2:在頁(yè)面?zhèn)鬟f過(guò)來(lái)時(shí)先通過(guò)JavaScript將URL編碼,再到后臺(tái)進(jìn)行解碼:
頁(yè)面部分:
<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>
后臺(tái)部分:(解碼)
String inStr= request.getParameter("work ");
String outStr=java.net.URLDecoder.decode(inStr);
嘗試過(guò)兩種方法后好像都不行,在后臺(tái)獲取到的字符還是會(huì)亂碼.試完之后真想哭.*o*
使用第一種方法后發(fā)現(xiàn):
在請(qǐng)求(request)中獲得的字符串是這樣的: ²¿ÃÅÖ÷¹ÜÉóÅú
使用new String(inStr.getBytes("iso-8859-1"),"UTF-8");處理后字符成了: ??????????
沒(méi)法,只能再試第二種方法了,使用后發(fā)現(xiàn):
在頁(yè)面中使用encodeURI(url)后,字符串是這樣的:
%E9%83%A8%E9%97%A8%E4%B8%BB%E7%AE%A1%E5%AE%A1%E6%89%B9
好像有希望了!!!!
應(yīng)該只要在后臺(tái)再來(lái)decoder一下就行了吧,偶是這樣想的,也是這樣做的:
在后臺(tái)中:
String inStr= request.getParameter("work ");
outStr=java.net.URLDecoder.decode(inStr);
在請(qǐng)求中獲得的字符串是這樣的: é?¨é¨ä¸»ç®¡å®¡æ?¹
decoder處理后得出的字符串為: é?¨é¨ä¸»ç®¡å®¡æ?¹
這時(shí)候真想哭啊!!%#$%@@!@$$##
革命尚未成功,還需努力!!!
從第二種方法中發(fā)現(xiàn):
在請(qǐng)求中獲得的字符串已經(jīng)亂碼了,用decoder處不處理值都是一個(gè)樣!!
明明我在頁(yè)面?zhèn)鬟^(guò)來(lái)的值是已經(jīng)encode過(guò)了的字符,而后來(lái)取出來(lái)卻….,這是為什么呢?
難倒是頁(yè)面編碼設(shè)置得有問(wèn)題?
看了一下頁(yè)面編碼是: pageEncoding="UTF-8"
改了!改成: pageEncoding="iso-8859-1"試試.
瀏覽頁(yè)面上,發(fā)現(xiàn)頁(yè)面上的中文變成了很多éæ?之類的字符,不管了,再試下,還是一樣的結(jié)果.濤聲依舊!
忽然想到應(yīng)該是在獲得字符串之前,也就是在request. getParameter("work ");這之前的某個(gè)地方已經(jīng)將URL進(jìn)行了decoder,并且將獲得的字符用Iso-8859-1的編碼方式存儲(chǔ)過(guò)了.
所以在request中會(huì)得到這些類似于éæ?之類的字符,這種字符應(yīng)該就是中文的iso-8859-1的形式!!
有辦法了,既然已經(jīng)獲得了iso-8859-1編碼形式的中文,那就只要再使用第一種方法(先獲得字符串的iso-8859-1數(shù)組,再將它實(shí)例成UTF-8的字符串)來(lái)進(jìn)行處理不就OK了!
試過(guò)之后果然OK!!!
處理中文亂碼代碼實(shí)現(xiàn)部分:
jsp頁(yè)面:
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript">
//開啟網(wǎng)頁(yè)對(duì)話腳本
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地址進(jìn)行編碼
url=encodeURI(url);
//alert(url);
//調(diào)用openDialog方法開啟網(wǎng)頁(yè)對(duì)話框
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>
頁(yè)面部分就一個(gè)超連接,用來(lái)開啟一個(gè)網(wǎng)頁(yè)對(duì)話框,只是開啟的這個(gè)對(duì)話框中請(qǐng)求的不是一個(gè)物理的頁(yè)面,而是請(qǐng)求的一個(gè)servlet(leavesp),而且url中帶有中文參數(shù)值(?work=部門主管審批)。
為了處理中文亂碼部分能夠在整個(gè)WEB系統(tǒng)中都能夠使用到,所以將中文亂碼處理寫成了一個(gè)Filter(過(guò)濾器),并在web.xml中配置所有的請(qǐng)求都將經(jīng)過(guò)這個(gè)Filter進(jìn)行過(guò)濾。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轉(zhuǎn)為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了,到這的時(shí)候就已經(jīng)自動(dòng)decode過(guò)了
//將字符串轉(zhuǎn)為UTF-8編碼形式
outStr = new String(inStr.getBytes("iso-8859-1"),"UTF-8");
}
return outStr;
}
/**
* 中文亂碼過(guò)濾處理
*/
public void doFilter(ServletRequest svlrequest, ServletResponse svlresponse,
FilterChain chain) throws IOException, ServletException
{
//將Servlet請(qǐng)求與響應(yīng)對(duì)象轉(zhuǎn)換成HttpServlet請(qǐng)求與響應(yīng)對(duì)象
HttpServletRequest request=(HttpServletRequest)svlrequest;
HttpServletResponse response=(HttpServletResponse)svlresponse;
//獲得請(qǐng)求的方式(1.post or 2.get),根據(jù)不同請(qǐng)求方式進(jìn)行不同處理
String method = request.getMethod();
//1.以post方式提交的請(qǐng)求,直接設(shè)置編碼為UTF-8
if(method.equalsIgnoreCase("post"))
{
try
{
request.setCharacterEncoding("UTF-8");
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
//2.以get方式提交的請(qǐng)求
else
{
//取出客戶提交的參數(shù)集
Enumeration<String> paramNames = request.getParameterNames();
//遍歷參數(shù)集取出每個(gè)參數(shù)的名稱及值
while(paramNames.hasMoreElements())
{
String name = paramNames.nextElement();//取出參數(shù)名稱
String values[] = request.getParameterValues(name);//根據(jù)參數(shù)名稱取出其值
//如果參數(shù)值集不為空
if(values != null)
{
//如果參數(shù)值集中只有一個(gè)值
if(values.length == 1)
{
try
{
//調(diào)用toUTF(values[0])函數(shù),(values[0]即第一個(gè)參數(shù)值)方法轉(zhuǎn)換參數(shù)值的字元編碼
String vlustr=toUTF(values[0]);
//并將該值以屬性的形式藏在request
request.setAttribute(name, vlustr);
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
//如果參數(shù)值集中有多個(gè)值
else
{
//遍歷參數(shù)值集
for(int i=0;i<values.length;i++)
{
try
{
//回圈依次將每個(gè)值調(diào)用toUTF(values[i])方法轉(zhuǎn)換參數(shù)值的字元編碼
String vlustr=toUTF(values[i]);
values[i] = vlustr;
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
//將該值以屬性的形式藏在request
request.setAttribute(name, values);
}
}
}
}
//設(shè)置響應(yīng)方式和支持中文的字元集
response.setContentType("text/html;charset=UTF-8");
//繼續(xù)執(zhí)行下一個(gè)filter,無(wú)一下個(gè)filter則執(zhí)行請(qǐng)求
chain.doFilter(request, response);
}
/**
* 銷毀方法
*/
public void destroy()
{
}
}
過(guò)濾器部分,可用來(lái)處理頁(yè)面提交的post和get方法產(chǎn)生的中文亂碼問(wèn)題。
Post方式提交的數(shù)據(jù)(form表單中提交的數(shù)據(jù))只需要進(jìn)行請(qǐng)求字符編碼設(shè)置request.setCharacterEncoding("UTF-8");和響應(yīng)設(shè)置response.setContentType("text/html;charset=UTF-8");設(shè)置就可以了。
Get方式提交的數(shù)據(jù)會(huì)包含在url中,(如:leavesp?work=部門主管審批),則需要取出參數(shù)名:Enumeration<String> paramNames = request.getParameterNames();(如:work)和取出參數(shù)值:String values[] = request.getParameterValues(name);(如:部門主管審批),然后再將參數(shù)值進(jìn)行編碼轉(zhuǎn)換:outStr = new String(inStr.getBytes("iso-8859-1"),"UTF-8");
過(guò)濾器寫好這后就需要到web.xml中<web-app>與</web-app>之間進(jìn)行配置了,web.xml中配置如下:
<!-- 配置過(guò)濾器 -->
<filter>
<description>處理中文亂碼過(guò)濾器</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><!-- 過(guò)濾所有請(qǐng)求,注:tomcat5請(qǐng)用/* -->
</filter-mapping>
這樣配置之后只要頁(yè)面有任何請(qǐng)求都會(huì)通過(guò)ProFilter進(jìn)行中文處理了,就不會(huì)再發(fā)生中文亂碼問(wèn)題了。
那一串通過(guò)get傳遞過(guò)來(lái)的中文處理過(guò)程如下:
1. 在jsp頁(yè)面的JavaScript里面進(jìn)行編碼處理:
url=encodeURI(‘leavesp?work=部門主管審批’)
編碼后結(jié)果:url=leavesp?work=%E9%83%A8%E9%97%A8%E4%B8%BB%E7%AE%A1%E5%AE%A1%E6%89%B9
2. 因?yàn)樵?/span>web.xml過(guò)濾器配置為<url-pattern>*</url-pattern>所以所有請(qǐng)求將會(huì)通過(guò)過(guò)濾器進(jìn)行處理,此過(guò)濾器處理過(guò)程如下:
2.1獲得參數(shù)名集合:
Enumeration<String> paramNames = request.getParameterNames();
String name = paramNames.nextElement();
2.1結(jié)果中有name=’work’;一值。
2.2通過(guò)參數(shù)名獲得參數(shù)值:
String values[] = request.getParameterValues(name);
因work的值只有一個(gè)所以2.2的結(jié)果為:values[0]=’ é?¨é¨ä¸»ç®¡å®¡æ?¹’;(此處得到的是字符串:“部門主管審批”的iso-8859-1編碼格式字符)
2.3獲得字符串的UTF-8編碼格式字符:
outStr = new String(inStr.getBytes("iso-8859-1"),"UTF-8");
2.3中獲得的結(jié)果為outStr=“部門主管審批”.
至此中文已經(jīng)正常了。
不過(guò)過(guò)濾器還沒(méi)處理結(jié)束,還得將參數(shù)名對(duì)應(yīng)的值(已經(jīng)處理的值)再重新藏到請(qǐng)求中去。
2.4將參數(shù)名對(duì)應(yīng)結(jié)果藏入請(qǐng)求中:
request.setAttribute(name, outStr);
通過(guò)2.4處理后,請(qǐng)求中的work的值就變成了:部門主管審批
2.5 繼續(xù)執(zhí)行下一個(gè)filter,無(wú)一下個(gè)filter則執(zhí)行請(qǐng)求
chain.doFilter(request, response);
3. 通過(guò)過(guò)濾器之后,就可以進(jìn)入請(qǐng)求中對(duì)應(yīng)leavesp的servlet了(servlet就不做說(shuō)明了),此時(shí)在servlet中通過(guò)String work=request.getParameter(“work”);就可以獲得url中傳遞過(guò)來(lái)的中文參數(shù)值了,結(jié)果為work=” 部門主管審批”。
看到這里,你應(yīng)該也已經(jīng)會(huì)處理中文亂碼問(wèn)題了。趕緊試試??!^_^
這是我個(gè)人處理中文亂碼的經(jīng)驗(yàn),我將它拿來(lái)分享與各位,如果中間有寫得不對(duì)的地方還請(qǐng)各位幫忙指正。謝謝。