jsp亂碼分析及解決(1)

來源:互聯網
上載者:User

        想必大家在網站開發時經常遇到亂碼問題,最近自己在寫了一個部落格的小例子時,又遇到了亂碼問題,一般都是些常見的,往往搜搜,都有解決方案,但網上大部分都是直接貼解決方案的,沒有指出具體原因,所以這兩天自己看了一些關於亂碼的文章,慢慢有點頭緒,所以抓緊寫下來,我會把自己遇到的亂碼問題一一呈現給大家,並分析原因及寫出解決辦法。


         如有不對,還請大家多多包含,積極指正!一個人的理解往往是有限,甚至有錯誤,集思廣益才會使分析更趨於正確、完美!



先看一段代碼,解釋幾處代碼:

<%@ page language="java" pageEncoding="gb2312"%><%@ page contentType="text/html;charset=iso8859-1"%><html><head><title>JSP的中文處理</title><meta http-equiv="Content-Type" content="text/html charset=gb2312"></head><body><%out.print("JSP的中文處理");%></body></html>

第一處<%@ page language="java" pageEncoding="gb2312"%>,指定了頁面的編碼格式,jsp檔案的儲存格式就是這個編碼格式,Eclipse會根據這個編碼格式儲存檔案。並編譯jsp檔案,包括裡面的漢字。

第二處編碼為解碼格式。因為存為gb2312的檔案被解碼為iso8859-1,這樣如有中文肯定出亂碼。也就是必須一致。如果第二處所在的這一行沒有的話,系統預設也是使用iso8859-1的編碼格式。所以如果沒有這一行的話,也會出現亂碼。必須一致才可以。

這行負責jsp頁面中字元按什麼編碼格式顯示,也就是最終見到的網頁內容的編碼格式。

注意:<%@ page language="java" pageEncoding=""%>指定了,<%@ page contentType="text/html;charset="%>沒有指定的話,一般預設是iso8859-1編碼格式;反之,它們編碼格式相同。

 第三處編碼為控制瀏覽器的解碼方式。如果前面的解碼都一致並且無誤的話,這個編碼格式用不用設定都可以。有的網頁出現亂碼,就是因為瀏覽器不能確定使用哪種編碼格式。因為頁面有時候會嵌入頁面,導致瀏覽器混淆了編碼格式出現了亂碼。

注意:<%@ page contentType="text/html;charset="%>指定了瀏覽器的編碼格式,如果jsp頁面中指定了這個,那麼meta http-equiv="Content-Type" content="text/html charset=">是不起作用的;只有jsp中沒有<%@ page contentType="text/html;charset="%>,它才會起作用;如果它們都存在,<%@ page contentType="text/html;charset="%>優先。

下面開始進入本文:

情形1:

             jsp頁面利用form表單提交(method=“post”),在servlet檔案中利用request.getParameter("參數名")得到傳過來的值。這裡往往會出現亂碼。



接下來的例子的處理方式是正確的,大家注意看紅色字。


關鍵點:jsp中的charset=“utf-8”且value = new String(value.getBytes("ISO8859_1"),
"utf-8");這兩個地方字元要保持一致才行。


index.jsp

<%@ page contentType="text/html; charset=utf-8" language="java" import="java.sql.*" errorPage="" %><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title></title><link href="CSS/style.css" type="text/css" rel="stylesheet"><style type="text/css"></style></head><body onselectstart="return false"><table class="indexmain">  <tr>    <td valign="top"><table width="658" border="0"> <tr>        <td colspan="2"> </td> </tr>      <tr>        <td width="92" height="358"> </td>        <td width="550" valign="bottom"><form name="form1" method="post" action="ConsumerServlet?method=0&sign=0" onSubmit="return userCheck()"><table width="291" border="0" align="center" cellpadding="0" cellspacing="0">  <tr>    <td width="66" height="30">使用者名稱:</td>    <td width="225">      <input name="account" type="text" class="inputinput" id="account" size="30">    </td>  </tr>    <tr>    <td height="30">密  碼:</td>    <td><input name="password" type="password" class="inputinput" id="password" size="30"></td>  </tr>    <tr>    <td height="30" colspan="2" align="center">    <input type="image" class="inputinputinput" src="images/land.gif">                        <a href="#" onClick="javascript:form1.reset()"><img src="images/reset.gif"></a>          <a href="accountAdd.jsp"><img src="images/register.gif"></a>   </td>  </tr></table></form></td>      </tr></table></td></tr></table><script src="JS/validate.js" language="javascript" type="text/javascript"></script></body></html>


ConsumerServlet.java


