【问题标题】:Remap JAX-WS address重新映射 JAX-WS 地址
【发布时间】:2014-12-31 17:25:36
【问题描述】:

我的问题是我有一个由 jboss 在http://localhost:8080/A 发布的 Web 服务,其中A 是服务实现类;我想要一个自定义网址http://localhost:8080/B/C/D.ws

在 wsdl 中,soap:address 正确设置为 http://localhost:8080/B/C/D.ws

在战争部署期间,服务在“错误”地址发布:

INFO  [org.jboss.ws.cxf.metadata] Adding service endpoint metadata: id=org.example.ServiceImpl
 address=http://localhost:8080/ServiceImpl
 ...

我得到的最好的结果是 jboss 在错误的 url 发布 ws,然后通过 servlet 更改地址;但是对“正确”url 的 SOAP 调用返回了 404。这是/WEB-INF/cxf-servlet.xml

<?xml ... >
<beans ...
    xmlns:jaxws="http://cxf.apache.org/jaxws" ... >
    <jaxws:endpoint
        id="someId"
        implementor="org.example.ServiceImpl"
        address="/B/C/D.ws" />
</beans>

web.xml 中使用以下url-pattern

<servlet>
    <servlet-name>cxf</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>cxf</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

这是日志:

17:41:53,648 INFO  [org.jboss.ws.cxf.metadata] Adding service endpoint metadata: id=org.example.ServiceImpl
 address=http://localhost:8080/ServiceImpl
 ...
17:41:59,307 INFO  [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] Creating Service {... targetNamespace ...}ServiceImplService from class org.example.ServicePort
17:41:59,572 INFO  [org.apache.cxf.endpoint.ServerImpl] Setting the server's publish address to be /B/C/D.ws

谢谢

