【问题标题】:CXF/Spring Injecting Top-Level Service Name and Namespace into JAX-WS InterfaceCXF/Spring 将顶级服务名称和命名空间注入 JAX-WS 接口
【发布时间】:2012-04-03 21:04:29
【问题描述】:

我正在使用基于 CXF 的 Web 服务,这与 CXF 网站 http://cxf.apache.org/docs/jax-ws-configuration.html 上的示例相似。此服务具有基于以下示例上下文的已实现端点:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://cxf.apache.org/jaxws 
        http://cxf.apache.org/schemas/jaxws.xsd">

    <jaxws:endpoint id="myServiceMembersImpl"
        implementor="#myService"
        endpointName="e:MyServiceMembersEndpoint"
        serviceName="s:MyServiceMembersService"
        address="http://localhost:8080/myservicemembers"
        xmlns:e="http://localhost:8080/myservicemembers/ns"
        xmlns:s="http://localhost:8080/myservicemembers/ns"/>

</beans>

那么,当然还有Java ...

界面:

package com.me.service;

@WebService
public interface MyService {

String MEMBER = "MEMBER";

@WebResult(name = MEMBER)
Member getMember(@WebParam(name = "memberId") long memberId) throws Exception;
     // ... 
     // more interface declarations 
     // ... 

} // end interface 

以及,实现:

package com.me.service.impl;

@WebService(endpointInterface = "com.me.service.MyService")
@Path("/")
public class MyServiceMembersImpl implements MyService {

@GET
@Path("/{id}")
@Consumes({ APP_JSON, APP_XML })
@Produces({ APP_JSON, APP_XML })
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public Member getMember(@PathParam("id") final long memberId) throws Exception {

        // ... 
        // business logic 
        // ... 
        return theMember; 

     } // end method 

} // end class 

返回的 WSDL 有点像这样开始:

<?xml version="1.0" encoding="UTF-8" ?> 
<wsdl:definitions name="MyServiceImplService" 
    targetNamespace="http://localhost:8080/myservicemembers/ns" 
    xmlns:ns1="**http://service.me.com/**" 
    xmlns:ns2="http://schemas.xmlsoap.org/soap/http" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:tns="http://localhost:8080/myservicemembers/ns" 
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <wsdl:import location="http://localhost:8080/myservicemembers?wsdl=**MyService**.wsdl" 
        namespace="**http://service.me.com/**" /> 
        <wsdl:binding name="MyServiceImplServiceSoapBinding" type="ns1:**MyService**">
<!-- ... --> 
</wsdl:definitions> 

在应用程序上下文中使用“jaxws:endpoint”元素来更改端点的设置相当简单。这充实了服务名称、端点名称和其他字段。但是,顶级接口在 WSDL 文件中仍然有发言权。上面的 STARRED 项来自顶级界面。 如何将值注入到 targetNamespace 和 serviceName 的顶级接口?

我这样做的充分理由包括 (1) 不想在 WSDL 中公开包名称和 (2) 希望在应用程序沿部署跑道向下移动时切换名称空间。因此我不能使用注释,因为它们是编译时值,我不能用属性占位符替换它们,并且我不会在生产层重新编译我的代码。

【问题讨论】:

  • 我愿意接受任何解决方案,包括静态块和直接访问器,只要它们可以通过属性替换进行设置。

标签: java spring jakarta-ee jax-ws cxf


【解决方案1】:

您可以通过在 Spring 配置中使用 JaxWsServerFactoryBean 而不是使用 &lt;jaxws:endpoint&gt; 以编程方式创建服务来做到这一点。以编程方式进行创建可为您提供更多控制权。

例如:

@Autowired
var myServiceImpl: MyService = _

val propMap = mutable.HashMap[String, AnyRef]("org.apache.cxf.logging.FaultListener"->faultListener.asInstanceOf[AnyRef])

val sf = new JaxWsServerFactoryBean
sf.setServiceBean(myServiceImpl)
sf.setAddress("/myservice")
sf.setServiceName(new QName(WEB_SERVICE_NAMESPACE, "myService", "MyService"))
sf.setProperties(propMap)
sf.create

【讨论】:

猜你喜欢
  • 2011-07-19
  • 1970-01-01
  • 1970-01-01
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 2012-12-24
  • 1970-01-01
相关资源
最近更新 更多