java中常見(jiàn)的中文亂碼總結(jié)
1.IO流中讀取文件時(shí)出現(xiàn)亂碼問(wèn)題
1,先記錄從文件中(new File()的時(shí)候)讀取數(shù)據(jù)逐級(jí)包裝直至緩沖字節(jié)輸入流(new BufferReader())并設(shè)置編碼格式
//文件路徑 String path = "??????????????????"; //讀取文件 File file = new File(path); //包裝成文件字節(jié)輸入流 FileInputStream fis = new FileInputStream(file); //下邊這個(gè)流可以理解為從字節(jié)流邁向字符流的一個(gè)橋梁 //并且InputStreamReader在創(chuàng)建對(duì)象的時(shí)候可以傳入想要的字符編碼的參 //數(shù)這里是“utf-8” InputStreamReader isr = new InputStreamReader(fis,"utf-8"); //再將InputStreamReader包裝進(jìn)BufferReader中 BufferedReader br = new BufferedReader(isr);
2.字節(jié)碼文件讀取時(shí)出現(xiàn)的亂碼問(wèn)題
遇到了一個(gè)在eclipse使用過(guò)程中發(fā)生的轉(zhuǎn)碼問(wèn)題 ,安裝完eclipse后Project→Properties→Resource中寫(xiě)著默認(rèn)的編碼格式為GBK,我一直沒(méi)有改成UTF-8,在學(xué)習(xí)過(guò)程中因?yàn)橐恢苯y(tǒng)一使用GBK編碼 所以一直也沒(méi)有出現(xiàn)問(wèn)題
直到有一天我在湯姆貓上運(yùn)行我學(xué)習(xí)Servlet中寫(xiě)的代碼時(shí)發(fā)現(xiàn)一個(gè)有趣的現(xiàn)象
如果我使用response直接向服務(wù)器發(fā)送中文內(nèi)容不會(huì)出現(xiàn)亂碼
`resp.getWriter().println("<h1>我喜歡吃</h1>");
但是在使用BufferReader的readline()方法讀取到中文內(nèi)容時(shí)會(huì)出現(xiàn)亂碼情況,我試過(guò)無(wú)論我修改IO流中讀取字符的編碼格式 還是修改整個(gè)項(xiàng)目的編碼格式 都不能改變這個(gè)亂碼問(wèn)題
BufferedReader br = new BufferedReader(fr); br.readLine()//下圖中“tom!”的那一行
請(qǐng)教了老師,得到了新的解決辦法
在本類(lèi)中加入一行代碼,這句代碼的意思是查看VM啟動(dòng)參數(shù),運(yùn)行后在控制臺(tái)上就可以看到下圖中的信息(只截了部分片段)可以看到有一個(gè)屬性叫file.encoding它的值是GBK
意思我個(gè)人分析可能是我創(chuàng)建項(xiàng)目的時(shí)候使用的是GBK編碼 然后自己也運(yùn)行過(guò)這個(gè)項(xiàng)目 .class的字節(jié)碼文件已經(jīng)生成了 這時(shí)候如果只在項(xiàng)目右鍵Properties進(jìn)去修改編碼格式為時(shí)已晚
//查看VM啟動(dòng)參數(shù) System.getProperties().list(System.out);
老師給出了一個(gè)臨時(shí)解決辦法,在本類(lèi)中將要出現(xiàn)亂碼的那一行之前加上一行
System.setProperty("file.encoding", "utf-8");
將上文中提到的VM參數(shù)中file.encoding的值現(xiàn)改成utf-8
其實(shí)最根本的解決辦法就是在項(xiàng)目創(chuàng)建之初就設(shè)定好編碼格式,如果出現(xiàn)像我這樣來(lái)不及的情況的話可以臨時(shí)使用這個(gè)方法
3.使用Servlet過(guò)濾器Filter統(tǒng)一設(shè)置整個(gè)Servlet項(xiàng)目中的各種編碼格式
Servlet提供了三大組件 servlet filer listener
在設(shè)置編碼格式時(shí) 我們就可以預(yù)先設(shè)定一個(gè)全局范圍內(nèi)的過(guò)濾器,
創(chuàng)建Filter類(lèi) 添加注解@WebFilter(eclipse在創(chuàng)建Filter類(lèi)時(shí)會(huì)自動(dòng)創(chuàng)建該注解) 注解的內(nèi)容我這里直接寫(xiě)了/* ,表示本項(xiàng)目中所有請(qǐng)求都必須先經(jīng)過(guò)這個(gè)Filter過(guò)濾
@WebFilter("/*") public class EncodingFilter implements Filter { public EncodingFilter() { } @Override public void init(FilterConfig fConfig) throws ServletException { //當(dāng)Filter被初始化的時(shí)候調(diào)用,打印輸出 //Servlet默認(rèn)是懶加載模式 System.out.println("encodingfilter is initialized........"); } @Override public void destroy() { //當(dāng)filter被銷(xiāo)毀的時(shí)候調(diào)用,打印輸出 System.out.println("encodingfilter is destoryed......."); } //doFilter方法就相當(dāng)于一個(gè)篩子 //一共四行代碼 分別是我們提出的三個(gè)要求,和一條放行代碼 @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //設(shè)置解析報(bào)文的編碼格式 request.setCharacterEncoding("utf-8"); //設(shè)置返回響應(yīng)使用的編碼格式 response.setCharacterEncoding("utf-8"); //告訴瀏覽器響應(yīng)內(nèi)容是text和html類(lèi)型的文件 編碼格式是utf-8 response.setContentType("text/html;charset=utf-8"); //放行請(qǐng)求 //其中包含了請(qǐng)求從哪里來(lái) 準(zhǔn)備到哪里去的相關(guān)信息 chain.doFilter(request, response); } }
過(guò)濾器的功能除了簡(jiǎn)介的注解形式之外,Servlet中還有一種基于web.xml文件的形式,打開(kāi)web.xml文件,在根目錄下加入以下代碼
<filter> <!-- 標(biāo)簽的name --> <filter-name>encode</filter-name> <!-- 標(biāo)簽的類(lèi)的位置 --> <filter-class>com.zyj.day02.EncodingFilter</filter-class> </filter> <filter-mapping> <!-- 對(duì)應(yīng)得標(biāo)簽的name --> <filter-name>encode</filter-name> <!-- 聲明作用域的范圍 --> <url-pattern>/*</url-pattern> </filter-mapping>
雖然內(nèi)容比較簡(jiǎn)單 但寫(xiě)起來(lái)也算是比較繁瑣 所以建議還是使用注解的形式來(lái)實(shí)現(xiàn)功能
值得一提的是
通過(guò)在filter類(lèi)的init方法中添加了一句打印語(yǔ)句我們發(fā)現(xiàn),如果你既在類(lèi)名上標(biāo)明注解 又在web.xml文件中添加了配置,那么當(dāng)有請(qǐng)求過(guò)來(lái)的時(shí)候,我們會(huì)在控制臺(tái)上發(fā)現(xiàn)init方法執(zhí)行了兩次,雖然目前看來(lái)沒(méi)有什么問(wèn)題 但總的來(lái)說(shuō) 二者有一個(gè)即可。
4,從阿里云服務(wù)器上的mysql數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)產(chǎn)生的中文亂碼
問(wèn)題描述:
當(dāng)我在servlet中連接好數(shù)據(jù)庫(kù) 打算實(shí)現(xiàn)一個(gè)寫(xiě)入的功能 一個(gè)讀取的功能
本來(lái)是可以通過(guò)sql語(yǔ)句順利的寫(xiě)入中文,在數(shù)據(jù)庫(kù)中查詢到中文,還可以讀取數(shù)據(jù)打印在控制臺(tái)上 整個(gè)過(guò)程中都沒(méi)有出現(xiàn)亂碼問(wèn)題 但當(dāng)我想使用直接從數(shù)據(jù)庫(kù)中讀取中文 “小張” 作為我項(xiàng)目中登錄功能的賬號(hào)時(shí) 發(fā)現(xiàn)無(wú)法讀取到正確的數(shù)據(jù) 以至于判定我在賬號(hào)框輸入的“小張”不存在 正在初學(xué)階段 大體知道各個(gè)流程中的各個(gè)編碼環(huán)境 但還是沒(méi)有找到是哪個(gè)環(huán)節(jié)的編碼格式與眾不同
找到了一個(gè)解決辦法 :
在項(xiàng)目中druid-config.properties(阿里云德魯伊的配置文件)中的url屬性后拼接一個(gè)?characterEncoding=utf-8 設(shè)置讀取mysql數(shù)據(jù)庫(kù)中數(shù)據(jù)的時(shí)候的編碼格式
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://你的端口號(hào):3306/estore?characterEncoding=utf-8 username=???mysql數(shù)據(jù)庫(kù)的賬號(hào) password=???mysql數(shù)據(jù)庫(kù)的密碼 maxActive=30 maxWait=3000
下面在給大家補(bǔ)充介紹:java中常見(jiàn)的中文亂碼總結(jié)
亂碼現(xiàn)象產(chǎn)生的原因:由于編碼方式的不同,才會(huì)出現(xiàn)亂碼的情況。
哪里會(huì)產(chǎn)生亂碼:1.頁(yè)面 2.url地址 3.數(shù)據(jù)庫(kù)亂碼 4.數(shù)據(jù)提交(form,ajax) 5.開(kāi)發(fā)工具
怎么解決:
1.統(tǒng)一開(kāi)發(fā)工具的編碼設(shè)置
2.設(shè)置應(yīng)用服務(wù)器的編碼方式,如:端口號(hào),編碼方式
3.數(shù)據(jù)庫(kù)本身的編碼方式
4.強(qiáng)制設(shè)置request和response的數(shù)據(jù)編碼方式(同時(shí)也可以采用過(guò)濾器的方式攔截所有的編碼方式)
5.采用代碼方式強(qiáng)轉(zhuǎn)數(shù)據(jù)編碼方式(UrlEncode.encode("你好","utf-8"))
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
- Java 解決讀寫(xiě)本地文件中文亂碼的問(wèn)題
- Java讀取properties配置文件時(shí),出現(xiàn)中文亂碼的解決方法
- Java讀寫(xiě).properties文件解決中文亂碼問(wèn)題
- Java讀寫(xiě)txt文件時(shí)防止中文亂碼問(wèn)題出現(xiàn)的方法介紹
- 解決Java原生壓縮組件不支持中文文件名亂碼的問(wèn)題
- java頁(yè)面中文亂碼的解決辦法
- Java Web開(kāi)發(fā)項(xiàng)目中中文亂碼解決方法匯總
- Java中HttpServletResponse響應(yīng)中文出現(xiàn)亂碼問(wèn)題
- java中文亂碼之解決URL中文亂碼問(wèn)題的方法
相關(guān)文章
Java的外部類(lèi)為什么不能使用private和protected進(jìn)行修飾的講解
今天小編就為大家分享一篇關(guān)于Java的外部類(lèi)為什么不能使用private和protected進(jìn)行修飾的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-04-04Java開(kāi)發(fā)或調(diào)用WebService的幾種方式總結(jié)
java開(kāi)發(fā)過(guò)程中,很多地方都會(huì)遇到數(shù)據(jù)傳遞,遠(yuǎn)程獲取數(shù)據(jù)問(wèn)題,這篇文章主要介紹了Java開(kāi)發(fā)或調(diào)用WebService的幾種方式的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-06-06教你Springboot如何實(shí)現(xiàn)圖片上傳
這篇文章主要介紹了教你Springboot如何實(shí)現(xiàn)圖片上傳,首先大家明白圖片上傳,需要在數(shù)據(jù)庫(kù)定義一個(gè)varchar類(lèi)型的img字段圖片字段,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07SpringMvc獲取頁(yè)面中的參數(shù)方法詳解
這篇文章主要介紹了SpringMvc獲取頁(yè)面中的參數(shù)方法詳解,獲取頁(yè)面的參數(shù)通常都是讓類(lèi)實(shí)現(xiàn)設(shè)置HttpServletRequest request接口然后重寫(xiě)接口中的方法的辦法來(lái)得到參數(shù),但是在Springmvc中有其他的獲取方法,需要的朋友可以參考下2023-10-10java實(shí)現(xiàn)小i機(jī)器人api接口調(diào)用示例
這篇文章主要介紹了java實(shí)現(xiàn)小i機(jī)器人api接口調(diào)用示例,需要的朋友可以參考下2014-04-04