request接收表單提交數據及其中文參數亂碼問題


一、request接收表單提交數據:

 

  • getParameter(String)方法(常用)
  • getParameterValues(String name)方法(常用)
  • getParameterMap()方法(編寫框架時常用)

 

比如現在有如下的form表單

 

復制代碼
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  3 <html>  4 <head>  5 <title>Html的Form表單元素</title>  6 </head>  7 <fieldset style="width:500px;">  8 <legend>Html的Form表單元素</legend>  9 <!--form表單的action屬性規定當提交表單時,向何處發送表單數據,method屬性指明表單的提交方式,分為get和post,默認為get--> 10 <form action="${pageContext.request.contextPath}/servlet/RequestDemo03" method="post"> 11 <!--輸入文本框,SIZE表示顯示長度,maxlength表示最多輸入長度--> 12 編&nbsp;&nbsp;號(文本框): 13 <input type="text" name="userid" value="NO." size="2" maxlength="2"><br> 14 <!--輸入文本框,通過value指定其顯示的默認值--> 15 用戶名(文本框):<input type="text" name="username" value="請輸入用戶名"><br> 16 <!--密碼框,其中所有輸入的內容都以密文的形式顯示--> 17 密&nbsp;&nbsp;碼(密碼框): 18 <!--&nbsp;表示的是一個空格--> 19 <input type="password" name="userpass" value="請輸入密碼"><br> 20 <!--單選按鈕,通過checked指定默認選中,名稱必須一樣,其中value為真正需要的內容--> 21 性&nbsp;&nbsp;別(單選框): 22 <input type="radio" name="sex" value="男" checked>23 <input type="radio" name="sex" value="女">女<br> 24 <!--下拉列表框,通過<option>元素指定下拉的選項--> 25 部&nbsp;&nbsp;門(下拉框): 26 <select name="dept"> 27 <option value="技術部">技術部</option> 28 <option value="銷售部" SELECTED>銷售部</option> 29 <option value="財務部">財務部</option> 30 </select><br> 31 <!--復選框,可以同時選擇多個選項,名稱必須一樣,其中value為真正需要的內容--> 32 興&nbsp;&nbsp;趣(復選框): 33 <input type="checkbox" name="inst" value="唱歌">唱歌 34 <input type="checkbox" name="inst" value="游泳">游泳 35 <input type="checkbox" name="inst" value="跳舞">跳舞 36 <input type="checkbox" name="inst" value="編程" checked>編程 37 <input type="checkbox" name="inst" value="上網">上網 38 <br> 39 <!--大文本輸入框,寬度為34列,高度為5行--> 40 說&nbsp;&nbsp;明(文本域): 41 <textarea name="note" cols="34" rows="5"> 42 </textarea> 43 <br> 44 <!--隱藏域,在頁面上無法看到,專門用來傳遞參數或者保存參數--> 45 <input type="hidden" name="hiddenField" value="hiddenvalue"/> 46 <!--提交表單按鈕,當點擊提交后,所有填寫的表單內容都會被傳輸到服務器端--> 47 <input type="submit" value="提交(提交按鈕)"> 48 <!--重置表單按鈕,當點擊重置后,所有表單恢復原始顯示內容--> 49 <input type="reset" value="重置(重置按鈕)"> 50 </form> 51 <!--表單結束--> 52 </fieldset> 53 </body> 54 <!--完結標記--> 55 </html> 56 <!--完結標記-->
復制代碼

 

  在Form表單中填寫數據,然后提交到RequestDemo03這個Servlet進行處理,填寫的表單數據如下:

 

  

 

在服務器端使用getParameter方法和getParameterValues方法接收表單參數,代碼如下:

 