【问题讨论】:

    标签: java web-services soap jboss servlet-mapping


    【解决方案1】:

    我遇到了类似的问题,用这种方法解决了。

    web.xml中覆盖了服务实现的url模式,像这样:

    <servlet>
        <servlet-name>ServiceImpl</servlet-name>
        <servlet-class>org.example.ServiceImpl</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServiceImpl</servlet-name>
        <url-pattern>/B/C/D.ws</url-pattern>
    </servlet-mapping>
    

    和你一样我使用属性address来设置服务发布地址

    这适用于我在 JBoss AS 6.1 (cxf 2.3.1) 中


    编辑:

    要验证这在 JBoss EAP 6.2 中是否正常工作,请创建一个基于 jboss-eap-quickstarts/helloworld-ws/ 的简单 Web 项目,如下所示:

    服务类:

    @WebService(serviceName = "HelloWorldService", portName = "HelloWorld", name = "HelloWorld", endpointInterface = "org.jboss.as.quickstarts.wshelloworld.HelloWorldService", targetNamespace = "http://www.jboss.org/jbossas/quickstarts/wshelloworld/HelloWorld")
    public class HelloWorldServiceImpl implements HelloWorldService {
    
        @Override
        public String sayHello() {
            return "Hello World!";
        }
    
        @Override
        public String sayHelloToName(final String name) {
    
            /* Create a list with just the one value */
            final List<String> names = new ArrayList<String>();
            names.add(name);
    
            return sayHelloToNames(names);
        }
    
        @Override
        public String sayHelloToNames(final List<String> names) {
            return "Hello " + createNameListString(names);
        }
    
        /**
         * Creates a list of names separated by commas or an and symbol if its the last separation. This is then used to say hello to
         * the list of names.
         * 
         * i.e. if the input was {John, Mary, Luke} the output would be John, Mary & Luke
         * 
         * @param names A list of names
         * @return The list of names separated as described above.
         */
        private String createNameListString(final List<String> names) {
    
            /*
             * If the list is null or empty then assume the call was anonymous.
             */
            if (names == null || names.isEmpty()) {
                return "Anonymous!";
            }
    
            final StringBuilder nameBuilder = new StringBuilder();
            for (int i = 0; i < names.size(); i++) {
    
                /*
                 * Add the separator if its not the first string or the last separator since that should be an and (&) symbol.
                 */
                if (i != 0 && i != names.size() - 1)
                    nameBuilder.append(", ");
                else if (i != 0 && i == names.size() - 1)
                    nameBuilder.append(" & ");
    
                nameBuilder.append(names.get(i));
            }
    
            nameBuilder.append("!");
    
            return nameBuilder.toString();
        }
    }
    

    web.xml:

    <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
        <servlet>
            <servlet-name>HelloWorldService</servlet-name>
            <servlet-class>org.jboss.as.quickstarts.wshelloworld.HelloWorldServiceImpl</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>HelloWorldService</servlet-name>
            <url-pattern>/C/D.ws</url-pattern>
        </servlet-mapping>
    
    </web-app>
    

    使用jboss-web.xml 覆盖应用程序的根上下文:

    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="  
          http://www.jboss.com/xml/ns/javaee  
          http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd">
        <context-root>B</context-root>
    </jboss-web> 
    

    获取以下部署结果:

    11:24:10,371 INFO  [org.jboss.ws.cxf.metadata] (MSC service thread 1-7) JBWS024061: Adding service endpoint metadata: id=HelloWorldService
     address=http://localhost:8080/B/C/D.ws
     implementor=org.jboss.as.quickstarts.wshelloworld.HelloWorldServiceImpl
     serviceName={http://www.jboss.org/jbossas/quickstarts/wshelloworld/HelloWorld}HelloWorldService
     portName={http://www.jboss.org/jbossas/quickstarts/wshelloworld/HelloWorld}HelloWorld
     annotationWsdlLocation=null
     wsdlLocationOverride=null
     mtomEnabled=false
    11:24:10,583 INFO  [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] (MSC service thread 1-7) Creating Service {http://www.jboss.org/jbossas/quickstarts/wshelloworld/HelloWorld}HelloWorldService from class org.jboss.as.quickstarts.wshelloworld.HelloWorldService
    11:24:10,944 INFO  [org.apache.cxf.endpoint.ServerImpl] (MSC service thread 1-7) Setting the server's publish address to be http://localhost:8080/B/C/D.ws
    11:24:11,009 INFO  [org.jboss.ws.cxf.deployment] (MSC service thread 1-7) JBWS024074: WSDL published to: file:/C:/desarrollo/java/jboss/jboss-eap-6.2/standalone/data/wsdl/jboss-helloworld-ws.war/HelloWorldService.wsdl
    11:24:11,014 INFO  [org.jboss.as.webservices] (MSC service thread 1-3) JBAS015539: Iniciando service jboss.ws.port-component-link
    11:24:11,026 INFO  [org.jboss.as.webservices] (MSC service thread 1-3) JBAS015539: Iniciando service jboss.ws.endpoint."jboss-helloworld-ws.war".HelloWorldService
    

    当我访问http://localhost:8080/B/C/D.ws?wsdl

    <wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.jboss.org/jbossas/quickstarts/wshelloworld/HelloWorld" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="HelloWorldService" targetNamespace="http://www.jboss.org/jbossas/quickstarts/wshelloworld/HelloWorld">
    
    <!-- ... -->
      <wsdl:service name="HelloWorldService">
        <wsdl:port binding="tns:HelloWorldServiceSoapBinding" name="HelloWorld">
          <soap:address location="http://localhost:8080/B/C/D.ws"/>
        </wsdl:port>
      </wsdl:service>
    </wsdl:definitions>
    

    可以看这个例子的出处:https://github.com/fedesierr/jaxws-endpointurl

    另一种选择是使用反向代理 (apache) 并在 soap:address 中设置 url。

    希望对你有所帮助。

    【讨论】:

    • 它不起作用。我的&lt;url-pattern&gt;jaxws:endpoint address 是一样的。你把你的jaxws:endpoint放在哪里了? /WEB-INF/whatever-servlet.xml/WEB-INF/beans.xml/META-INF/cxf/cxf.xml ?
    • @vault 您使用的是什么版本的 JBoss?
    • JBoss EAP 6.2(评论必须至少有 15 个字符的长度。)
    • 没错。我今天早上用另一种类似的方法解决了这个问题(我没有提到我有一个 web 应用程序,我不能更改 jboss-web.xml)。你应该得到最好的答案。几分钟后,我将发布我的解决方案。感谢您的宝贵时间。
    • 嗨,我今天试过你的方法。它失败了,因为我的 Impl 类类型不是 servlet。有什么提示吗?谢谢
    【解决方案2】:

    所以,这就是我管理它的方式。我在 JBoss EAP 6.2 上,除了重新映射端点之外,我的第二个问题是保持我的 webapp servlet 可见。我的第三个问题是我必须管理的真正的 url 架构是:

    • /(网络应用)
    • /alpha/read/Name.ws
    • /alpha/write/Name.ws
    • /beta/read/Name.ws
    • /beta/write/Name.ws

    所以我不能:

    • 设置CXFServlet:&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
    • 改变jboss-web.xml&lt;context-root&gt;/&lt;/context-root&gt;

    解决方法:CXFServlets 定义 url 的第一部分,jaxws:endpoint address 第二部分。

    web.xml

    <servlet>
        <servlet-name>alpha</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <init-param>
            <param-name>config-location</param-name>
            <param-value>/WEB-INF/alpha.xml</param-value>    
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>beta</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <init-param>
            <param-name>config-location</param-name>
            <param-value>/WEB-INF/beta.xml</param-value>    
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet>
        <servlet-name>mywebapp</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <multipart-config>
            <location>/tmp</location>
            <max-file-size>10485760</max-file-size>
            <max-request-size>1048576</max-request-size>
            <file-size-threshold>10485760</file-size-threshold>
        </multipart-config>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>alpha</servlet-name>
        <!-- WARNING: This string becomes a prefix of jaxws:endpoint address -->
        <url-pattern>/alpha/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>beta</servlet-name>
        <!-- WARNING: This string becomes a prefix of jaxws:endpoint address -->
        <url-pattern>/beta/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>mywebapp</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    alpha.xml

    <beans xmlns="http://www.springframework.org/schema/beans" ... >
    
        <jaxws:endpoint id="alphaRead" 
               implementor="path.to.AlphaReadImpl"
               address="/read/Name.ws" />
    
        <jaxws:endpoint id="alphaWrite" 
               implementor="path.to.AlphaWriteImpl" 
               address="/write/Name.ws" />
    </beans>
    

    beta.xml

    <beans xmlns="http://www.springframework.org/schema/beans" ... >
    
        <jaxws:endpoint id="betaRead" 
               implementor="path.to.BetaReadImpl"
               address="/read/Name.ws" />
    
        <jaxws:endpoint id="betaWrite" 
               implementor="path.to.BetaWriteImpl" 
               address="/write/Name.ws" />
    </beans>
    

    【讨论】:

    猜你喜欢
    • 2016-09-15
    • 2011-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 2011-11-07
    相关资源
    最近更新 更多