全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

谈谈为JAXB和response设置编码,解决wechat4j中文乱码的问题

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

一、问题描述

看到没,红色框框内的乱码赤裸裸的对我进行挑衅,而我却无可奈何,真是糟糕透顶。

二、寻求解决之道

面对问题,只有拿着刀逼自己去解决啊,能怎么样呢?

首先,必须搞清楚微信智能回复的机制,画图如下:

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学院整理  # 我是  # 解决问题  # 三处  # 器上  # 运行环境  # 好了  # 对我  # 你会  # 万事大吉  # 这段  # 不愿意  # 拿着  # 不清楚  # 这两个  # 我认为  # 欢呼雀跃  # 而我  # 可以看到  # 按理说  # 问题是 


相关文章: 临沂网站制作公司有哪些,临沂第四中学官网?  太平洋网站制作公司,网络用语太平洋是什么意思?  如何快速搭建支持数据库操作的智能建站平台?  建站之星后台管理:高效配置与模板优化提升用户体验  常州自助建站费用包含哪些项目?  建站之星后台密码遗忘或太弱?如何重置与强化?  网页制作模板网站推荐,网页设计海报之类的素材哪里好?  c# await 一个已经完成的Task会发生什么  企业宣传片制作网站有哪些,传媒公司怎么找企业宣传片项目?  网站建设制作需要多少钱费用,自己做一个网站要多少钱,模板一般多少钱?  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  网站设计制作公司地址,网站建设比较好的公司都有哪些?  官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站  如何在Golang中引入测试模块_Golang测试包导入与使用实践  建站主机默认首页配置指南:核心功能与访问路径优化  香港网站服务器数量如何影响SEO优化效果?  如何基于云服务器快速搭建网站及云盘系统?  网站制作多少钱一个,建一个论坛网站大约需要多少钱?    c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  如何在云主机快速搭建网站站点?  红河网站制作公司,红河事业单位身份证如何上传?  建站之星代理平台如何选择最佳方案?  企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?  如何选择高效可靠的多用户建站源码资源?  如何配置IIS站点权限与局域网访问?  名字制作网站免费,所有小说网站的名字?  新网站制作渠道有哪些,跪求一个无线渠道比较强的小说网站,我要发表小说?  开心动漫网站制作软件下载,十分开心动画为何停播?  如何在阿里云虚拟服务器快速搭建网站?  如何通过网站建站时间优化SEO与用户体验?  制作门户网站的参考文献在哪,小说网站怎么建立?  较简单的网站制作软件有哪些,手机版网页制作用什么软件?  如何通过智能用户系统一键生成高效建站方案?  详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)  制作网站的公司有哪些,做一个公司网站要多少钱?  教学网站制作软件,学习*后期制作的网站有哪些?  外贸公司网站制作哪家好,maersk船公司官网?  广州网站建站公司选择指南:建站流程与SEO优化关键词解析  建站之星安装后界面空白如何解决?  如何高效配置IIS服务器搭建网站?  模具网站制作流程,如何找模具客户?  如何打造高效商业网站?建站目的决定转化率  深圳企业网站制作设计,在深圳如何网上全流程注册公司?  定制建站是什么?如何实现个性化需求?  网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?  桂林网站制作公司有哪些,桂林马拉松怎么报名?  如何有效防御Web建站篡改攻击?  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。