前期准备
mule IDE
一个已启用的WebService服务。
这是我自己写的一个WebService服务,基于Springboot和CXF。里面有3个方法:
sayYes,无参
sayHello,参数为String
sayObject ,参数为Object
主要涉及到4个文件:
根据yml文件和cxfConfig文件的配置,wsdl的路径为:http://127.0.0.1:8080/spring/webServices/demoWs?wsdl
(项目的路径是spring)
下面开始Mule
1、新建一个mule项目
本人使用的mule IDE为anypoint Studio 6.5.1
填写好project name后,创建项目即可。注意不要勾选maven,因为在测试时发现,maven mule项目会报错,该错误如何处理,目前尚未找到解决方案。
2、画流程图
新建项目后,左边的项目结构中,会有一个蓝色的xml文件,打开该文件(默认也是打开该文件)。出现一个空白的界面。在右边的Mule palette中,分别拖取HTTP、Java、Webservice Consumer到xml文件中,如下图所示。
简单介绍一下,这是一个流程图意思为,从HTTP接收请求,然后把请求中的参数发到Java中进行处理,再把处理后的结果作为参数,传到webService中,最后把webService的返回结果返回给HTTP。
(1)配置Mule的HTTP入口
按照下图所示,建立新的HTTP Listener 。这里的作用相当于,为你的Mule项目建立入口。
然后在path中填入你想要的路径,此处的配置与上图的区别在于,上图是配置这个mule项目,这里是针对本流程的子路径(一个项目可以有多个流程,详见下文)
(2)通过Java转换传入参数
在mule的组件与组件之间、流与流之间是通过消息进行交互的,在mule中称为mule message。HTTP中获取到的参数,会传到Java中,其类型为Message。
把相关的json jar引入到项目:
在下图路径建立lib文件夹,并放入相应的jar包
在项目中刷新一下,然后在项目的properties中添加lib
然后开始写java代码
在Java中,创建3个package。分别用于保存entity、转换工具类、转换过程,如下图所示:
entity类
转换工具类
转换过程类
这类要继承AbstractMessageTransformer,这是mule提供的类。重写其方法transformMessage。红色箭头是需要注意的地方:
第一个param的key,要填写webservice所设置的参数名字(见本文章第一张图的@WebParam注解)
第二个箭头 要填写mule流程里想调用的方法名,即@WebMethod对应的的名字
第三个箭头要填写明明空间(targerNamespace),
填错了都会调用失败
39行代码跑完后,其String内容如下(也就是说,call webservice要以这样的格式拼xml):
下面那段String转换,其作用是把param的子标签(不含标签)中的"<"和">"替换掉。不然WebService在解释餐数时会报错:意外的元素 (uri:"", local:"name")。所需元素为(none)。这是因为sayHello的传参是String,CXF看到有xml的标签就会进一步解释,而不会把里面的内容都当做String。因此这里把"<"和">"替换掉,不让CXF继续解析下去。
换言之,如果传给Webservice的参数像下面那样,就不用替换<>。
当然,正常情况下不会出现我说的问题,只是我为了做一些特殊的测试,所以才要这样搞。
注意:后来我在进一步测试时,发现只要提前提取出param中的xml,放到map中,就可以不替换<>,详见另一篇文章的webservice优化。
(3)在流程中配置Java
(4)配置webservice consumer
这里可以选择调用哪个方法,如果方法不齐全,点一下reload WSDL按钮。注意,Java trans里面的方法名,要与这里选择的方法一致
尝试运行
右击流程图的空白地方,运行mule(再次提醒,webservice要在运行状态)
使用postmen,访问mule的http地址,传入参数name,age,可以看到返回结果。webservice的控制台也成功输出内容。
这里有个坑要说明一下,替换标签时,最初我是使用< &rt;分别去替换<和>,但是运行时mule提示rt报错,估计rt是一个关键字。所以我就用了+lt+和+qt+去替换<>。在WebService记得要替换回来。
后来发现,提前提取好param标签,放到map中再进行soap转换时,就不用替换<> 了。
3、调用无参Webservice
这里很简单,直接截图,不解释(xml to json非必要):
相关的代码例子下载地址如下:
https://blog.csdn.net/dl348/article/details/83185036
注意事项:
用postman call HTTP时,要做如下设置。做了这个设置后,message.getPayload()会是map格式,如果不加的话,则是BufferInputStream的格式。
后来,经过进一步的测试,发现上文还有可以优化的地方,写在另一篇文章里《Webservice优化,使用mule中json/xml的转换功能》。https://blog.csdn.net/dl348/article/details/83410087
下面的内容来自另一篇CSDN的博文,介绍了如何以String的形式获取http的参数。
一般来说,当使用POST方法传递JSON数据到HTTP组件后,此时如果放置一个Logger组件,会发现经过HTTP组件后,payload的类型实际是org.glassfish.grizzly.utils.BufferInputStream,因为经过HTTP后将负载变为了流的形式了。
如果需要还原为JSON格式字符串,方法有3个:
(1)在HTTP组件后,使用Object to String组件将payload转为String,最简单的方法。
(2)使用MEL表达式#[message.payloadAs(java.lang.String)]
(3)java中可以继承AbstractMessageTransformer,然后通过MuleMessage类的getPayloadAsString()方法。
如果你需要在java组件里面解析JSON字符串,那么可以使用org.json.simple里面的类来解析,这个jar包Mule里面已经引入,因此可以直接使用,代码如下:
但是上面的代码只支持JSON对象,如果JSON字符串是数组,则会出现类型转换错误