获取CXF端点的URL

时间:2012-10-02 18:03:13

标签: java web-services cxf

情况

我正在使用Apache CXF 2.6.2将Web服务部署到Tomcat服务器。我正在使用CXFServlet和以下基于Spring的配置导出服务:

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
         http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

    <jaxws:endpoint id="test_endpoint"
                    implementor="org.xyz.TestImpl"
                    address="/test"/>

    <bean id="testBean" class="org.xyz.TestBean">
        <property name="endpoint" ref="test_endpoint" />
    </bean>
</beans>

在我的示例部署中,CXFServlet正在使用相对路径/服务,例如,由TestImpl类实现的Web服务可用作http://domain.com/tomcat-context/services/test TestBean类有一个端点的setter,它由Spring设置。

目标

我想使用endpoint字段确定TestBean类中端点test_endpoint提供的地址(URL)。结果应该是“http://domain.com/tomcat-context/services/test”。

我尝试了什么

log.info("Endpoint set to " + endpoint);
log.info("Address: " + endpoint.getAddress());
org.apache.cxf.jaxws.EndpointImpl ep = (org.apache.cxf.jaxws.EndpointImpl) endpoint;
log.info("Other Address: " + ep.getBindingUri());
log.info("Props: " + ep.getProperties());

但结果只是

Address: /Sachbearbeiter
Other Address: null
Props: {}

如何获取完整的网址?有没有办法没有自己构建它?

3 个答案:

答案 0 :(得分:1)

您是否尝试过围绕CXF消息查看它是否在其中一个属性中?我使用Camel和CXF并获得这样的实际CXF消息:

Message cxfMessage = exchange.getIn().getHeader(CxfConstants.CAMEL_CXF_MESSAGE, Message.class);

你应该能够像普通的CXF一样获得CXF消息:

PhaseInterceptorChain.getCurrentMessage()

请参阅此网址:Is there a way to access the CXF message exchange from a JAX-RS REST Resource within CXF?

从那里,您可以获得以下属性:

org.apache.cxf.request.url=someDomain/myURL

答案 1 :(得分:1)

您可以使用以下代码构建网址。您可以根据自己的环境进行编辑。

String requestURI = (String) message.get(Message.class.getName() + ".REQUEST_URI");
Map<String, List<String>> headers = CastUtils.cast((Map) message.get(Message.PROTOCOL_HEADERS));
List sa = null;
String hostName=null;
    if (headers != null) {
            sa = headers.get("host");
        }

        if (sa != null && sa.size() == 1) {
            hostName = "http://"+ sa.get(0).toString()+requestURI;
        }

答案 2 :(得分:1)

我有同样的要求。但是,我认为仅从端点定义检索主机和端口是不可能的。正如您所提到的,endpoint.getAddress()只提供服务名称而不是整个网址。这是我的理由:

让我们检查一个预期的端点地址:http://domain.com/tomcat-context/CXFServlet-pattern/test

CXF运行时在servlet容器上运行。中间两部分(tomcat-context/CXFServlet-pattern)实际上由servlet容器处理,可以从ServletContext检索。您可以在Spring中实现org.springframework.web.context.ServletContextAware。最后一部分(test是服务名称)由CXF处理,可以由endpoint.getAddress()检索。但是schema://host:port的第一部分超出了这一部分并且受到控制通过主机配置。例如,您的服务可以接收http://domain.comhttps://doman.com的请求,而CXF运行时在部署服务时从不知道它。但是,当请求到来时,可以从其他帖子中提到的请求或消息中检索它。

HTH