tomcat中的get、post區別

最近作一個項目,前臺傳到後臺的數據是亂碼。看着代碼應該是正確的,可是就是有問題,而後請教了旁邊的老司機才找到問題是什麼。話很少說,下面是模擬情景的代碼,其實也很簡單,前臺一個form表單,post  方法,而後傳一箇中文字符串到servlet。 若是第一次調用request,不是設置字符編 碼(req.setCharacterEncoding("utf-8");)而是調用其餘的request 方法,那麼設置的字符編碼不會成功。html

 

前端模板:前端

<!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 代碼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")就會無效。ajax

要修改就很簡單了①:把form 表單改成get  數據庫

                       ②: req.setCharacterEncoding("utf-8"); 聲明在第一行,或者filter  裏面作字符處理瀏覽器

                       ③:  tomcat

                        String  name = req.getParameter("name");服務器

                       byte[] nameBytes = name.getBytes("ISO-8859-1");框架

                          name = new String(nameBytes,"utf-8");ide

         

 

如下文章是摘自

 http://my.oschina.net/looly/blog/287255?p=2&temp=1470195279778#blog-comments-list

由來

在寫一個小小的表單提交功能的時候,出現了亂碼,很奇怪request上來的參數所有是亂碼,而從數據庫查詢出來的中文顯示到頁面正常,鎖定確定是request對象那裏出了問題。後來通過排查,發現是我封裝的框架中出了問題,總結爲在setCharacterEncoding方法以前,調用了getParameter方法,致使字符集改變失敗。沒看過Tomcat實現Servlet的源碼,貌似是一旦調用getParameter方法Request的參數就會所有被解析,從而再調用setCharacterEncoding就無效了。

原理解析

其實編碼問題本質仍是兩點:

  1. 瀏覽器在封裝Http請求的時候的編碼和服務器在解析Http請求編碼不一致
  2. 服務器返回數據的時候編碼和瀏覽器解析不一樣。

那麼咱們就從這兩點入手解析。

瀏覽器請求

在點擊提交表單的那一刻,瀏覽器把表單內容封裝成一個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請求,有兩種方式解碼:

  1. 在Servlet容器中設置,例如Tomcat設置URIEncoding="UTF-8",就會對Get請求用utf8解碼(貌似Tomcat7會報無效,具體解決請百度,反正我不一樣這種方法)
  2. String name = new String(request.getParameter("name").getBytes("iso-8859-1"),"GBK"));第一個編碼就是你Servlet容器(例如Tomcat)裏設置的編碼,默認iso-8859-1,第二個參數就是你瀏覽器使用的編碼格式。若是你用表單提交,那這個編碼就是頁面的編碼(Content-Type裏的charset=XXX),若是你直接用瀏覽器地址欄裏敲,恭喜你,你得判斷userAgent來使用不一樣編碼了。這也是我爲啥不提倡第一種方式,由於它遇到瀏覽器直接敲出來的參數就很是不靈活。

至於爲何要使用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頭的一些信息作修改。

相關文章
相關標籤/搜索