国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

談談為JAXB和response設置編碼,解決wechat4j中文亂碼的問題

2019-11-26 13:24:58
字體:
來源:轉載
供稿:網友

如果有哪一個做程序員的小伙伴說自己沒有遇到中文亂碼問題,我是不愿意相信的。今天在做微信訂閱號的智能回復時,又一時迷亂的跳進了中文亂碼這個火坑。剛解決問題時,都歡呼雀躍了,完全忘記了她曾經帶給我的痛苦。

一、問題描述

這里寫圖片描述

看到沒,紅色框框內的亂碼赤裸裸的對我進行挑釁,而我卻無可奈何,真是糟糕透頂。

二、尋求解決之道

面對問題,只有拿著刀逼自己去解決啊,能怎么樣呢?

首先,必須搞清楚微信智能回復的機制,畫圖如下:

ps,工具用得不好,請見諒。

接下來,我們抓重點,看亂碼重要發生在什么位置。

1.controller返回給用戶

response.setHeader("content-type", "text/html;charset=UTF-8");// 瀏覽器編碼response.getOutputStream().write(result.getBytes());

就這段代碼了,指定response的編碼方式為UTF-8,按理說亂碼問題應該出現好轉,但是結果依然是沒有。

2.JAXB的toXML

public String toXML(Object obj) {  String result = null;  try {    JAXBContext context = JAXBContext.newInstance(obj.getClass());    Marshaller m = context.createMarshaller();    m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);    m.setProperty(Marshaller.JAXB_FRAGMENT, true);// 去掉報文頭    ByteArrayOutputStream os = new ByteArrayOutputStream();    XMLSerializer serializer = getXMLSerializer(os);    m.marshal(obj, serializer.asContentHandler());    result = os.toString("UTF-8");  } catch (Exception e) {    e.printStackTrace();  }  logger.info("response text:" + result);  return result;}private XMLSerializer getXMLSerializer(OutputStream os) {  OutputFormat of = new OutputFormat();  formatCDataTag();  of.setCDataElements(cdataNode);  of.setPreserveSpace(true);  of.setIndenting(true);  of.setOmitXMLDeclaration(true);  of.setEncoding("UTF-8");  XMLSerializer serializer = new XMLSerializer(of);  serializer.setOutputByteStream(os);  return serializer;}

這里有三個關鍵的點:

1. m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

2. getXMLSerializer(os)

3. os.toString("UTF-8");

可以看到以上三個地方均會涉及到轉碼,第1處,設置Marshaller的編碼;第二處,設置整個XMLSerializer的編碼;第三處,設置返回的ByteArrayOutputStream的string編碼。三處缺一不可。

這次這么透徹,應該解決了問題了吧,但是解決依然中文亂碼,那該如何是好呢?

3.tomcat的輸出環境作怪

針對這一點,網上有人提供這樣的解決思路。

set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER% -Dfile.encoding=UTF-8

設置后重啟tomcat,問題是能夠解決,但副作用是整個tomcat在服務器上運行輸出(tomcat的cmd窗口)一直是亂碼,我認為這種方案不可取。

在運行的war中加入以下代碼

System.getProperty("file.encoding");

你會驚奇的發現,tomcat的運行環境(window server 2008)竟然是GBK,不知道你是否不驚奇,我是嚇到了,為什么不是UTF-8呢?如果是GBK的話,上面兩個步驟中我加入再多的UTF-8頁扯淡啊,不解。

三、解決問題

有了以上的經驗,我們修改以下wechat4j的代碼,主要是第二點。

public String toXML(Object obj) {  String result = null;  try {    JAXBContext context = JAXBContext.newInstance(obj.getClass());    Marshaller m = context.createMarshaller();    String encoding = Config.instance().getJaxb_encoding();    logger.debug("toXML encoding " + encoding + "System file.encoding " + System.getProperty("file.encoding"));    m.setProperty(Marshaller.JAXB_ENCODING, encoding);    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);    m.setProperty(Marshaller.JAXB_FRAGMENT, true);// 去掉報文頭    ByteArrayOutputStream os = new ByteArrayOutputStream();    XMLSerializer serializer = getXMLSerializer(os);    m.marshal(obj, serializer.asContentHandler());    result = os.toString(encoding);  } catch (Exception e) {    e.printStackTrace();  }  logger.info("response text:" + result);  return result;}private XMLSerializer getXMLSerializer(OutputStream os) {  OutputFormat of = new OutputFormat();  formatCDataTag();  of.setCDataElements(cdataNode);  of.setPreserveSpace(true);  of.setIndenting(true);  of.setOmitXMLDeclaration(true);  String encoding = Config.instance().getJaxb_encoding();  of.setEncoding(encoding);  XMLSerializer serializer = new XMLSerializer(of);  serializer.setOutputByteStream(os);  return serializer;}

這兩個方法中,對encoding我們加上可配置的編碼方式,可手動設置GBK(我的服務器上配置了GBK)、GB2312、UTF-8。

如此,會發現wechat4j的后臺輸出就不再是中文亂碼了,但返回給用戶的信息更亂了。

這里寫圖片描述

怎么能這樣呢,耍我這枚程序員啊,真想吐兩句臟話。但別怕啊,既然wechat4j的logger日志不再中文亂碼,那么只能說是第1個環節又出現問題了。

調整嘛

response.setHeader("content-type", "text/html;charset=UTF-8");// 瀏覽器編碼response.getOutputStream().write(result.getBytes("UTF-8"));

注意,這里不能是GBK,只能是UTF-8,我表示不清楚為什么,微信的產品經理給出來解釋下。

重點,JAXB和response合伙解決wechat4j中文亂碼的 方法再次聲明如下:

WeChatController.Java,就是你配給微信公眾開發平臺的URL處,response調整如下

response.setHeader("content-type", "text/html;charset=UTF-8");// 瀏覽器編碼response.getOutputStream().write(result.getBytes("UTF-8"));

wechat4j的JaxbParser.java,分別調整toXML(Object obj)和getXMLSerializer(OutputStream os)方法:

public String toXML(Object obj) {  String result = null;  try {    JAXBContext context = JAXBContext.newInstance(obj.getClass());    Marshaller m = context.createMarshaller();    String encoding = Config.instance().getJaxb_encoding();// GBK    logger.debug("toXML encoding " + encoding + "System file.encoding " + System.getProperty("file.encoding"));    m.setProperty(Marshaller.JAXB_ENCODING, encoding);    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);    m.setProperty(Marshaller.JAXB_FRAGMENT, true);// 去掉報文頭    ByteArrayOutputStream os = new ByteArrayOutputStream();    XMLSerializer serializer = getXMLSerializer(os);    m.marshal(obj, serializer.asContentHandler());    result = os.toString(encoding);  } catch (Exception e) {    e.printStackTrace();  }  logger.info("response text:" + result);  return result;}private XMLSerializer getXMLSerializer(OutputStream os) {  OutputFormat of = new OutputFormat();  formatCDataTag();  of.setCDataElements(cdataNode);  of.setPreserveSpace(true);  of.setIndenting(true);  of.setOmitXMLDeclaration(true);  String encoding = Config.instance().getJaxb_encoding();//GBK  of.setEncoding(encoding);  XMLSerializer serializer = new XMLSerializer(of);  serializer.setOutputByteStream(os);  return serializer;}

好了,萬事大吉了。

這里寫圖片描述

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 沈阳市| 雅安市| 报价| 勐海县| 长垣县| 大新县| 海宁市| 吉首市| 稻城县| 木里| 西乌珠穆沁旗| 高邑县| 肇源县| 岳池县| 庐江县| 竹北市| 辉南县| 龙陵县| 洪洞县| 盐源县| 外汇| 高平市| 屏南县| 日喀则市| 南通市| 高陵县| 眉山市| 翁源县| 茌平县| 桑植县| 沙洋县| 临海市| 合阳县| 大城县| 隆子县| 资溪县| 广州市| 连云港市| 确山县| 卢湾区| 射阳县|