论坛首页 Java版 SOA

jax-ws 遇到带泛型的方法就不能正常导出了,抛出an operation already exists

浏览 2156 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2007-10-22 关键字: jax-ws, webservice, cxf
举个例子
对于采用springside的泛型DAO的service, 实现类存在泛型的接口方法实现,如果想要导出service同名接口方法的时候就会抛出
An operation with name [{http://examples.com/}get] already exists in this service
即使用@WebMethod(operationName="")来改方法的名字都没用.
难道说必须要牺牲泛型特性,一个一个方法来写?
请教各位该如何解决这个问题

@WebService
public interface CompanyService {
    Company get(Long id);
}


@WebService(
	endpointInterface="com.examples.CompanyService",
	serviceName="CompanyService")
public class CompanyManager extends HibernateEntityDao<Company> {
}


public class HibernateEntityDao<T> {
    T get(Long id) {
        ....
    }
}


如果启动服务就会
抛出异常:
Exception in thread "main" java.lang.IllegalArgumentException: An operation with name [{http://examples.com/}get] already exists in this service
at org.apache.cxf.service.model.InterfaceInfo.addOperation(InterfaceInfo.java:71)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createOperation(ReflectionServiceFactoryBean.java:380)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createInterface(ReflectionServiceFactoryBean.java:372)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:242)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:272)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:146)
at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:89)
at org.apache.cxf.frontend.AbstractEndpointFactory.createEndpoint(AbstractEndpointFactory.java:83)
at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:107)
at org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:147)
at org.apache.cxf.jaxws.EndpointImpl.getServer(EndpointImpl.java:287)
at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:227)
at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:179)
at org.apache.cxf.jaxws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:74)
at javax.xml.ws.Endpoint.publish(Unknown Source)
   
最后更新时间:2007-10-23
那是因为你采用的是doc/literal wrapped的方式...

你能否采用doc/literal bare的方式,用这种方式,就可以发布重载方法的service..

@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
   
0 请登录后投票
最后更新时间:2007-10-22
兄弟,我试过了,不行的.
   
0 请登录后投票
最后更新时间:2007-10-23
你能否把service 和 Manager再写详细些..

我这里看到你就发布一个方法:
Company get(Long id);

还有什么方法也是get(...)同名的吗?

希望能把service和 manager的代码再详细些,至少让我们看见2个get.的方法吧...
   
0 请登录后投票
最后更新时间:2007-10-23
如果你使用的是JaxWs front end 采用Java First 的话,是需要检查方法名是不是重复了。
还有我不知道你的@WebMethod(operationName="") 加在什么地方,我觉得如果是加在SEI CompanyService上
的话应该是没有问题的。
   
0 请登录后投票
最后更新时间:2007-10-22
jeff_yuchang 写道
你能否把service 和 Manager再写详细些..

我这里看到你就发布一个方法:
Company get(Long id);

还有什么方法也是get(...)同名的吗?

希望能把service和 manager的代码再详细些,至少让我们看见2个get.的方法吧...


和Company get(Long id)同名的就是HibernateEntityDao里面的T get(Long id);
HibernateEntityDao完整类很长,就是Springside那个类.
你看到的几乎就是全部的代码了
   
0 请登录后投票
最后更新时间:2007-10-22
jnn 写道
如果你使用的是JaxWs front end 采用Java First 的话,是需要检查方法名是不是重复了。
还有我不知道你的@WebMethod(operationName="") 加在什么地方,我觉得如果是加在SEI CompanyService上
的话应该是没有问题的。


@WebMethod(operationName="")我在CompanyService, HibernateEntityDao都加了,也不起作用.
   
0 请登录后投票
最后更新时间:2007-10-22
我也是
   
0 请登录后投票
最后更新时间:2007-10-23
不知道你对生成出来的WSDL有没有特殊的要求。
如果没有,你可是试着用Simple Front End来发布你的Service。

具体可以参考CXF wiki中的文档。
http://cwiki.apache.org/CXF20DOC/simple-frontend.html
   
0 请登录后投票
最后更新时间:2007-10-23
phew...

终于重现你这个错误了...
我猜想你应该是用<jaxws:endpont>标签来发布你的service吧?

只传递serviceBean Object给他,CXF这样会根据你的Impl类去反射,然后去生成wsdl,通过观察你的HibernateEntityDao, 他继承了HibernateGenericDao, 这个类里有重载的get方法, 跟泛型没多大关系..

这里,我有一个work around的方法. 就是不用JAX-WS API,用CXF的API:

JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
sf.setServiceClass(CompanyService.class);
sf.setAddress("http://localhost:9001/Hello");
CompanyManager impl = new CompanyManager();
sf.setServiceBean(impl);
sf.create();

你也可以通过spring的配置,标签应该是:<jaxws:server>

<jaxws:server serviceClass="**.CompanyService" serviceBean="#companyManager" address="/companyService">
</jaxws:server>

这样的话,CXF就是通过Interface去生成你的WSDL, 而不是根据你的Impl类去生成wsdl.就不会有重载的问题,如果在你的Interface上有重载的问题,你可以加@WebMethod(operationName="")的方式来解决.

我只测过代码的,配置文件没测过,你需要看cxf的jaxws.xsd来配置..不过我记得是那样的...
   
0 请登录后投票
论坛首页 Java版 SOA

跳转论坛:
JavaEye推荐