Java Web 編碼問題三:URL和URI以及QueryString的編碼問題

    在問題以前咱們先來了解一下什麼是URL,URI以及QueryString,以下圖1所示:html

1URL-URI-QueryStringjava

URL:是全球資源定位符的英文縮寫,如上 其中localhost:是指Domain(IP或者主機名),8080:是端口
Web服務通常是80,8080是本身測試是候用的,避免和和瀏覽器的端口衝突。
ROOT:是ContentPath,就是虛擬路徑,若是是tomcat服務器對象的是servlet.xml配置文件中的<Context path=」/ROOT」 />
若是沒有配置這一個tomcat默認的是path就是ROOT。
Servlet:就是ServletPath的信息,就是和web.xml中的<url-pattern>相對應的,用來查找Servlet。
GetSpecialInfos:就是要請求的文件了。
category=土特產:就是QueryString,至關於用get提交的參數。
URI(Universal Resource Identifier, 簡稱"URI"):是Web上可用的每種資源。經過URI進行定位。通常是服務器本身使用。

       知道了URL,URI和QueryString,咱們就能夠來試一試他們的編碼問題了,看下面一個Java Servlet程序:web

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.wl.util.SpecialInfoToJson;
import org.wl.util.StringUtils;
 
/**
 * Servlet implementation class GetSpecialInfo
 */
public class GetSpecialInfos extends HttpServlet {
         private static final long serialVersionUID = 1L;
    private static final Logger log = LogManager.getLogger(); 
    /**
     * @see HttpServlet#HttpServlet()
     */
    public GetSpecialInfos() {
        super();
        // TODO Auto-generated constructor stub
    }
 
         /**
          * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
          */
         protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                   doPost(request, response);
         }
 
         /**
          * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
          */
         protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                   response.setContentType("text/html;charset=utf-8");
                  
                   log.info(request.getCharacterEncoding());
                   request.setCharacterEncoding("utf-8");
                   log.info(request.getCharacterEncoding());
                  log.info(request.getQueryString());
                   System.out.println();
                   String category = request.getParameter("category");
                   if(StringUtils.isNullOrEmpty(category))
                   {
                            response.getWriter().append("category is null");
                            return;
                   }
                   log.info(category);
//               category = new String(category.getBytes("iso-8859-1"),"utf-8");
//               category = new String(category.getBytes("iso-8859-1"),"gbk");
//               log.info(category);
                   response.getWriter().append(SpecialInfoToJson.getCategoryInfo(category));
         }
}

     我用的是tomcat服務器,若是要進行簡單測試,能夠把log語句換爲System.out.println();輸出直接到控制檯,避免配置log4j2。能夠把最後的response.getWriter().append(SpecialInfoToJson.getCategoryInfo(category));去掉。apache

直接經過瀏覽器訪問:http://localhost:8080/market/GetSpecialInfos?category=土特產數組

把market換爲您的工程名字。瀏覽器

經過IE瀏覽器訪問控制檯的輸出:tomcat

null服務器

22:02:58.492 INFO  org.wl.app.GetSpecialInfos 44 doPost - utf-8app

22:02:58.492 INFO  org.wl.app.GetSpecialInfos 45 doPost - category=ÍÁÌزúpost

22:02:58.492 INFO  org.wl.app.GetSpecialInfos 52 doPost - ÍÁÌزú

經過Firefox或者Google瀏覽器訪問控制檯的輸出(忽略了部分輸出):

null

utf-8

category=%E5%9C%9F%E7%89%B9%E4%BA%A7

土特产

如今還暫時猜想不出是什麼意思,沒有關係咱們先把把被註釋掉的代碼        

category = new String(category.getBytes("iso-8859-1"),"utf-8");去掉註釋,在從新運行。

發現用Firefox或者Google瀏覽器訪問的控制檯的輸出爲:

null

utf-8

category=%E5%9C%9F%E7%89%B9%E4%BA%A7

土特产

土特產

用IE訪問控制檯的輸出爲:

null

22:43:56.614 INFO  org.wl.app.GetSpecialInfos 44 doPost - utf-8

22:43:56.614 INFO  org.wl.app.GetSpecialInfos 45 doPost - category=ÍÁÌزú

22:43:56.614 INFO  org.wl.app.GetSpecialInfos 53 doPost - ÍÁÌزú

22:43:56.614 INFO  org.wl.app.GetSpecialInfos 56 doPost - ���ز

    說明Firefox和Google對於QueryString的編碼格式是utf-8。而IE對於QueryString的編碼確定不是utf-8。

    咱們在把category = new String(category.getBytes("iso-8859-1"),"utf-8");註釋掉。

    把 category = new String(category.getBytes("iso-8859-1"),"gbk");的註釋去掉。從新運行,而後經過IE

FirefoxGoogle瀏覽器來訪問。

    控制檯的輸出爲IE正常了,FirefoxGoogle亂碼了。說明IE用的是gbk或者以其兼容的編碼方式(gb2312等)

QueryString進行編碼的。

    下面咱們從新來看一看這一句:category = new String(category.getBytes("iso-8859-1"),"utf-8");

    咱們爲何要category.getBytes("iso-8859-1"),用iso-8859-1這一編碼來獲得字節數組。是由於對於QueryString來講,若是沒有中請求頭(header)中設置contentType,在tomcatservlet.xml配置文件中也沒有設置<Connector URIEncoding=」utf-8」 uesBodyEncodingForURI=」true」 />這樣的配置。那麼就會使用iso-8859-1QueryString進行編碼。咱們的request.setCharacterEncoding("utf-8");這一句一直輸出的是null,說明瀏覽器並無設置contentType。咱們也沒有配置服務器,因此就使用的是iso-8859-1QueryString進行的編碼。

    同時咱們發現request.setCharacterEncoding("utf-8");這一句好像沒有用,對於get方式提交的(包括,url參數,和表單經過get方法提交)的確沒有做用,可是對於post提交的是用用的。若是有興趣能夠試一試。

注意:必須同時設定了contentType和uesBodyEncodingForURI=」true」纔會使用contentType的方式對QueryString就像解碼。

相關文章
相關標籤/搜索