使用mule生成WSDL中文乱码问题解决方法

开发 后端
在发布Web服务 的时候,WSDL 作为服务的描述,里面有一个标签可以写入中文,是用来作为注解来写入描述性信息的,这个标签就是。

在发布Web服务 的时候,WSDL 作为服务的描述,里面有一个标签可以写入中文,是用来作为注解来写入描述性信息的,这个标签就是。OECP平台中使用开源ESB总线mule 来做webService 发布使用.发布时就遇到了中文 描述乱码 问题,经过一天多的时间来翻阅mule和cxf的源代码,问题最终被解决。这里记录一下解决的过程和方法。

mule 内使用的spring-cxf来将一个java方法转换为webService 。cxf有一个annotation是生成wsdl 中的 标签用的,这个annotation就是@WSDLDocumentation 。但是这个标签使用后,生成的WSDL 文件,中文 却显示成了乱码 。

经过测试发现,单纯使用Spring-cxf时,@WSDLDocumentation 不会产生乱码 。这就说明问题出在mule 上。只能翻一下mule 的源代码来查找原因了。由于找不到与当前使用的jar包版本相同的源代码,只能使用升级版的源码,调试的时候发现升级的改动比较大,删掉的以前的一些方法和代码修改也蛮多,错行缺行导致调试可读性极差,让我一直看了一天多。比较安慰的是最终还是找到了问题原因并解决了。下面就具体说一下原理。

我们知道发布WebService 以后,使用url+?wsdl的方式访问,将会获取到服务描述文件wsdl 文件.mule 中发布服务后,使用这种方式访问服务器将会启动一个线程,线程调用链如下图:

 

标记①下面,是http请求引起的mule 事件级联链条,是mule 内部的架构机制,这个不是我们现在要所关注的.重点在第②行,红色标记出的OutputStream就是用来承载wsdl 文件流的对象,实际上它是一个ByteArrayOutputStream。在图上⑥的位置执行完后,这个Stream将被写入完成。前面的每一个步骤中文字符 的编码都是正确的,即便是写入到Stream中,字符的byte编码也没有问题。但是,此时我们发现查看这个Stream的内容时,却看到了乱码 。这是为什么呢?为什么Stream中存储的byte没错,但是却能看到乱码呢?

经常调试程序的朋友们知道,当我们查看一个对象的内容时,对象查看器,将调用对象的toString方法。经检查发现ByteArrayOutputStream的toString方法果然被重写:

java 代码

  1. public synchronized String toString() {  
  2. return new String(buf, 0 , count);  

ByteArrayOutputStream使用buffer中所有的byte创建并返回了一个String对象。这里注意,创建String的时候并没有指定编码格式。那么它用的是什么编码格式?我们去String中看看,String使用了StringCoding来转化byte为char数组,而其中选用的编码格式是从Charset.defaultCharset()得来的。从JDK的API中我们能找到了这个方法,上面是这么说的:

 

 

在我们的服务器运行环境中得到的默认编码 格式为GBK。于是乱码形成的原因找到了:由于Spring-cxf生成服务的wsdl 时用的是UTF-8编码,而被mule 错误的使用了服务器运行环境默认编码GBK,所以UTF-8下的正常显示中文 最终被显示为乱码 了。

mule 中的类CxfInboundMessageProcessor第201行:

msg = out.toString();

这就是乱码 产生的根源,在将字节流转为字符串的时候,没有指定编码格式,而默认使用了GBK,就是wsdl 文件乱码 的原因。

解决这个问题又两种方案:

1. 改变jvm的默认字符编码。

2. 修改CxfInboundMessageProcessor类的源代码。

第一种方案通过修改服务器的启动参数,追加一段“-Dfile.encoding=UTF-8”,就可以改变服务器的java运行环境。此时启动服务器时我们会发现,虽然我们的WSDL中文不再出现乱码了,但是服务器控制台显示的中文 却全都成了乱码 。我猜是服务器的日志输出依赖于操作系统的默认字符集吧。暂且不说这个日志乱码 问题,即使不存在这个问题我认为这种方案也是不太合适的。wsdl 是否出现乱码依赖于运行服务器的默认字符集,对于OECP平台来说是不可控的。OECP平台使用什么样的字符编码应该依赖于应用自己的配置。

于是决定修改mule 的源代码,比较幸运的是CxfInboundMessageProcessor这个类,在升级的过程中没有改动,不然就要反编译来获取源码了。

将201行的msg = out.toString();修改为如下代码:

java 代码

  1. String enc = event.getMuleContext().getConfiguration().getDefaultEncoding();  
  2. msg = out.toString(enc); 

从mule 的配置中得到配置的编码格式,并在将Stream转换为String的时候指定使用此编码格式.至此问题解决了.

我们可以在使用mule发布服务时,使用WSDLDocumentation 标签来为服务添加描述了.wsdl 作为WebService 的描述,如果没有注释性的文字,wsdl 描述可读性实在不是很好. WSDLDocumentation 标签就是作为这种描述存在的,如果你想在WSDL 中加入中文 的描述这个标签应该是唯一的选择.如果你使用的也是mule ,也遇到了中文 的乱码 问题,希望可上面的内容可以帮助你。

作者本人将原文转发到此,原文地址为:http://www.oecp.cn/hi/slx/blog/2315

文章地址:http://songlixiao.iteye.com/blog/1085140

【编辑推荐】

  1. Oracle计划修复Java SE中的17个漏洞
  2. Oracle推出Java SE6漏洞补丁名为Update 26
  3. Spring整合DWR comet 实现无刷新 多人聊天室
责任编辑:艾婧 来源: ITEYE
相关推荐

2009-07-17 14:33:05

Jython中文问题

2011-03-18 18:47:34

QtMySQL

2009-06-09 15:51:07

Java ee中文问题解决方法

2009-02-18 14:28:23

编码乱码JSP

2009-08-14 13:49:58

Rails中文问题

2013-06-14 10:48:53

IIS 7

2009-12-28 10:56:45

WPF Image

2010-07-29 15:28:47

Flex安全沙箱

2009-02-26 11:13:41

Weblogic中间件JSP

2010-06-09 16:33:46

Cacti中文

2010-05-26 11:08:33

SVN管理

2010-08-03 09:12:52

Flex安全沙箱

2009-06-19 11:16:14

java web中文乱码

2011-06-13 16:16:32

Qt 中文问题

2011-05-18 14:00:30

在线备份

2010-01-13 21:06:37

双绞线

2009-11-17 10:43:59

ubuntu 9.10输入法解决方法

2010-05-11 15:09:51

Unix系统

2009-10-29 10:04:57

VB.NET Read

2009-07-02 13:26:32

JSP中文乱码
点赞
收藏

51CTO技术栈公众号