程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> JSP+ MySQL中文亂碼問題post提交亂碼解決方案

JSP+ MySQL中文亂碼問題post提交亂碼解決方案

日期:2017/1/9 14:17:24      編輯:關於JSP
    當提交的數據中含有中文(比如變量姓名的值為中文)時,mysql_insert.jsp頁面上顯示新增的那條記錄中的相應中文(姓名的值)亂碼  

    寫了兩個jsp頁面index.jsp和mysql_insert.jsp。數據處理流程為:在浏覽器(chrome)上訪問index.jsp後在其表 單上輸入數據,提交至mysql_insert.jsp,mysql_insert.jsp首先將接收到的數據按變量存入MySQL的html_db數據 庫的person_tb中(該表原有部分數據),然後mysql_insert.jsp再拿出該表中所有數據顯示在mysql_insert.jsp頁面 上。

    現在發現,當提交的數據中含有中文(比如變量姓名的值為中文)時,mysql_insert.jsp頁面上顯示新增的那條記錄中的相應中文(姓名的值)亂碼,其他數據都顯示正常,查看數據庫,發現也是相應的含有中文的變量值(姓名的值)亂碼。亂碼情況如下圖:
    JSP+ MySQL中文亂碼問題post提交亂碼解決方案 三聯 
    index.jsp 中第一行有語句:<%@ page contentType="text/html;charset=gb2312"%> ,在浏覽器(chrome)中訪問此頁面時無亂碼(主要指中文亂碼,英文亂碼現象還沒遇見過)。(試過將gb2312換成utf-8,訪問後中文亂碼)
    mysql_insert.jsp中第一行有語句:<%@page language="java" pageEncoding="UTF-8"%>,在浏覽器中直接訪問此頁面時無亂碼。
    mysql_insert.jsp頁面的代碼如下:

    復制代碼 代碼如下:
    <%@page language="java" pageEncoding="UTF-8"%>
    <%@ page import="java.sql.*" %>
    <HTML>
    <HEAD>
    <TITLE>add message into table </TITLE>
    </HEAD>
    <BODY>
    <%
    String id=request.getParameter("id"); //從表單獲得
    String name=request.getParameter("name"); //從表單獲得
    String sex=request.getParameter("sex"); //從表單獲得
    String age=request.getParameter("age"); //從表單獲得
    try
    {
    /** 連接數據庫參數 **/
    String driverName = "com.mysql.jdbc.Driver"; //驅動名稱
    String DBUser = "root"; //mysql用戶名
    String DBPasswd = "123456"; //mysql密碼
    String DBName = "html_db"; //數據庫名

    String connUrl = "jdbc:mysql://localhost/" + DBName + "?user=" + DBUser + "&password=" + DBPasswd;
    Class.forName(driverName).newInstance();
    Connection conn = DriverManager.getConnection(connUrl);
    Statement stmt = conn.createStatement();
    stmt.executeQuery("SET NAMES UTF8");
    String insert_sql = "insert into person_tb values('" + id + "','" + name + "','" + sex + "','" + age + "')";
    String query_sql = "select * from person_tb";

    try {
    stmt.execute(insert_sql);
    }catch(Exception e) {
    e.printStackTrace();
    }
    try {
    ResultSet rs = stmt.executeQuery(query_sql);
    while(rs.next()) {
    %>
    ID:<%=rs.getString("id")%> </br>
    姓名:<%=rs.getString("name")%> </br>
    性別:<%=rs.getString("sex")%> </br>
    年齡:<%=rs.getString("age")%> </br> </br>
    <%
    }
    }catch(Exception e) {
    e.printStackTrace();
    }
    //rs.close();
    stmt.close();
    conn.close();
    }catch (Exception e) {
    e.printStackTrace();
    }
    %>
    </body>
    </html>


    我的數據庫設置的是全部使用UTF-8編碼,如下圖:
     
    我的虛擬目錄下的web.xml內容如下:
     
    tomcat/conf目錄下的server.xml文件的內容如下:

    復制代碼 代碼如下:
    <U><?xml version='1.0' encoding='utf-8'?></U>
    <Server port="8005" shutdown="SHUTDOWN">
    <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
    <Listener className="org.apache.catalina.core.JasperListener" />
    <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
    <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
    <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
    type="org.apache.catalina.UserDatabase"
    description="User database that can be updated and saved"
    factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
    pathname="conf/tomcat-users.xml" />
    </GlobalNamingResources>
    <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <Engine name="Catalina" defaultHost="localhost">
    <Realm className="org.apache.catalina.realm.LockOutRealm">
    <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
    resourceName="UserDatabase"/>
    </Realm>
    <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
    prefix="localhost_access_log." suffix=".txt"
    pattern="%h %l %u %t "%r" %s %b" />
    </Host>
    </Engine>
    </Service>
    </Server>


    tomcat/conf目錄下web.xml文件的主要內容如下:

    復制代碼 代碼如下:
    <U><?xml version="1.0" encoding="UTF-8"?></U>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
    <param-name>debug</param-name>
    <param-value>0</param-value>
    </init-param>
    <init-param>
    <param-name>listings</param-name>
    <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <init-param>
    <param-name>fork</param-name>
    <param-value>false</param-value>
    </init-param>
    <init-param>
    <param-name>xpoweredBy</param-name>
    <param-value>false</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!-- The mappings for the JSP servlet -->
    <servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
    <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>
    <session-config>
    <session-timeout>30</session-timeout>
    </session-config>
    <此處省略了mime-mapping的內容>
    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    </web-app>


    現在我能想到的設置編碼的地方也就只有這麼多了,其他還有哪裡需要設置編碼?懇求指導。
    哈哈哈,經過我的一番苦苦探索,終於找到亂碼的原因了,當然亂碼問題也被解決了。師兄對我建議所有編碼全部使用UTF-8,因此我也建議讀者也這樣做,好處很多。
    下面我介紹下我的解決過程:
    第一步:在我發現有亂碼後,我首先想到的就是是不是我在某個地方設置的編碼錯誤導致的,而MysQL裡的設置是正確的(my.ini裡設置),就是全部設置為utf8。所以MySQL下的設置我不需要修改。
    第 二步:然後就是tomcat了,這東西要對我提交的數據進行處理,網上有許多人提出需要設置web.xml和server.xml裡面的編碼,其中主要是 在server.xml裡添加URIEncoding="UTF-8",具體設置為:<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />。在我完成這一步的設置之後再次測試,發現還是亂碼。保留這一步的修改,進行下一步。
    第三 步:再次回到.jsp頁面,我試著將所有涉及到編碼和字符集的地方都設置為UTF-8(我之前在index.jsp中首行寫的是<%@page language="java" contentType="text/html; charset=gb2312" %> ,現在使用dreamweaver打開index.jsp將其修改為charset=utf-8),然後在浏覽器直接訪問index.jsp發現中文有亂 碼,於是關閉dreamweaver,使用myeclipse重新打開index.jsp文件,發現代碼中的中文就是亂碼,果斷修改成正確的中文字符,同 時保留剛才對charset的修改,即仍然使用charset=utf-8,然後重新在浏覽器訪問index.jsp,終於中文字符正常顯示了。(以後從 此告別dreamweaver,害我饒了好多路)然後我在index.jsp頁面上輸入中文數據並提交,依然是中文亂碼。做了這一步的修改後,我的兩 個.jsp文件的頭部均有如下兩句:
    <%@ page language="java" pageEncoding="utf-8"%>
    <%@ page contentType="text/html;charset=utf-8"%>

    第 四步:我剛才在想,到底是往數據庫存數據時導致的亂碼還是從數據庫取數據時導致的亂碼呢?再或者是在提交後傳輸數據到mysql_insert.jsp頁 面時導致的亂碼?然後我直接在數據庫中插入一條含有中文字符的數據,然後在浏覽器直接訪問mysql_insert.jsp,發現中文字符能正常顯示。那 就是說,是在存數據,或者傳輸數據時亂碼的了。那麼該怎麼設置才能不至於傳數據、存數據不亂碼呢?
    第五步:網上找了下,找到如下內容,非常有用:
    1、jsp頁面的編碼方式有兩個地方需要設置:

    復制代碼 代碼如下:
    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%@ page contentType="text/html;charset=utf-8"%>


    其中:pageEncoding 指的是jsp文件本身在本地保存時的編碼方式。contentType的charset是指服務器發送網頁內容給客戶端時所使用的編碼。
    從第一次訪問一個jsp頁面開始,到這個頁面被發送到客戶端,這個Jsp頁面要經過三次編碼轉換:
    第一階段是jsp編譯成.java,它會根據pageEncoding的設定讀取jsp,結果是由指定的編碼方案翻譯成統一的UTF-8 JAVA源碼(即.java),如果pageEncoding設定錯了,或沒有設定,出來的就是中文亂碼。
    第二階段是由JAVAC的JAVA源碼至java byteCode的編譯,不論JSP編寫時候用的是什麼編碼方案,經過這個階段的結果全部是UTF-8的encoding的java源碼。
    JAVAC用UTF-8的encoding讀取java源碼,編譯成UTF-8 encoding的二進制碼(即.class),這是JVM對常數字串在二進制碼(java encoding)內表達的規范。
    第三階段是Tomcat(或其的application container)載入和執行階段二的來的JAVA二進制碼,輸出的結果,也就是在客戶端見到的,這時隱藏在階段一和階段二的參數contentType就發揮了功效
    所以最終的解決方法為:
    在jsp頁面設置pageEncoding或者contentType的其中一個為支持中文的編碼格式(如utf-8,gbk,gb2312)。因為設置一個的話,另一個默認會和它一樣。
    如果兩個都設置的話,必須保證兩個都是支持中文編碼(不一定要一樣)。
    最佳建議設置如下:
    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%@ page contentType="text/html;charset=utf-8"%>

    2、post方式傳值亂碼:
    由 於post方式傳值是通過request存儲的,在另一個頁面也是通過request.getParameter(String name)來提取信息,所以這種情況下的亂碼主要是因為request存儲信息的編碼設置導致的。post提交時,如果沒有設置提交的編碼格式,則會以 iso8859-1方式進行提交,接受的jsp卻以utf-8的方式接受。所以使用如下語句即可得到單個正確的中文字符串:String str = new String(request.getParameter("something").getBytes("ISO-8859-1"),"utf-8") ;
    解決方法:
    一、在接收頁面設置request.setCharacterEncoding("UTF-8")。
    二、最好通過過濾器實現每個頁面都設置為request.setCharacterEncoding("UTF-8")。
    三、在發送數據的頁面使用語句指定使用UTF-8格式發送數據。
    3、get方式傳值亂碼:
    get方式傳值有兩種,一種是表單get傳值,另一種是url地址傳值(實質上這兩種方式都是通過url參數的方式傳值)。
    表單方式get傳值:
    表 單方式get傳值的編碼過程為,首先浏覽器根據頁面的charset編碼方式對傳值進行編碼,然後提交至服務器交給tomcat,tomcat對這些信息 進行解碼時,采用的解碼方式是由server.xml文件中的URIEncoding設置決定的,也就是說,當我們使用命令 request.getParameter("")獲取表單參數值時,得到的字符串,經過了charset的編碼和URIEncoding的解碼。

    由上所知,只要charset的編碼和URIEncoding的解碼一致,並且支持中文,就能保證沒有亂碼。
    設置URIEncoding的方法如下:
    方法一:
    修改$TOMCAT/conf/server.xml文件,在HTTP Connector或者AJP Connector的配置加上URIEncoding="UTF-8"

    復制代碼 代碼如下:
    <... maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
    enableLookups="false" redirectPort="8443" acceptCount="100"
    connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8" />


    方法二:
    使用useBodyEncodingForURI="true". 這個方法適合你的TOMCAT實例下需要跑多個不同Encoding的程序時。

    復制代碼 代碼如下:
    <... maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
    enableLookups="false" redirectPort="8443" acceptCount="100"
    connectionTimeout="20000" disableUploadTimeout="true" useBodyEncodingForURI="true" />
    enableLookups="false" redirectPort="8443" protocol="AJP/1.3" useBodyEncodingForURI="true" />


    在Tomcat配置中,連接器(HTTP Connector)屬性中有一個URIEncoding和
    useBodyEncodingForURI屬性,這兩個屬性設置對URL後的附加參數進行URL解碼時該如何選擇 字符集編碼。URIEncoding用於制定URL後的附加參數的字符集編碼,useBodyEncodingForURI 則說明是否采用實體內容的字符集編碼設置來替代URIEncoding的設置,也就是說當 useBodyEncodingForURI屬性設置為true時ServletRequest.setCharacterEncoding方法設置的字 符集編碼也影響getParameter等方法對URL地址後的參數進行URL解碼的結果。(在/%TomCat_Home%/ confserver.xml文件中找到 <Connector>標記,然後在後面加上useBodyEncodingForURI=true)
    url方式get傳值亂碼:
    於這種方式,浏覽器不會采用頁面的charset方式對URL中的中文進行編碼後提交至服務器(IE,FireFox都一樣),而是采用系統的GBK轉碼為ISO-8859-1之後提交至服務器tomcat,所以這個過程為:
    首先,url地址中的中文被從gbk轉換成ISO-8859-1,交給tomcat後,又被tomcat根據URLEcoding解碼,這種情況,只有 把URLEcoding設置為gbk才能在request.getParameter("")時不出現亂碼。但是這樣就會影響到上面的配置,所以一個好的 解決方法是,使用java.net.URLEcoder和URLDecoder對地址中的中文進行手動編碼和解碼。
    所以一個萬全的解決方法為:
    1)所有頁面的charset設置為UTF-8。
    2)Tomcat的URIEncoding默認是ISO-8859-1,而我設置為UTF-8,主要是想解決中文命名的文件以及請求以get方式提交有可能出現的亂碼問題。
    3)添加過濾器,調用request.setCharacterEncoding("utf-8")方法將request的字符集設定為utf-8,解決請求以post方式提交的亂碼問題。
    4)url地址中存在中文參數時,首先對中文參數使用URLEcoder編碼為utf-8,然後在request.getParameter("")接收到參數後再使用URLDecoder還原。例如:
    from.jsp頁面:

    復制代碼 代碼如下:
    <%String username = "張某某" ;
    username = URLEncoder.encode(username,"utf-8");
    %>
    <a href="to.jsp?param=<%=username %>">轉入</a>


    to.jsp頁面

    復制代碼 代碼如下:
    <%=URLDecoder.decode(request.getParameter("param"),"utf-8")%>


    總之 ,亂碼的解決方案如下:
    post傳值亂碼時,在接收端設置request.setCharacterEncoding("UTF-8")
    get傳值或者url亂碼時,手動設置接收的參數String str = new String(request.getParameter("something").getBytes("ISO-8859-1"),"utf-8") ;
    由上可見get,post傳值在tomcat5中是不一樣的.
    看完了上面紅字部分的內容,我決定在提交數據的頁面設置以UTF-8的格式提交數據,而同時在接收數據的頁面設置也以UTF-8接收數據,於是我在兩個頁面的首部都添加了如下語句:
    <%
    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html; charset=utf-8");
    %>

    然後測試,OK了!沒有亂碼了!
    現在,index.jsp頁面的代碼如下:

    復制代碼 代碼如下:


    <%@ page language="java" pageEncoding="utf-8"%>
    <%@ page contentType="text/html;charset=utf-8"%>
    <%
    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html; charset=utf-8");
    %>
    <html>
    <head>
    </head>
    <body>
    <form action="mysql_insert.jsp" method="post">
    ID :<input type = "text" name="id" value="0"/>
    姓名 :<input type = "text" name="name" value="aaa"/>
    性別 :<input type = "text" name="sex" value="female"/>
    年齡:<input type = "text" name="age" value="20"/>
    </br>
    <input type = "submit" value="提交"/>
    </form>
    </body>
    </html>

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved