JAVA WEB 中的編碼分析
Table of Contents
1 常見編碼格式的區別
1.1 爲何要編碼
1.2 常見編碼格式
2 須要編碼的場景
2.1 磁盤IO
2.2 內存中
- 字符和字節之間的轉換demo
- 內存字符佔用字節數驗證
2.3 網絡IO
可是仍是強烈的不建議使用操做系統的默認編碼,由於這樣,你的應用程序的編碼格式就和運行環境綁定起來了,在跨環境下極可能出現亂碼問題。 genesys sdk 的demo 示例,怎麼來解決的? css
2.4 java 中編解碼的原理
2.4.1 編碼類圖
2.4.2 編碼時序圖
2.4.3 各類編碼格式編碼後的字節數組示例
3 JAVA WEB 中涉及的編碼問題
3.1 HTTP請求中涉及到編碼的地方
3.2 URL中的編碼
- ServletPath和PathInfo中的中文
- QueryString中的中文
public void service(org.apache.coyote.Request req, org.apache.coyote.Response res) throws Exception { Request request = (Request) req.getNote(ADAPTER_NOTES); Response response = (Response) res.getNote(ADAPTER_NOTES); if (request == null) { // Create objects request = connector.createRequest(); request.setCoyoteRequest(req); response = connector.createResponse(); response.setCoyoteResponse(res); // Link objects request.setResponse(response); response.setRequest(request); // Set as notes req.setNote(ADAPTER_NOTES, request); res.setNote(ADAPTER_NOTES, response); // Set query string encoding req.getParameters().setQueryStringEncoding (connector.getURIEncoding()); }
因此,結論是,queryStringEncoding編碼的優先級是,第一是隨contentType(設置了useBodyEncodingForURI),第二隨URIEncoding(沒有設置useBodyEncodingForURI),第三則是默認編碼(即沒有設置contentType,設置了useBodyEncodingForURI=true)
protected void parseParameters() { parametersParsed = true; Parameters parameters = coyoteRequest.getParameters(); boolean success = false; try { // Set this every time in case limit has been changed via JMX parameters.setLimit(getConnector().getMaxParameterCount()); // getCharacterEncoding() may have been overridden to search for // hidden form field containing request encoding String enc = getCharacterEncoding(); boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI(); if (enc != null) { parameters.setEncoding(enc); if (useBodyEncodingForURI) { parameters.setQueryStringEncoding(enc); } } else { parameters.setEncoding (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING); if (useBodyEncodingForURI) { parameters.setQueryStringEncoding (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING); } }
<Connector executor="tomcatThreadPool" protocol="org.apache.coyote.http11.Http11NioProtocol" port="8080" URIEncoding="UTF-8" useBodyEncodingForURI="true" compression="off" enableLookups="false" maxKeepAliveRequests="20" bufferSize="8192" connectionTimeout="5000" redirectPort="8443" server="DPServer"/>
3.3 HTTP header 中的編碼
3.4 POST 的編碼
/** * Get the character encoding used for this request. */ public String getCharacterEncoding() { if (charEncoding != null) { return charEncoding; } charEncoding = getCharsetFromContentType(getContentType()); return charEncoding; }