如果有哪一个做程序员的小伙伴说自己没有遇到中文乱码问题,我是不愿意相信的。今天在做微信订阅号的智能回复时,又一时迷乱的跳进了中文乱码这个火坑。刚解决问题时,都欢呼雀跃了,完全忘记了她曾经带给我的痛苦。

一、问题描述
看到没,红色框框内的乱码赤裸裸的对我进行挑衅,而我却无可奈何,真是糟糕透顶。
二、寻求解决之道
面对问题,只有拿着刀逼自己去解决啊,能怎么样呢?
首先,必须搞清楚微信智能回复的机制,画图如下:
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;
}
好了,万事大吉了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# wechat4j
# 乱码
# 中文乱码
# JAXB简介_动力节点Java学院整理
# Jaxb2实现JavaBean与xml互转的方法详解
# java使用jaxb操作xml示例
# 深入jaxb xjc编码问题的详细介绍
# JAXB命名空间_动力节点Java学院整理
# 我是
# 解决问题
# 三处
# 器上
# 运行环境
# 好了
# 对我
# 你会
# 万事大吉
# 这段
# 不愿意
# 拿着
# 不清楚
# 这两个
# 我认为
# 欢呼雀跃
# 而我
# 可以看到
# 按理说
# 问题是
相关文章:
如何设置并定期更换建站之星安全管理员密码?
如何在建站之星网店版论坛获取技术支持?
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
制作网站怎么制作,*游戏网站怎么搭建?
建站IDE高效指南:快速搭建+SEO优化+自适应模板全解析
江苏网站制作公司有哪些,江苏书法考级官方网站?
历史网站制作软件,华为如何找回被删除的网站?
如何在景安云服务器上绑定域名并配置虚拟主机?
长沙做网站要多少钱,长沙国安网络怎么样?
SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?
Swift中switch语句区间和元组模式匹配
C++如何编写函数模板?(泛型编程入门)
建站主机选择指南:服务器配置与SEO优化实战技巧
GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?
如何用wdcp快速搭建高效网站?
如何选择建站程序?包含哪些必备功能与类型?
详解jQuery中基本的动画方法
如何获取PHP WAP自助建站系统源码?
建站之星在线客服如何快速接入解答?
大同网页,大同瑞慈医院官网?
如何选择可靠的免备案建站服务器?
如何在Windows 2008云服务器安全搭建网站?
北京建设网站制作公司,北京古代建筑博物馆预约官网?
如何通过FTP空间快速搭建安全高效网站?
Android自定义listview布局实现上拉加载下拉刷新功能
代购小票制作网站有哪些,购物小票的简要说明?
焦点电影公司作品,电影焦点结局是什么?
学校建站服务器如何选型才能满足性能需求?
宝塔面板如何快速创建新站点?
品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?
网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?
网站代码制作软件有哪些,如何生成自己网站的代码?
制作电商网页,电商供应链怎么做?
如何在Ubuntu系统下快速搭建WordPress个人网站?
Android自定义控件实现温度旋转按钮效果
制作网站的网址是什么,请问后缀为.com和.com.cn还有.cn的这三种网站是分别是什么类型的网站?
深圳防火门网站制作公司,深圳中天明防火门怎么编码?
西安大型网站制作公司,西安招聘网站最好的是哪个?
如何通过虚拟机搭建网站?详细步骤解析
如何解决VPS建站LNMP环境配置常见问题?
如何快速搭建高效可靠的建站解决方案?
开封网站制作公司,网络用语开封是什么意思?
建站之星后台密码遗忘或太弱?如何重置与强化?
实例解析angularjs的filter过滤器
招商网站制作流程,网站招商广告语?
如何在云主机上快速搭建网站?
如何在橙子建站中快速调整背景颜色?
南京做网站制作公司,南京哈发网络有限公司,公司怎么样,做网页美工DIV+CSS待遇怎么样?
无锡营销型网站制作公司,无锡网选车牌流程?
如何制作一个表白网站视频,关于勇敢表白的小标题?
*请认真填写需求信息,我们会在24小时内与您取得联系。