整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          java之學習篇-亂碼問題匯總

          java之學習篇-亂碼問題匯總

          天突然想到之前的一個項目,是和另一個公司合作,我提供后臺,對方寫小程序調用我的接口,我本地測試好接口后,是沒有問題的,然后部署到對方服務器(windows系統),接著就是出先各種各樣的亂碼問題,在這里匯總記錄下,以便后面學習。

          java亂碼出現的問題有很多,這里主要記錄下tomcat,log4j,mysql,jsp,html,http(get,post請求亂碼處理)。常見的問題可能是tomcat,http請求亂碼問題了,至于jsp和html的亂碼問題就很簡單了,相信大家也知道,我也就不多說了,首先來說下tomcat的亂碼問題,

          一個是程序需要發送http GET請求到服務器,請求的參數中包含了中文字符。程序中參數為UTF-8格式,且經過了UTF-8 URL編碼再發送。使用的tomcat服務器,但服務器端后臺程序中取到的參數的中文是亂碼。

          解決辦法:修改Tomcat的Server.xml,在Connector標簽中加上URLEncoding參數。

          <Connector port="8080" maxThreads="150" minSpareThreads="25"
          maxSpareThreads="75" enableLookups="false" redirectPort="8443"
          acceptCount="100" debug="99" connectionTimeout="20000"
          disableUploadTimeout="true" URIEncoding="UTF-8"/>
          

          另一個是tomcat控制臺打印亂碼,程序中輸出到tomcat控制臺的中文信息亂碼了,

          解決辦法:打開文件/tomcat/bin/catalina.bat,然后設置set JAVA_OPTS=的內容中添加選項-Dfile.encoding=UTF-8即可,當然,我不敢包證,但是我的就是這么處理然后就可以了。

          然后是log4j的日志打印亂碼,這個亂碼也是打印在tomcat控制臺的時候亂碼,但是日志文件卻不會,而且我本地測試的時候打印也不會亂碼

          而且我配置的也是utf-8,這個曾經讓我惱火好久,后面我偶然在一篇博客上發現,說有些服務器你配utf-8是不行的,他的是編碼就是GBK,我就權當試試,沒想到還真是這個問題,這也是讓我很無語,,,,

          然后就是http請求的亂碼,我這個亂碼問題是我在shiro判斷是否登錄的時候,因為我是前后端分離,所以我shiro判斷未登錄的時候,是返回狀態碼和提示信息,而不是跳轉登錄頁面,我用response返回中文提示信息是,結果返回的是亂碼,可是我明明設置了

          res.setCharacterEncoding("utf-8");
          

          可是到前端頁面的時候還是亂碼了,這讓我很費解,后面我仔細想了下,我服務端是設置了返回utf-8的編碼,但是瀏覽器是用utf-8去解析的嗎?后面去查了下還要加一條配置,

          res.setContentType("text/html;charset=utf-8");
          

          之前知道有這個配置,但是一直不知道有什么區別,今天算是明白了一點,這個就是告訴瀏覽器,你要用什么編碼去解析這個數據。

          最后一個是mysql 中文的亂碼了,這個著實讓我煩惱了好久,我去網上查了,說建表的時候要設置utf-8的編碼,可是我在新建數據庫的時候就設置了默認就是utf-8的編碼,然后我說要配置數據庫的默認編碼,修改mysql配置文件/etc/my.cnf。

          [mysqld]
          character-set-server=utf8 
          [client]
          default-character-set=utf8 
          [mysql]
          default-character-set=utf8
          

          我設置好這個以后,終于不會亂了,但是,,保存進去的中文居然全部變成了???號,于是又去奔波了,

          通過這個命令,我們可以看到,我們服務端居然還不是utf-8???

          這讓我很傷,終于,尋的良方,

          只要在數據庫properties文件的連接信息里加兩個參數

          ?useUnicode=true&characterEncoding=utf-8
          

          就可以了,唉,真是一波三折啊,

          真是與服務器斗,其樂無窮;與數據庫斗,其樂無窮;與瀏覽器斗,其樂無窮啊

          pache Derby 是一個開源的完全使用 Java 語言實現的嵌入式關系型數據庫。JDK歷史版本中曾經包含了 Derby 版本,叫做 Java DB,但目前 JDK 中已經不再默認包含了。

          官網主頁:https://db.apache.org/derby/

          在更新JDK到21/22版本后,同樣也是出現使用控制臺執行SQL腳本出現漢字亂碼。

          運行環境

          D:\db-derby-10\bin>sysinfo

          ------------------ Java 信息 ------------------
          Java 版本:        21.0.2
          Java 供應商:      Oracle Corporation
          Java 主目錄:      D:\JDK21
          Java 類路徑:      D:\db-derby-10/lib/derbyshared.jar;D:\db-derby-10/lib/derby.jar;D:\db-derby-10/lib/de
          rbynet.jar;D:\db-derby-10/lib/derbyclient.jar;D:\db-derby-10/lib/derbytools.jar;D:\db-derby-10/lib/derby
          optionaltools.jar
          OS 名:            Windows 10
          OS 體系結構:      amd64
          OS 版本:          10.0
          Java 用戶名:      chenxd
          Java 用戶主目錄:C:\Users\chenxd
          Java 用戶目錄:    D:\db-derby-10\bin
          java.specification.name: Java Platform API Specification
          java.specification.version: 21
          java.runtime.version: 21.0.2+13-LTS-58
          --------- Derby 信息 --------
          [D:\db-derby-10\lib\derby.jar] 10.17.1.0 - (1913217)
          [D:\db-derby-10\lib\derbytools.jar] 10.17.1.0 - (1913217)
          [D:\db-derby-10\lib\derbynet.jar] 10.17.1.0 - (1913217)
          [D:\db-derby-10\lib\derbyclient.jar] 10.17.1.0 - (1913217)
          [D:\db-derby-10\lib\derbyshared.jar] 10.17.1.0 - (1913217)
          D:\db-derby-10\bin>startNetworkServer
          Tue May 14 10:47:20 CST 2024 : Apache Derby 網絡服務器 - 10.17.1.0 - (1913217) 已啟動并準備接受端口 1527
           上的連接

          運行ij,插入記錄,出現亂碼(JDK19及之前未曾出現這個問題):

          D:\db-derby-10\bin>ij -p ij.properties

          ij>connect 'chendb';
          ij> drop table zipcodes;
          ij> create table zipcodes(zipcode varchar(6), university varchar(20), city varchar(10)); 
          ij> insert into zipcodes values ('100044', '北京交通大學', '北京');
          ij> insert into zipcodes values ('200030', '上海交通大學', '上海');
          ij> select * from zipcodes;
          ZIPCO&|UNIVERSITY          |CITY
          --------------------------------------
          100044|??????????          |????
          200030|?????????           |???

          問題解決

          基于上回Java輸入輸出文件亂碼的經驗,基本確定就是控制臺字符集(GBK)和數據庫字符集(UTF-8)編碼不一致,需要修改ij運行時的字符集為GBK。由于ij運行時,實際是用java命令指定類名運行的,可以使用運行時指定 ”-Dderby.ui.codeset=GBK“ 來修改字符集為“GBK”。為了方便使用,直接使用配置文件ij.propertis,在其中加入字符集相關的屬性定義:

          ij.driver=org.apache.derby.jdbc.ClientDriver
          ij.protocol=jdbc:derby://localhost:1527/
          #解決JDK21后,命令行漢字輸入亂碼問題
          #默認命令行字符集為GBK(代碼頁936)而非UTF-8(代碼頁 65001)
          #https://www.rfc-editor.org/rfc/rfc5646.html
          derby.ui.locale=zh-Hans
          derby.ui.codeset=GBK

          重新運行ij:

          D:\db-derby-10\bin>ij -p ij.properties

          ij 版本 10.17
          ij> connect 'chendb';
          ij> insert into zipcodes values ('100044', '北京交通大學', '北京');
          已插入/更新/刪除 1 行
          ij> select * from zipcodes;
          ZIPCO&|UNIVERSITY          |CITY
          --------------------------------------
          100044|??????????          |????
          200030|?????????           |???
          100044|北京交通大學              |北京
          
          已選擇 3行
          ij>

          至此成功解決亂碼問題。

          14_HttpRunner中文亂碼問題_01_悟空CRM 斷言中文失敗顯示亂碼_原因分析



          測試目的:

          • 實現“悟空CRM”系統登錄
          • 通過頁面標題文字進行斷言,判斷登錄是否成功


          通過瀏覽器登錄成功后,進入系統首頁,查看源代碼,準備把標題文字作為斷言用例執行是否成功的標志。

          編寫測試用例如下:

          
          - config:
              name: 悟空CRM
          
          - test:
              name: 登錄
              request:
                url: http://192.168.1.102/72crm/index.html#/workbench/index
                method: POST
                data:
                  username: 13888888888
                  password: 123456
              validate:
                - eq: [status_code, 200]
                - eq: [<title>(.*)CRM</title>, 悟空]
           


          執行測試用例,直接失敗 :(


          看看錯誤提示,發現是第二個斷言,即標題的斷言失敗了。

          再仔細看輸出,實際結果提取出來的是亂碼,到這里就基本清楚了,字符編碼問題!!



          我們編寫用例使用的是 UTF-8 字符編碼方式,這種方式下對常見中文的編碼規律是,每個漢字被編碼為三個字節,“悟空”是兩個漢字,編碼后對應六個字節,數數亂碼的字符數量,正好也是六個。


          這六個亂碼是什么鬼。別著急,我們詳細分析一下。


          這里我使用的常見的 EditPlus 文本編輯工具,新建一個空白文本文件,輸入“悟空”二字,并保存為“UTF-8”編碼方式(注意:這是重點! 重點!)


          保存成功后,直接查看文件內容的十六進制編碼。

          “悟空”二字的 UTF-8 編碼是: E6 82 9F E7 A9 BA 共六個字節


          正常情況下,用UTF-8方式進行編碼,則解碼也必須是UTF-8方式,即編碼和解碼一致,否則就會出現亂碼。我們通過HttpRunner執行測試用例,返回的HTTP響應數據(即HTML文件)中,標題位置直接就輸出了亂碼(見截圖中劃綠線的紅色錯誤提示部分)。那么HttpRunner到底用的什么方式進行解碼呢?一般情況下,尤其是英文的軟件,都默認習慣使用ISO8859-1的字符編碼方式。


          我們知道最早的字符編碼是 ASCII 碼,共表示128個字符,每個字符占用1B(1個字節)的大小,但實際只使用了其中的7位,高位補了0,如字符 'A'的編碼是 '0100 0001',最高位是一個0來占位的。


          后續有些國家和地區對 ASCII 碼進行了擴展,即把最高位的0給使用了,這樣就可以表示256個字符。但是這些擴展互相間不兼容。


          在 Windows 中運行命令:charmap ,打開字符映射工具,字符集分別選中“Windows 西歐”和“Windows中歐”,可以清楚的看到,從 0X80 編碼以后(即擴展出來的字符內容),二者出現很大的不同,西歐字符集中的一些字符,在中歐字符集中就根本沒有出現。也就是說,同樣的編碼如果使用不同的字符集解碼,可能產生不同的字符顯示,這就是亂碼形成的很大根源,說白了就是一句話:編碼和解碼不一致。


          于是大牛出現了- ISO(國際標準化組織),他制定了一套統一的標準,即 ISO8859 字符集系列,分別把西歐、東歐、南歐、北歐等字符集分別編號為 ISO8859-1、ISO8859-2、ISO8859-3、ISO8859-4等。其中,最常用的就是 ISO8859-1 西歐這個標準,也稱Latin-1。


          由于“悟空”二字的 UTF-8 編碼是: E6 82 9F E7 A9 BA ,這六個字節如果用西歐的 ISO8859-1來一個字節一個字節的解碼,每個字節就對應了一個西歐的字符。這些字符就是我們從錯誤提示信息中所看到的亂碼了。


          主站蜘蛛池模板: 91久久精品一区二区| 久久精品一区二区三区中文字幕| 精品aⅴ一区二区三区| 波多野结衣高清一区二区三区| 无码日韩AV一区二区三区| 色婷婷综合久久久久中文一区二区| 精品3d动漫视频一区在线观看| 免费在线视频一区| 国产在线一区二区三区| 激情内射亚洲一区二区三区 | 国产A∨国片精品一区二区| 一区二区三区免费在线视频 | 国产乱码精品一区二区三区四川人| 无码日韩AV一区二区三区| 国产一区二区三区不卡观| 在线观看日韩一区| 日韩精品一区二区三区四区| 波多野结衣一区在线| 伊人无码精品久久一区二区| 无码人妻精品一区二| 麻豆国产在线不卡一区二区| 中文字幕一精品亚洲无线一区| 国产MD视频一区二区三区| 无码中文字幕乱码一区| 国产自产对白一区| 亚洲国产欧美一区二区三区| 蜜桃臀无码内射一区二区三区| 精品一区二区久久久久久久网站| 一区二区三区高清视频在线观看 | bt7086福利一区国产| 91精品一区二区| 国产伦精品一区二区三区视频小说| 亚洲国产美女福利直播秀一区二区| 免费无码一区二区三区蜜桃| 亚洲福利视频一区二区| 国产成人无码AV一区二区在线观看 | 亚欧成人中文字幕一区| 2021国产精品一区二区在线| 中文乱码人妻系列一区二区| 亚洲av无码一区二区三区在线播放| 日本精品一区二区三区视频|