// 使用者登入操作public void checkConsumer(HttpServletRequest request,HttpServletResponse response)                                                         throws ServletException, IOException {String account = Chinese.toChinese(request.getParameter("account"));consumerDao = new ConsumerDao();ConsumerForm consumerForm = consumerDao.getConsumerForm(account);if (consumerForm == null) {request.setAttribute("information", "您輸入的使用者名稱不存在,請重新輸入!");} else if (!consumerForm.getPassword().equals(request.getParameter("password"))) {request.setAttribute("information", "您輸入的登入密碼有誤,請重新輸入!");} else {request.setAttribute("form", consumerForm);}//驗證通過之後RequestDispatcher requestDispatcher = request.getRequestDispatcher("dealwith.jsp");requestDispatcher.forward(request, response);}

Chinese.java(關鍵)

              

public class Chinese {    public  static String  toChinese(String value) {           try {               if (value == null) {                   return "";               } else {                   value = new String(value.getBytes("ISO8859_1"), "utf-8");                   return value;                                                            }                             //用ISO8859_1的編碼格式去讀取value,並轉換成utf-8           } catch (Exception e) {               return "";           }    }}


這段代碼負責轉碼,可能大家對紅色代碼不太理解,我這裡貼上JAVA API的解釋:

public byte[] getBytes(String charsetName)

               throws
UnsupportedEncodingException

使用指定的字元集將此String 解碼為位元組序列,並將結果儲存到一個新的位元組數組中。

當此字串不能在給定的字元集中解碼時,該方法無指定的行為。當需要進一步控制解碼過程時,應使用CharsetEncoder 類。

參數:

charsetName - 受支援的
charset 名稱

返回:

結果位元組數組

拋出:

UnsupportedEncodingException - 如果指定的字元集不受支援

public String(byte[] bytes,

              String charsetName)

       throws UnsupportedEncodingException

構造一個新的 String,方法是使用指定的字元集解碼指定的位元組數組。新的 String 的長度是一個字元集函數,因此不能等於位元組數組的長度。

當給定位元組在給定字元集中無效的情況下,該構造方法無指定的行為。當需要進一步控制解碼過程時,應使用
CharsetDecoder 類。

參數:

bytes - 要解碼為字元的位元組

charsetName - 受支援的 charset 的名稱

拋出:

UnsupportedEncodingException - 如果指定字元集不受支援

情形2:

          form表單的另外一種形式(利用Submit)。

下面是一個提交頁面(submit.jsp),代碼如下:

<%@ page contentType="text/html; charset=gb2312"%> <html><head><title>JSP的中文處理</title><meta http-equiv="Content-Type" content="text/html; charset=gb2312"></head><body><form name="form1" method="post/get" action="process.jsp"><div align="center"><input type="text" name="name"><input type="submit" name="Submit" value="Submit"></div></form></body></html>

下面是處理頁面(process.jsp)代碼:


<%@ page contentType="text/html; charset=gb2312"%><html><head><title>JSP的中文處理</title><meta http-equiv="Content-Type" content="text/html; charset=gb2312"></head><body><%=request.getParameter("name")%></body></html>

如果輸入中文,就會看到亂碼,解決方案同上:


<%@ page contentType="text/html; charset=gb2312"%><html><head><title>JSP的中文處理</title><meta http-equiv="Content-Type" content="text/html; charset=gb2312"></head><body><%String s=new String(request.getParameter("name").getBytes("ISO-8859-1"),"gb2312") ;out.print(s);%></body></html>

這樣就OK了。



分析:

            tomcat預設使用ISO-8859-1的方式去讀取數值的,但實際裡面的字元編碼應該是jsp頁面的pageEncoding指定的(一般不會是iso-8859-1),這樣的話讀取之後顯示的編碼格式和儲存的格式不一致,所以出現了亂碼。

            而我們的轉碼恰恰解決了這個問題,我們先使用ISO-8859-1格式解碼字串,再利用與pageEncoding一致的編碼格式解碼位元組數組,這樣就使讀取之後顯示的編碼格式和儲存的格式一致,亂碼問題解決。





網上搜尋的來另外一種解決方案:

                                         通過request.seCharacterEncoding ("gb2312")對請求進行統一編碼。

修改後的process.jsp代碼如下:

<%@ page contentType="text/html; charset=gb2312"%><%request.setCharacterEncoding("gb2312");%><html><head><title>JSP的中文處理</title><meta http-equiv="Content-Type" content="text/html; charset=gb2312"></head><body><%=request.getParameter("name")%></body></html>

經測試,這個方法不行,還是亂碼,哪位給解釋解釋????

未完待續~~~


               

           


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.