Search code examples
jakarta-eedeploymentjava-metro-framework

Metro WebService - How to Configure/Deploy?


I have a Metro client to a webservice that works fine. However, we don't have access to the service in our lab environment, so I wrote a mock service for testing. I'm having issues understanding endpoints and how to set them up.

I'm passing the URL into the client constructor and setting it in the request context like this:

    // Set the service port URL
    BindingProvider bindingProvider = ((BindingProvider) port);
    Map<String, Object> context = bindingProvider.getRequestContext();
    context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, serviceURL);

For my mock service, I'm using the URL of the war as given to me by Glassfish when I click on the "Launch" link in the list of applications (http://myserver:80/MySoapService).

The code has been generated from the wsdl provided to us. The WebService interface looks something like this:

@WebService(name = "My_Soap_Service", targetNamespace = "urn:My.DataEntityModel")
@XmlSeeAlso({
    ObjectFactory.class
})
public interface MySoapService {


    @WebMethod(operationName = "Ping", action = "urn:My.DataEntityModel/Ping")
    @WebResult(name = "PingResult", targetNamespace = "urn:My.DataEntityModel")
    @RequestWrapper(localName = "Ping", targetNamespace = "urn:My.DataEntityModel", className = "dataentitymodel.Ping")
    @ResponseWrapper(localName = "PingResponse", targetNamespace = "urn:My.DataEntityModel", className = "dataentitymodel.PingResponse")
    public String ping(
        @WebParam(name = "inputString", targetNamespace = "urn:My.DataEntityModel")
        String inputString);


    @WebMethod(operationName = "ProcessRecordResult", action = "urn:My.DataEntityModel/ProcessRecordResult")
    @WebResult(name = "ProcessRecordResultResult", targetNamespace = "urn:My.DataEntityModel")
    @RequestWrapper(localName = "ProcessRecordResult", targetNamespace = "urn:My.DataEntityModel", className = "dataentitymodel.ProcessRecordResult")
    @ResponseWrapper(localName = "ProcessRecordResultResponse", targetNamespace = "urn:My.DataEntityModel", className = "dataentitymodel.ProcessRecordResultResponse")
    public String ProcessRecordResult(
        @WebParam(name = "recordStatusXML", targetNamespace = "urn:My.DataEntityModel")
        String recordStatusXML);


    @WebMethod(operationName = "ProcessBatchResult", action = "urn:My.DataEntityModel/ProcessBatchResult")
    @WebResult(name = "ProcessBatchResultResult", targetNamespace = "urn:My.DataEntityModel")
    @RequestWrapper(localName = "ProcessBatchResult", targetNamespace = "urn:My.DataEntityModel", className = "dataentitymodel.ProcessBatchResult")
    @ResponseWrapper(localName = "ProcessBatchResultResponse", targetNamespace = "urn:My.DataEntityModel", className = "dataentitymodel.ProcessBatchResultResponse")
    public String processBatchResult(
        @WebParam(name = "batchStatusXML", targetNamespace = "urn:My.DataEntityModel")
        String batchStatusXML);

}

My web.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">

<web-app>
    <listener>
        <listener-class>
            com.sun.xml.ws.transport.http.servlet.WSServletContextListener </listener-class>
    </listener>
    <servlet>
        <servlet-name>MySoapService</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>MySoapService</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>
</web-app>

I'm having trouble setting up my sun-jaxws.xml file. Initially it looked like this:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints
        xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
        version="2.0">
    <endpoint
            name="MyService"
            implementation="my.package.MySoapServiceImpl"
            url-pattern="/"
            wsdl-location="WEB-INF/wsdl/MySoapService.wsdl"/>
</endpoints>

But my client got back a "Web Services" HTML page which described the service. I haven't been able to find any practical info/examples of sun-jaxws.xml files, but figured I needed an endpoint for each of the methods in the webservice. So I changed it to look like this:

<?xml version="1.0" encoding="UTF-8"?>
<endpoints
        xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
        version="2.0">
    <endpoint
            name="Ping"
            implementation="my.package.MySoapServiceImpl"
            url-pattern="/ping"
            wsdl-location="WEB-INF/wsdl/MySoapService.wsdl"/>

    <endpoint
            name="ProcessRecord"
            implementation="my.package.MySoapServiceImpl"
            url-pattern="/processRecordResult"
            wsdl-location="WEB-INF/wsdl/MySoapService.wsdl"/>

    <endpoint
            name="ProcessBatch"
            implementation="my.package.MySoapServiceImpl"
            url-pattern="/processBatchResult"
            wsdl-location="WEB-INF/wsdl/MySoapService.wsdl"/>

</endpoints>

Now I get a 404 error when my client tries to access the service.

I don't know if I'm setting up the sun-jaxws.xml and/or web.xml files incorrectly, using the wrong URL in the client or something completely different.

Can somebody tell me what I'm doing wrong and/or point me to a resource that explains this in a easy-to-understand way?


Solution

  • I got it working and in case this is useful to others, here's my config...

    web.xml

    <web-app>
        <listener>
            <listener-class>
                com.sun.xml.ws.transport.http.servlet.WSServletContextListener </listener-class>
        </listener>
        <servlet>
            <servlet-name>MySoapService</servlet-name>
            <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>MySoapService</servlet-name>
            <url-pattern>/service</url-pattern>
        </servlet-mapping>
        <session-config>
            <session-timeout>60</session-timeout>
        </session-config>
    </web-app>
    

    sun-jaxws.xml

    Even though I found many examples/blogs which state that port and service elements in the sun-jaxws.xml file are optional, I couldn't get it to work without them. Also, I found posts that state the sun-jaxws.xml file itself is optional if deploying on Glassfish. However, again I found it mandatory.

    <?xml version="1.0" encoding="UTF-8"?>
    <endpoints
            xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
            version="2.0">
        <endpoint
            name="MyService"
            interface="my.package.MySoapServiceInterface"
            implementation="my.package.MySoapServiceImpl"
            service="{urn:my.xmlns.tns.urn}My_Soap_Service"
            port="{urn:my.xmlns.tns.urn}My_Port_Type"
            url-pattern="/service"
            wsdl="WEB-INF/wsdl/MyService.wsdl"
    </endpoints>
    

    Web Service Impl Class

    I found it necessary to include the endpointInterface in the WebSevice annotation:

    @WebService(endpointInterface="my.package.MySoapServiceInterface")
    public class MySoapServiceImpl implements MySoapServiceInterface
    

    and of course each web service method needs to annotated with WebMethod:

    @WebMethod
    public String doSomething(String string)