java web項(xiàng)目各種亂碼的解決方案 | 您所在的位置:網(wǎng)站首頁(yè) › 屬狗運(yùn)勢(shì)2021年運(yùn)勢(shì)如何 › java web項(xiàng)目各種亂碼的解決方案 |
原創(chuàng)作品,允許轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章?
原始出處?、作者信息和本人聲明。否則將追究法律責(zé)任。
作者:
永恒の_☆?地址:
http://blog.csdn.net/chenghui0317/article/details/10299103
一、前言
?? ?目前web項(xiàng)目中,很多亂碼情況沒(méi)有得到統(tǒng)一解決,或多或少影響開(kāi)發(fā)效率和延長(zhǎng)開(kāi)發(fā)時(shí)間, 所以總結(jié)一下關(guān)于java web項(xiàng)目各種亂碼情況的解決方案。 二、準(zhǔn)備條件?? ? 1、一個(gè)普通的web項(xiàng)目 webProject;? ?? 2、一個(gè)web服務(wù)器 Tomcat。 三、分析各種亂碼的情況???? 1、項(xiàng)目的編碼格式和頁(yè)面文件的編碼格式不一樣是否有沖突? ????? 答:webProject項(xiàng)目的編碼格式是“GBK” ,項(xiàng)目下的頁(yè)面中的編碼格式是“UTF-8”,實(shí)踐發(fā)現(xiàn),項(xiàng)目的編碼格式和頁(yè)面的編碼格式不一樣不會(huì)有任何問(wèn)題,顯示的中文沒(méi)有亂碼。???? ???? 查看項(xiàng)目的編碼格式可以在?項(xiàng)目-->右鍵-->Properties--> Text file encoding?框內(nèi)顯示的具體值就是項(xiàng)目編碼格式。? ???? 查看頁(yè)面文件的編碼格式可以在?頁(yè)面-->右鍵-->Properties--> Text file encoding?框內(nèi)顯示的具體值就是頁(yè)面文件的編碼格式。 ???? 2、頁(yè)面的文件編碼格式和頁(yè)面內(nèi)容的編碼格式不一樣是否有沖突? ????? 答:將頁(yè)面文件編碼格式改為“UTF-8”,頁(yè)面的內(nèi)容的編碼格式改為“GBK”,具體如下: [html]? view plain ?copy ??????????Insert?title?here??????測(cè)試中文是否亂碼!@#!@#?????? 結(jié)果發(fā)現(xiàn) 亂碼了,具體效果如下:所以頁(yè)面的文件的編碼格式必須和頁(yè)面內(nèi)容的編碼格式一樣,否則顯示肯定亂碼。 ?????另外,如果頁(yè)面中格式在eclipse顯示 是好的,這個(gè)時(shí)候改變文件的編碼格式也會(huì)亂碼,如果非要改變文件編碼的格式,可以這樣: 先將顯示正確的內(nèi)容復(fù)制一份 然后修改文件的編碼格式,這個(gè)時(shí)候文件內(nèi)顯示的是亂碼,然后將復(fù)制的內(nèi)容直接覆蓋在這個(gè)頁(yè)面中就好了。 ?????如果給將上面代碼的pageEncoding改為"UTF-8"了發(fā)現(xiàn)顯示正常了,所以可不可以這么說(shuō),頁(yè)面顯示是否亂碼與charset指定的值無(wú)關(guān)? ???? 但是如果將上面代碼的pageEncoding="UTF-8“這個(gè)屬性直接去掉,然后顯示效果,發(fā)現(xiàn)亂碼了。 如果把contentType屬性的值改為 contentType="text/html; charset=UTF-8" 試試效果,具體如下: 所以可以這么理解:在沒(méi)有指定pageEncoding屬性的時(shí)候, charset 將會(huì)被忽略,如果沒(méi)有指定pageEncoding屬性,那么頁(yè)面就會(huì)按照charset的編碼值來(lái)顯示具體效果。 ???? 如果charset指定的值是GBK ,這個(gè)時(shí)候由于沒(méi)有pageEncoding 所以頁(yè)面內(nèi)容按照GBk編碼顯示,但是與文件編碼格式不符合 ,索引導(dǎo)致亂碼。具體效果如下: ???? 現(xiàn)在又有另外一種情況,如果pageEncoding指定了UTF-8 ,但是charset指定的是 GBK ,GB2312? 這個(gè)時(shí)候頁(yè)面顯示不會(huì)亂碼。 ???? 但是如果charset指定的是iso-8859-1,這個(gè)時(shí)候頁(yè)面顯示就是亂碼了,具體效果如下: ???? 但是如果charset指定的是big5,這個(gè)是頁(yè)面顯示只是部分亂碼,具體效果如下: 所以BIG5只會(huì)會(huì)繁體或者沒(méi)有繁體格式的文字敏感。 ???? 現(xiàn)在再實(shí)驗(yàn)一下,把contentType屬相也去掉,指定meta標(biāo)簽中content屬性中的charset=UTF-8 ,具體效果如下: 一種另外格式的亂碼顯示出來(lái)了。。。 綜上所述:在jsp中如果要顯示正確的內(nèi)容,并且保證其顯示不亂碼,必須要指定contentType 或者 pageEncoding 的屬性與文件編碼格式一致。并且如果他們都存在,那么pageEncoding必須與文件編碼格式一致,contentType必須是中文編碼格式才行。 ????3、通過(guò)URL傳遞中文參數(shù)的時(shí)候接收的亂碼怎么解決? ???? 答:新建一個(gè)servlet 名叫encodeServlet,在encode.jsp中添加超鏈接傳遞一個(gè)參數(shù)? 跳轉(zhuǎn)到該serlvet。 超鏈接如下: [html]? view plain ?copy go?to?servlet??servlet接收參數(shù),具體get方法處理方式如下: [java]? view plain ?copy ????/**??????*?@see?HttpServlet#doGet(HttpServletRequest?request,?HttpServletResponse?response)??????*/??????protected?void?doGet(HttpServletRequest?request,?HttpServletResponse?response)?throws?ServletException,?IOException?{??????????String?param?=?request.getParameter("param");????????????????????request.getRequestDispatcher("../encode.jsp?param="+param).forward(request,?response);??????}?? 調(diào)試之后發(fā)現(xiàn),參數(shù)亂碼了:???? 這是因?yàn)閰?shù)通過(guò)url傳遞的時(shí)候是以http超文本協(xié)議傳遞的,它的格式是 iso-8859-1 ,所以可以設(shè)置tomcat服務(wù)器全局URL請(qǐng)求的格式,這樣子所有的請(qǐng)求都會(huì)按照這個(gè)編碼格式傳遞參數(shù)了。具體如下: 在tomcat安裝目錄的conf/server.xml中找到protocol="HTTP/1.1"的屬性配置的連接器,在里面添加URIEncoding屬性,具體如下: URIEncoding ,顧名思義,它只針對(duì) URL傳遞的請(qǐng)求,即get請(qǐng)求。。 ???? 并且如果這么設(shè)置之后就不能再使用 param = new String(param.getBytes("iso-8859-1"),"UTF-8");轉(zhuǎn)碼了? 這樣反而又變亂碼了。 ???? 另外還可以在接收到參數(shù)之后,重新指定編碼也可以,具體如下: [java]? view plain ?copy String?param?=?request.getParameter("param");??param?=?new?String(param.getBytes("iso-8859-1"),"UTF-8");?? 調(diào)試頁(yè)面,發(fā)現(xiàn)并沒(méi)有成功,具體效果如下:沒(méi)有效果,,,為什么,?因?yàn)轫?yè)面的內(nèi)容編碼是UTF-8的,但是URL它傳遞的時(shí)候只能傳遞iso-8859-1 的編碼,如果直接傳遞UTF-8編碼的內(nèi)容,那么無(wú)論后臺(tái)怎么轉(zhuǎn)換都沒(méi)有效果。 即使在servlet中重新指定charset 也無(wú)濟(jì)于事。 ???? 但是如果直接在地址欄輸入: http://localhost:8080/webProject/servlet/encodeServlet?param=中文 并且修改一些代碼,具體修改如下: [java]? view plain ?copy response.setContentType("text/html;charset=UTF-8");??String?param?=?request.getParameter("param");??param?=?new?String(param.getBytes("iso-8859-1"),"UTF-8");?? 然后運(yùn)行效果如下:這樣子是沒(méi)問(wèn)題的。。 ???? 但是如果非要使用new String()重新編碼來(lái)實(shí)現(xiàn)接收中文怎么辦呢?,可以修改源碼,具體如下: [java]? view plain ?copy request.setCharacterEncoding("UTF-8");??String?param?=?request.getParameter("param");??param?=?new?String(param.getBytes("iso-8859-1"),"UTF-8");?? 設(shè)置字符編碼格式 即可,具體效果如下:實(shí)踐證明,不管是超鏈接 跳轉(zhuǎn)到servlet 還是直接在url輸入中文跳轉(zhuǎn)到servlet 只使用request.setCharacterEncoding("UTF-8"); 統(tǒng)一編碼格式 都可以實(shí)現(xiàn)接收正確的參數(shù)。。 最開(kāi)始一直以為request.setCharacterEncoding("UTF-8"); 只能處理post請(qǐng)求的參數(shù),get請(qǐng)求的一樣可以。 ???? 既然這么有效果,那么為了避免重復(fù)的使用這行代碼或者忘記使用而導(dǎo)致亂碼,可以使用一個(gè)過(guò)濾器 統(tǒng)一處理任何請(qǐng)求的編碼格式。一勞永逸。 具體FIlter代碼如下: [java]? view plain ?copy package?com.struts2.util;????import?java.io.IOException;????import?javax.servlet.Filter;??import?javax.servlet.FilterChain;??import?javax.servlet.FilterConfig;??import?javax.servlet.ServletException;??import?javax.servlet.ServletRequest;??import?javax.servlet.ServletResponse;????import?org.apache.log4j.Logger;????public?class?CharacterFilter?implements?Filter?{????????private?Logger?logger?=?Logger.getLogger(this.getClass());??????String?encoding?=?null;??????@Override??????public?void?destroy()?{??????????logger.info("***************the?CharacterFilter?class'?destroy()?is?invoking?.***************");??????}????????@Override??????public?void?doFilter(ServletRequest?request,?ServletResponse?response,??????????????FilterChain?filterChain)?throws?IOException,?ServletException?{??????????request.setCharacterEncoding(encoding);??????????response.setCharacterEncoding(encoding);??????????filterChain.doFilter(request,?response);??????}????????@Override??????public?void?init(FilterConfig?filterConfig)?throws?ServletException?{??????????logger.info("***************the?CharacterFilter?class'?init()?is?invoking?.***************");??????????encoding?=?filterConfig.getInitParameter("encoding");??????}????}?? 然后web.xml的配置如下: [html]? view plain ?copy ????characterFitler????com.struts2.util.CharacterFilter??????????encoding??????UTF-8????????????characterFitler????/*???????? 但是但是,實(shí)際開(kāi)發(fā)中,上面的配置在處理get請(qǐng)求的時(shí)候 有些時(shí)候可以指定編碼成功,有的時(shí)候指定編碼失敗, 成功率大概60-70%之間,至今不知道為何會(huì)這樣。。。 解決方案: 使用js函數(shù)編碼之后,然后后臺(tái)解碼即可,具體前臺(tái)代碼如下: [html]? view plain ?copy ????????Insert?title?here??????測(cè)試中文是否亂碼!@#!@#??go?to?servlet????function?goTo(){??????var?param?=?encodeURI(encodeURI("中文"));??//這里編碼必須調(diào)用兩次,因?yàn)閭鬟f后臺(tái)后java程序會(huì)解碼一次,然后自己還要解碼一次,??????location.href="/servlet/encodeServlet?param="+param;??}???????? 后臺(tái)解碼代碼如下: [java]? view plain ?copy //request.setCharacterEncoding("UTF-8");??//response.setContentType("text/html;charset=UTF-8");??String?param?=?request.getParameter("param");??//param?=?new?String(param.getBytes("iso-8859-1"),"UTF-8");//這個(gè)用于直接處理轉(zhuǎn)換get請(qǐng)求的編碼??//param?=?URLEncoder.encode(param);//這個(gè)是用于編碼的方法??param?=?URLDecoder.decode(param);//這個(gè)是用于解碼的方法?? ok ,這樣子解決了js函數(shù)請(qǐng)求后臺(tái)出現(xiàn)亂碼的情況。???? 另外在利用PrintWriter輸出的時(shí)候 出現(xiàn)亂碼了,具體代碼如下: [java]? view plain ?copy PrintWriter?out?=?response.getWriter();??out.print("接收的參數(shù)是:"+param);????out.close();?? 具體效果如下所示:這里可以在servlet請(qǐng)求的頂部加上response.setContentType("text/html;charset=UTF-8"); 設(shè)置內(nèi)容編碼格式 即可輸出正確的效果,具體如下圖: 綜上所述: (1)在參數(shù)的時(shí)候出現(xiàn)亂碼,如果是get請(qǐng)求可以統(tǒng)一設(shè)置tomcat的uri編碼處理格式,這樣所有的url發(fā)送的請(qǐng)求都是以指定格式發(fā)送。 (2)request.setCharacterEncoding("UTF-8");主要用戶 get/post請(qǐng)求中設(shè)置整個(gè)servlet的編碼格式,好處是防止傳遞的中文參數(shù)亂碼。 (3)response.setContentType("text/html;charset=UTF-8"); 主要用于指定當(dāng)前請(qǐng)求中的內(nèi)容格式,好處是防止輸出內(nèi)容的時(shí)候防止中文亂碼。 (4)如果在處理中文亂碼中以上方法都解決不了,那就要使用js前段編碼兩次,后臺(tái)解碼的方式處理。 ??? 4、是否有其他框架的配置直接解決中文亂碼情況? ???? 如果項(xiàng)目中使用了struts2 ,可以在sturts.xml中配置一個(gè)常量,指定所有post請(qǐng)求的編碼,具體如下: [html]? view plain ?copy ?????? 如果在項(xiàng)目中使用了spring,可以在web.xml中配置一個(gè)過(guò)濾器也可以解決編碼亂碼的問(wèn)題,具體如下: [html]? view plain ?copy ????encodingFilter????org.springframework.web.filter.CharacterEncodingFilter??????????encoding??????UTF-8??????????????forceEncoding??????true????????????encodingFilter????/*???? |
CopyRight 2018-2019 實(shí)驗(yàn)室設(shè)備網(wǎng) 版權(quán)所有 |