CXF和Metro的OneWay实现与JSR-181规范不一致的情况
最近朋友问我了Web Services中一些关于MEP的问题。在讨论问题的过程中偶然提及了JSR-181规范中的Oneway注解。本来打算直接写一篇MEP的东东,没想到翻看Oneway的过程中发现了规范与实现的某些不符合,于是先有了这篇很短的B文。
先看一下Oneway在JSR-181 v2.0的规范中有着如下明确说明(这段直接引用自规范文档):
4.3 Annotation: javax.jws.Oneway
4.3.1 Description
Indicates that the given web method has only an input message and no output. Typically, a oneway method returns the thread of control to the calling application prior to executing the actual business method. A JSR-181 processor is REQUIRED to report an error if an operation marked @Oneway has a return value, declares any checked exceptions or has any INOUT or OUT parameters.但是如果你在用CXF或者Metro开发Web Services的话,就会发现实际使用Oneway注解和规范的要求有些区别。
在CXF中我们可以声明如下的方法:
@Oneway
public String serve(String biz) throws Exception {
System.out.println("oneway.cxf - " + biz);
return "oneway.cxf - " + biz;
}编译之后,用CXF提供的java2ws工具并加上-frontend jaxws 生成WSDL的话,会发现生成的WSDL文件中简单的忽略了该方法的返回值。
下面是我得到的WSDL的片段:
<wsdl:portType name="OnewayImpl">
<wsdl:operation name="serve">
<wsdl:input name="serve" message="tns:serve">
</wsdl:input>
</wsdl:operation>
</wsdl:portType>在Metro中依然可以用同样的声明:
@Oneway
public void oneway(String oneway) {
System.out.println("metro.oneway - " + oneway);
// return "metro.oneway - " + oneway;
}如果把该方法声明为有返回值的并抛出异常,那么在用Sun提供的apt来编译的时候,会报告错误说该方法带Oneway注解但却有返回值并抛出异常。
改为void并去掉异常,正常通过apt的编译。Sun也提供了一个从class生成WSDL的工具--wsgen,使用这个工具来处理CXF的java2ws所处理的代码片段,会报告错误说该方法标注为Oneway却带有返回值和异常。
不论是CXF还是Metro,这些有输入参数的Oneway,运行起来都没有问题。
从上面的现象来看,不管是CXF还是Metro都不甚符合JSR-181的规范中说明的(注意规范引用黑体部分)。
就我个人来讲我更倾向于Metro的实现,对Oneway来说,返回值和异常是没有任何意义的(异常也可以看作是一种变态返回)。尽量早地报告无意义状态是有意义的(绕嘴-_-)。所以Metro提供的编译工具(apt)在几乎是最早的时候就报告了错误状态,当然如果有Eclipse的JSR-181插件的话在代码编辑阶段报告错误就更好了(或许有我不知道)。CXF的问题我认为是没有足够的错误提示,而且又没有任何提示地忽略了可能有意义的代码。就 JSR-181本身来讲,不允许任何输入参数显得太过苛刻,这样的方法意味着只能干最基本的事情。也许就是这个原因,CXF和Metro都允许 Oneway输入参数的存在。
btw:我的CXF是2.2,Metro是1.4。

Comments
希望跟你联系
Hi 竹十一,
今天偶然间看到你写的东西,觉得很受启发。
我本人现在一家美资软件公司的中国研发中心工作,最近我们这里正在为一个新产品的研发成立了一个新的团队,现在有两个高级的研发职位正在内部招聘。我觉得你很适合我们这个职位,如果你愿意过来试试的话请和我联系。 leeon.li@ca.com
Thanks,
Leeon
Post new comment