Remap JAX-WS address

China☆狼群 提交于 2020-01-02 09:55:13

问题


My problem is that I have a web service that gets published by jboss at http://localhost:8080/A, where A is the service implementation class; I want a custom url http://localhost:8080/B/C/D.ws.

In the wsdl, soap:address is correctly set http://localhost:8080/B/C/D.ws.

During war deployment, service gets published at the "wrong" address:

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

The best I got was jboss publishing the ws at the wrong url, and then the address changed through a servlet; but a SOAP call to the "right" url returned a 404. This is /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>

With the following url-pattern in web.xml:

<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>

This was the log:

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

Thanks


回答1:


I had a similar problem and resolved with this approach.

In the web.xml overwrites the url pattern for the service implementation, like this:

<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>

Like you I use the property address to set the service publish address

This works for my in JBoss AS 6.1 (cxf 2.3.1)


EDIT:

To validate that this works correctly in JBoss EAP 6.2, create a simple web project based on jboss-eap-quickstarts/helloworld-ws/ as follows:

Service Class:

@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>

To overwrite the root context of the application using the 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> 

Getting the following result for the deploy:

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

When I access to 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>

You can see the source of this example: https://github.com/fedesierr/jaxws-endpointurl

Another alternative is to use a reverse proxy (apache) and set the url in the soap:address.

I hope this help.




回答2:


So, this is how I managed it. I'm on JBoss EAP 6.2 and, apart from remapping endpoints, my second problem was to keep my webapp servlet visible. My third problem is that the real schema of urls I have to manage is:

  • / (webapp)
  • /alpha/read/Name.ws
  • /alpha/write/Name.ws
  • /beta/read/Name.ws
  • /beta/write/Name.ws

So I could not:

  • set CXFServlet: <url-pattern>/*</url-pattern>
  • alter jboss-web.xml: <context-root>/</context-root>

The solution: CXFServlets define the first part of the url, jaxws:endpoint address the second part.

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>


来源:https://stackoverflow.com/questions/26741633/remap-jax-ws-address

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!