先後臺亂碼問題本身因爲也看過相關博客介紹過解決方法,可是本身本地測試後亂碼發生的略有不一樣,故在此做出總結,並附上本身的環境html
開發環境idea2019.3,tomcat8, windows7前端
使用chrome瀏覽器進行測試java
1.前臺向後臺傳送中文字符的狀況介紹:web
前臺代碼jsp文件spring
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 3 <form action="requestPost.do" method="post"> 4 用戶名:<input type="text" name="userName"/> 5 <input type="submit" value="post方式提交表單"> 6 </form> 7 8 <form action="requestGet.do" method="get"> 9 用戶名:<input type="text" name="userName"/> 10 <input type="submit" value="get方式提交表單"> 11 </form>
後臺代碼servletchrome
1 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 2 3 //獲取servletPath 4 String servletPath = request.getServletPath(); 5 //去除路徑名後綴名中的.do 6 String methodName = servletPath.substring(1, servletPath.length()-3); 7 try { 8 //利用反射獲取methodName對應的方法 9 Method method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); 10 //利用反射調用相應的方法 11 method.invoke(this, request, response); 12 } catch (Exception e) { 13 e.printStackTrace(); 14 response.sendRedirect("error.jsp"); 15 } 16 } 17 18 19 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 20 // TODO Auto-generated method stub 21 doGet(request, response); 22 }
1 private void requestGet(HttpServletRequest request, HttpServletResponse response){ 2 System.out.println("requestGet"); 3 4 String userName = request.getParameter("userName"); 5 System.out.println("直接獲取用戶名: "+userName); 6 try { 7 request.setCharacterEncoding("UTF-8"); 8 userName = request.getParameter("userName"); 9 System.out.println("設置utf-8編碼: "+userName); 10 11 userName = new String(userName.getBytes("ISO8859-1"), "utf-8"); 12 System.out.println("先ISO8859-1接收數據,後轉UTF-8編碼: "+ userName); 13 14 // response.setHeader("content-type", "text/html; charset=UTF-8"); 15 // response.getWriter().write(userName); 16 } catch (IOException e) { 17 e.printStackTrace(); 18 } 19 20 } 21
結果:windows
requestGet
直接獲取用戶名: 小紅
設置utf-8編碼: 小紅
先ISO8859-1接收數據,後轉UTF-8編碼: ??
1 private void requestPost(HttpServletRequest request, HttpServletResponse response){ 2 System.out.println("requestPost"); 3 String userName = request.getParameter("userName"); 4 System.out.println("直接獲取用戶名: "+userName); 5 try { 6 request.setCharacterEncoding("UTF-8"); 7 userName = request.getParameter("userName"); 8 System.out.println("設置utf-8編碼: "+userName); 9 10 userName = new String(userName.getBytes("ISO8859-1"), "utf-8"); 11 System.out.println("先ISO8859-1接收數據,後轉UTF-8編碼: "+ userName); 12 13 // response.setHeader("content-type", "text/html; charset=UTF-8"); 14 // response.getWriter().write(userName); 15 } catch (IOException e) { 16 e.printStackTrace(); 17 } 18 19 }
結果:數組
requestPost
直接獲取用戶名: ?°????
設置utf-8編碼: ?°????
先ISO8859-1接收數據,後轉UTF-8編碼: 小明
從以上結果能夠看出,對於前臺的get請求方式,後臺不須要對其對任何操做,中文字符不會出現亂碼狀況;瀏覽器
相反,對於post請求方式,後臺須要將先使用先tomcat
ISO8859-1接收數據,後轉UTF-8編碼
才能保證中文不亂碼。
另外,若是在web.xml中設置字符編碼,則無論是post仍是get皆不用作任何處理,下面的設置是防止前端輸入的數據到了後臺發生亂碼現象。
1 <filter> 2 <filter-name>encoding-filter</filter-name> 3 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 4 <init-param> 5 <param-name>encoding</param-name> 6 <param-value>UTF-8</param-value> 7 </init-param> 8 <init-param> 9 <param-name>forceEncoding</param-name> 10 <param-value>true</param-value> 11 </init-param> 12 </filter> 13 <filter-mapping> 14 <filter-name>encoding-filter</filter-name> 15 <url-pattern>*.do</url-pattern> 16 </filter-mapping>
2.後臺向前臺輸出帶有中文字符的亂碼現象:
前臺代碼:
1 <a href="query.do">Query</a><br/> 2 <a href="delete.do">Delete</a><br/> 3 <a href="update.do">update</a><br/>
後臺代碼servlet:
1 private void update(HttpServletRequest request, HttpServletResponse response){ 2 System.out.println("update"); 3 try { 4 /* 5 * 當輸出數字時,須要將該數字轉換成字符串形式,而後轉化成字節數組進行輸出 6 * 因此,當但願服務器輸出什麼瀏覽器就能看到什麼,那麼服務器端都要以字符串 7 * 的形式進行輸出 8 * */ 9 10 response.setHeader("content-type", "text/html; charset=UTF-8"); 11 //response.getOutputStream().write(1);//前臺顯示不出1 12 response.getOutputStream().write((1+"").getBytes("UTF-8")); 13 } catch (IOException e) { 14 e.printStackTrace(); 15 } 16 } 17 18 private void delete(HttpServletRequest request, HttpServletResponse response){ 19 System.out.println("delete"); 20 try { 21 /* 22 *使用outputStream輸出中文注意事項: 23 * 在服務端,數據以哪一個碼錶輸出,那麼就要控制客戶端以相應的碼錶打開, 24 * 好比response.getOutputStream().write("刪除操做".getBytes("UTF-8"));//使用 25 * outputStream流向客戶端瀏覽器輸出中文,以utf-8的編碼進行輸出 26 * 此時就要控制客戶端瀏覽器以utf-8的編碼打開,不然前臺顯示時會出現中文亂碼 27 * 可經過設置響應頭控制瀏覽器的行爲解決亂碼問題: 28 * response.setHeader("content-type", "text/html; charset=UTF-8"); 29 * 經過設置響應頭控制瀏覽器以utf-8的編碼顯示數據 30 * */ 31 response.setHeader("content-type", "text/html; charset=UTF-8"); 32 /*getbytes()是一個將字符轉換成字節數組的過程,這個過程必定會查找碼錶,若是是 33 中文的操做系統環境,默認就是查找GB2312的碼錶,將字符轉換成字節數組的過程就是將 34 中文轉換成GB2312的碼錶上對應的數字, 35 好比:"中" 在GB2312的碼錶上對應的數字是98 36 getbytes()若是不帶參數,那麼就會根據操做系統的語言環境來選擇轉換碼錶,若是是中文操做系統, 37 那麼就使用GB2312的碼錶 38 */ 39 response.getOutputStream().write("刪除操做".getBytes("UTF-8")); 40 } catch (IOException e) { 41 e.printStackTrace(); 42 } 43 } 44 45 private void query(HttpServletRequest request, HttpServletResponse response){ 46 System.out.println("query"); 47 try { 48 /* 49 * 與outputStream相同 50 * 設置響應頭來控制瀏覽器以指定的字符編碼進行顯示 51 * response.setHeader("content-type", "text/html; charset=UTF-8"); 52 * 它的等價寫法: 53 * response.getWriter().write("<meta http-equiv='content-type' content='text/html'; charset='UTF-8'/>"); 54 * */ 55 response.setHeader("content-type", "text/html; charset=UTF-8"); 56 response.getWriter().write("查詢操做"); 57 } catch (IOException e) { 58 e.printStackTrace(); 59 } 60 }
後臺向前臺輸出中文時,無論是使用outputStream仍是PrintWriter,只須要添加一句
response.setHeader("content-type", "text/html; charset=UTF-8");
就可以解決亂碼問題,同時這裏也順便介紹了若是向前臺輸出數字時,須要將其轉換成字符串再輸出,不然會顯示不正常。
本文主要參考的孤傲蒼狼博客相關內容,可是本身親自在本身電腦上測試的狀況和其中有點不同,具體差別緣由不太清楚。