tomcat中的get、post區別,tomcatgetpost區別
最近做一個項目,前台傳到背景資料是亂碼。看著代碼應該是正確的,但是就是有問題,然後請教了旁邊的老司機才找到問題是什麼。話不多說,下面是類比情景的代碼,其實也很簡單,前台一個form表單,post 方法,然後傳一個中文字串到servlet。 如果第一次調用request,不是設定字元編 碼(req.setCharacterEncoding("utf-8");)而是調用其他的request 方法,那麼設定的字元編碼不會成功。
前端模板:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title></head><body><form action="/post" method="post"> 使用者名稱<input type="text" name="name"> <input type="submit" value="提交"></form></body></html>
Java 代碼
package cn.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet("/post")public class TestPost extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String cmd = req.getParameter("cmd"); list(req, resp); } public void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); String name = null; if (req.getParameter("name") != null && !"".equals(req.getParameter("name"))) { name = req.getParameter("name"); System.out.println("name-------------------------->>>:" + name); } }}
如上代碼:request 首先調用 req.getParameter("cmd");然後再是 req.setCharacterEncoding("utf-8");出現的原因是request 在傳入的時候如果不設定req格式,在第一次調用req 的時候tomcat 會自動的給req 增加字元格式設定 ,後面再設定 req.setCharacterEncoding("utf-8")就會無效。
要修改就很簡單了①:把form 表單改為get
②: req.setCharacterEncoding("utf-8"); 聲明在第一行,或者filter 裡面做字元處理
③:
String name = req.getParameter("name");
byte[] nameBytes = name.getBytes("ISO-8859-1");
name = new String(nameBytes,"utf-8");
以下文章是摘自 http://my.oschina.net/looly/blog/287255?p=2&temp=1470195279778#blog-comments-list由來
在寫一個小小的表單提交功能的時候,出現了亂碼,很奇怪request上來的參數全部是亂碼,而從資料庫查詢出來的中文顯示到頁面正常,鎖定肯定是request對象那裡出了問題。後來經過排查,發現是我封裝的架構中出了問題,總結為在setCharacterEncoding方法之前,調用了getParameter方法,導致字元集改變失敗。沒看過Tomcat實現Servlet的源碼,貌似是一旦調用getParameter方法Request的參數就會全部被解析,從而再調用setCharacterEncoding就無效了。
原理解析
其實編碼問題本質還是兩點:
那麼我們就從這兩點入手解析。
瀏覽器請求
在點擊提交表單的那一刻,瀏覽器把表單內容封裝成一個Http請求,資料通過a=1&b=2這樣的形式直接請求伺服器,表單值會被瀏覽器最一次urlencode,對於不同的請求方式編碼不同:
Get和Post請求
瀏覽器會讀取頁面的編碼(頁面編碼會在Content-type頭中體現),用此編碼對錶單值做urlencode,那麼到伺服器的編碼方式就是你Content-Type裡的編碼。很多通過JS提交表單為了規避瀏覽器的urlencode帶來的編碼混淆,會對資料首先做一次urlencode,這樣在伺服器上做一次urldecode既可(因為js做完urlencode後內容為ASCII字元,所以這樣的字元無論瀏覽器用什麼編碼解碼出來都是一樣的)
AJAX請求
在Jquery中AJAX請求全部使用utf8編碼封裝請求,如果你的頁面和項目用的非utf8編碼,一定會出現亂碼
瀏覽器地址欄直接輸入帶參數的地址
這種情況就比較複雜,不同的瀏覽器編碼也不相同。Chrome之類的瀏覽器預設使用utf8編碼(urlencode),而IE則使用GBK(死變態IE!!!)。
伺服器端解碼
對於伺服器端我在此只討論Servlet。
Get請求
對於Get請求,有兩種方式解碼:
至於為什麼要使用getBytes("iso-8859-1"),是因為在你瀏覽器用某種編碼後,Servlet容器自作多情給你用iso-8859-1解碼了一下,如果你設定了URIEncoding="UTF-8"它就會用utf8給你解碼,運氣好你瀏覽器用的也是這種編碼,那解出來就直接用了,所以在ISO-8859-1的情況下你得再“原路返回”到二進位,重新用正確的編碼解碼一下。
Post請求和Ajax請求
Post請求就比較簡單一點了,同樣你可以使用Get請求中的方法2來解決,不過比較麻煩,這時候我們就可以使用Servlet裡的方法request.setCharacterEncoding方法設定你的解碼類型,例如你的頁面編碼是utf8,表單則urlencode成utf8了,那麼你在調用getParameter方法之前(記住,一定要之前!!在第一次調用getParameter之前!)使用setCharacterEncoding方法。 Ajax請求同理。
響應請求
響應也是相同道理,這回輪到伺服器做編碼,瀏覽器做解碼。只需要設定response.setCharacterEncoding,就會自動在回應標頭的Content-Type中加入charset=XXX,返回的內容就可以被正常解析啦~
我想我說的相對比較清楚了,網上很多解決亂碼的文章都只是講你加上某句代碼就會解決,這樣是不科學的,一定也要知道原理,也要知道每句代碼背後做了哪些工作。其實我們在操作HttpServlet對象的時候,本質上是對Http頭的一些資訊做修改。