復制代碼
 1 package gacl.request.study;  2 import java.io.IOException;  3 import java.text.MessageFormat;  4 import javax.servlet.ServletException;  5 import javax.servlet.http.HttpServlet;  6 import javax.servlet.http.HttpServletRequest;  7 import javax.servlet.http.HttpServletResponse;  8 /**  9  * @author gacl 10  * 獲取客戶端通過Form表單提交上來的參數 11 */ 12 public class RequestDemo03 extends HttpServlet { 13 14 public void doGet(HttpServletRequest request, HttpServletResponse response) 15 throws ServletException, IOException { 16 //客戶端是以UTF-8編碼提交表單數據的,所以需要設置服務器端以UTF-8的編碼進行接收,否則對於中文數據就會產生亂碼 17 request.setCharacterEncoding("UTF-8"); 18 /** 19  * 編&nbsp;&nbsp;號(文本框): 20  <input type="text" name="userid" value="NO." size="2" maxlength="2"> 21 */ 22 String userid = request.getParameter("userid");//獲取填寫的編號,userid是文本框的名字,<input type="text" name="userid"> 23 /** 24  * 用戶名(文本框):<input type="text" name="username" value="請輸入用戶名"> 25 */ 26 String username = request.getParameter("username");//獲取填寫的用戶名 27 /** 28  * 密&nbsp;&nbsp;碼(密碼框):<input type="password" name="userpass" value="請輸入密碼"> 29 */ 30 String userpass = request.getParameter("userpass");//獲取填寫的密碼 31 String sex = request.getParameter("sex");//獲取選中的性別 32 String dept = request.getParameter("dept");//獲取選中的部門 33 //獲取選中的興趣,因為可以選中多個值,所以獲取到的值是一個字符串數組,因此需要使用getParameterValues方法來獲取 34 String[] insts = request.getParameterValues("inst"); 35 String note = request.getParameter("note");//獲取填寫的說明信息 36 String hiddenField = request.getParameter("hiddenField");//獲取隱藏域的內容 37 38 String instStr=""; 39 /** 40  * 獲取數組數據的技巧,可以避免insts數組為null時引發的空指針異常錯誤! 41 */ 42 for (int i = 0; insts!=null && i < insts.length; i++) { 43 if (i == insts.length-1) { 44 instStr+=insts[i]; 45 }else { 46 instStr+=insts[i]+","; 47  } 48  } 49 50 String htmlStr = "<table>" + 51 "<tr><td>填寫的編號:</td><td>{0}</td></tr>" + 52 "<tr><td>填寫的用戶名:</td><td>{1}</td></tr>" + 53 "<tr><td>填寫的密碼:</td><td>{2}</td></tr>" + 54 "<tr><td>選中的性別:</td><td>{3}</td></tr>" + 55 "<tr><td>選中的部門:</td><td>{4}</td></tr>" + 56 "<tr><td>選中的興趣:</td><td>{5}</td></tr>" + 57 "<tr><td>填寫的說明:</td><td>{6}</td></tr>" + 58 "<tr><td>隱藏域的內容:</td><td>{7}</td></tr>" + 59 "</table>"; 60 htmlStr = MessageFormat.format(htmlStr, userid,username,userpass,sex,dept,instStr,note,hiddenField); 61 62  response.setCharacterEncoding("UTF-8");//設置服務器端以UTF-8編碼輸出數據到客戶端 63 response.setContentType("text/html;charset=UTF-8");//設置客戶端瀏覽器以UTF-8編碼解析數據 64 response.getWriter().write(htmlStr);//輸出htmlStr里面的內容到客戶端瀏覽器顯示 65  } 66 67 public void doPost(HttpServletRequest request, HttpServletResponse response) 68 throws ServletException, IOException { 69  doGet(request, response); 70  } 71 }
復制代碼

 

運行結果如下:

 

  

在服務器端使用getParameterMap方法接收表單參數,代碼如下:

復制代碼
 1 //request對象封裝的參數是以Map的形式存儲的  2 Map<String, String[]> paramMap = request.getParameterMap();  3 for(Map.Entry<String, String[]> entry :paramMap.entrySet()){  4 String paramName = entry.getKey();  5 String paramValue = "";  6 String[] paramValueArr = entry.getValue();  7 for (int i = 0; paramValueArr!=null && i < paramValueArr.length; i++) {  8 if (i == paramValueArr.length-1) {  9 paramValue+=paramValueArr[i]; 10 }else { 11 paramValue+=paramValueArr[i]+","; 12  } 13  } 14 System.out.println(MessageFormat.format("{0}={1}", paramName,paramValue)); 15 }
復制代碼

運行結果如下:

  

二、request接收表單提交數據的中文參數亂碼問題:

 

3.1、以POST方式提交表單中文參數的亂碼問題

 

例如有如下的form表單頁面:

 

復制代碼
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  2  3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  4 <html>  5 <head>  6 <title>request接收中文參數亂碼問題</title>  7 </head>  8  9 <body> 10 <form action="<%=request.getContextPath()%>/servlet/RequestDemo04" method="post"> 11 用戶名:<input type="text" name="userName"/> 12 <input type="submit" value="post方式提交表單"> 13 </form> 14 </body> 15 </html>
復制代碼

 

  

 

  此時在服務器端接收中文參數時就會出現中文亂碼,如下所示:

 

  

 

3.2、post方式提交中文數據亂碼產生的原因和解決辦法

 

  

 

  可以看到,之所以會產生亂碼,就是因為服務器和客戶端溝通的編碼不一致造成的,因此解決的辦法是:在客戶端和服務器之間設置一個統一的編碼,之后就按照此編碼進行數據的傳輸和接收。

 

  由於客戶端是以UTF-8字符編碼將表單數據傳輸到服務器端的,因此服務器也需要設置以UTF-8字符編碼進行接收,要想完成此操作,服務器可以直接使用從ServletRequest接口繼承而來的"setCharacterEncoding(charset)"方法進行統一的編碼設置。修改后的代碼如下:

 

復制代碼
1 public void doPost(HttpServletRequest request, HttpServletResponse response) 2 throws ServletException, IOException { 3 /** 4  * 客戶端是以UTF-8編碼傳輸數據到服務器端的,所以需要設置服務器端以UTF-8的編碼進行接收,否則對於中文數據就會產生亂碼 5 */ 6 request.setCharacterEncoding("UTF-8"); 7 String userName = request.getParameter("userName"); 8 System.out.println("userName:"+userName); 9 }
復制代碼

 

  使用request.setCharacterEncoding("UTF-8");設置服務器以UTF-8的編碼接收數據后,此時就不會產生中文亂碼問題了,如下所示:

 

  

 

3.3、以GET方式提交表單中文參數的亂碼問題

 

例如有如下的form表單頁面:

 

復制代碼
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  2  3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  4 <html>  5 <head>  6 <title>request接收中文參數亂碼問題</title>  7 </head>  8  9 <body> 10 <form action="${pageContext.request.contextPath}/servlet/RequestDemo04" method="get"> 11 姓名:<input type="text" name="name"/> 12 <input type="submit" value="get方式提交表單"> 13 </form> 14 </body> 15 </html>
復制代碼

 

  

 

  此時在服務器端接收中文參數時就會出現中文亂碼,如下所示:

 

  

 

  那么這個中文亂碼問題又該如何解決呢,是否可以通過request.setCharacterEncoding("UTF-8");設置服務器以UTF-8的編碼進行接收這種方式來解決中文亂碼問題呢,注意,對於以get方式傳輸的中文數據,通過request.setCharacterEncoding("UTF-8");這種方式是解決不了中文亂碼問題,如下所示:

 

  

 

3.4、get方式提交中文數據亂碼產生的原因和解決辦法

 

  對於以get方式傳輸的數據,request即使設置了以指定的編碼接收數據也是無效的(至於為什么無效我也沒有弄明白),默認的還是使用ISO8859-1這個字符編碼來接收數據,客戶端以UTF-8的編碼傳輸數據到服務器端,而服務器端的request對象使用的是ISO8859-1這個字符編碼來接收數據,服務器和客戶端溝通的編碼不一致因此才會產生中文亂碼的。解決辦法:在接收到數據后,先獲取request對象以ISO8859-1字符編碼接收到的原始數據的字節數組,然后通過字節數組以指定的編碼構建字符串,解決亂碼問題。代碼如下:

 

復制代碼
 1 public void doGet(HttpServletRequest request, HttpServletResponse response)  2 throws ServletException, IOException {  3 /**  4  *  5  * 對於以get方式傳輸的數據,request即使設置了以指定的編碼接收數據也是無效的,默認的還是使用ISO8859-1這個字符編碼來接收數據  6 */  7 String name = request.getParameter("name");//接收數據  8 name =new String(name.getBytes("ISO8859-1"), "UTF-8");//獲取request對象以ISO8859-1字符編碼接收到的原始數據的字節數組,然后通過字節數組以指定的編碼構建字符串,解決亂碼問題  9 System.out.println("name:"+name); 10 }
復制代碼

 

運行結果如下:

 

 

3.5、以超鏈接形式傳遞中文參數的亂碼問題

 

  客戶端想傳輸數據到服務器,可以通過表單提交的形式,也可以通過超鏈接后面加參數的形式,例如:

 

1 <a href="${pageContext.request.contextPath}/servlet/RequestDemo05?userName=gacl&name=徐達沛">點擊</a>

 

  點擊超鏈接,數據是以get的方式傳輸到服務器的,所以接收中文數據時也會產生中文亂碼問題,而解決中文亂碼問題的方式與上述的以get方式提交表單中文數據亂碼處理問題的方式一致,如下所示:

 

1 String name = request.getParameter("name"); 2 name =new String(name.getBytes("ISO8859-1"), "UTF-8");

 

  另外,需要提的一點就是URL地址后面如果跟了中文數據,那么中文參數最好使用URL編碼進行處理,如下所示:

 

1 <a href="${pageContext.request.contextPath}/servlet/RequestDemo05?userName=gacl&name=<%=URLEncoder.encode("徐達沛", "UTF-8")%>">點擊</a>

 

3.6、提交中文數據亂碼問題總結

 

  1、如果提交方式為post,想不亂碼,只需要在服務器端設置request對象的編碼即可,客戶端以哪種編碼提交的,服務器端的request對象就以對應的編碼接收,比如客戶端是以UTF-8編碼提交的,那么服務器端request對象就以UTF-8編碼接收(request.setCharacterEncoding("UTF-8"))

 

  2、如果提交方式為get,設置request對象的編碼是無效的,request對象還是以默認的ISO8859-1編碼接收數據,因此要想不亂碼,只能在接收到數據后再手工轉換,步驟如下:

 

  1).獲取獲取客戶端提交上來的數據,得到的是亂碼字符串,data="???è?????"

 

   String data = request.getParameter("paramName"); 

 

  2).查找ISO8859-1碼表,得到客戶機提交的原始數據的字節數組

 

   byte[] source = data.getBytes("ISO8859-1"); 

 

  3).通過字節數組以指定的編碼構建字符串,解決亂碼

 

   data = new String(source, "UTF-8"); 

 

       或

  String data = request.getParameter("paramName");

  data=new String(data.getBytes("ISO8859-1"), "UTF-8");

  通過字節數組以指定的編碼構建字符串,這里指定的編碼是根據客戶端那邊提交數據時使用的字符編碼來定的,如果是GB2312,那么就設置成data = new String(source, "GB2312"),如果是UTF-8,那么就設置成data = new String(source, "UTF-8")

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM