Version 3

    JSE Server Side Programming Model

     

    The JSE server side programming model is about exposing plain java service endpoints.

    The JSE is deployed as a standard war archive plus an additional webservices.xml deployment descriptor.

     

     

    Service Endpoint Interface

     

    The SEI declares the endpoint implementation methods that are to be exposed as web service operations.

    For the JSE we use the same service endpoint interface as for the EJB service endpoint.

     

    Web Service Description Language

     

    To describe the functionality of a service endpoint, we use an interoperable document format, the WSDL.

    The Java Web Service Development Pack comes

    with the tools needed to generate the WSDL from the service endpoint interface.

     

     

     

    To generate a WSDL that uses document/literal, you would use something similar to:

       wscompile -cp ../../output/classes -gen:server -f:documentliteral -d WEB-INF/wsdl -mapping WEB-INF/OrganizationServiceJSE_Mapping.xml config.xml
    
       <configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
        <service name="OrganizationServiceJSE"
          targetNamespace="http://com.underworld.crimeportal"
          typeNamespace="http://com.underworld.crimeportal/types"
          packageName="com.underworld.crimeportal">
          <interface name="com.underworld.crimeportal.OrganizationEndpoint"></interface>
        </service>
       </configuration>
    

     

    The options to wscompile are described as part

    of the jaxrpc documentation that comes with the JWSDP.

     

    The webservice  tutorial is also a good starting point.

     

     

     

     

    Here is a WSDL, that corresponds to the service endpoint interface from above.

     

     

       <definitions name="OrganizationServiceJSE" targetNamespace="http://com.underworld.crimeportal"
          xmlns:tns="http://com.underworld.crimeportal" xmlns="http://schemas.xmlsoap.org/wsdl/"
          xmlns:ns2="http://com.underworld.crimeportal/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
    
        <types>
          <schema targetNamespace="http://com.underworld.crimeportal/types" ...>
            <complexType name="getContactInfo">
              <sequence>
                <element name="String_1" type="string" nillable="true"></element>
              </sequence>
            </complexType>
            <complexType name="getContactInfoResponse">
              <sequence>
                <element name="result" type="string" nillable="true"></element>
              </sequence>
            </complexType>
            <element name="getContactInfo" type="tns:getContactInfo"></element>
            <element name="getContactInfoResponse" type="tns:getContactInfoResponse"></element>
          </schema>
        </types>
    
        <message name="OrganizationEndpoint_getContactInfo">
          <part name="parameters" element="ns2:getContactInfo"></part>
        </message>
        <message name="OrganizationEndpoint_getContactInfoResponse">
          <part name="result" element="ns2:getContactInfoResponse"></part>
        </message>
    
        <portType name="OrganizationEndpoint">
          <operation name="getContactInfo">
            <input message="tns:OrganizationEndpoint_getContactInfo"/>
            <output message="tns:OrganizationEndpoint_getContactInfoResponse"></output>
          </operation>
        </portType>
    
        <binding name="OrganizationEndpointBinding" type="tns:OrganizationEndpoint">
          <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
          <operation name="getContactInfo">
            <soap:operation soapAction=""></soap:operation>
            <input>
              <soap:body use="literal"></soap:body>
            </input>
            <output>
              <soap:body use="literal"></soap:body>
            </output>
          </operation>
        </binding>
    
        <service name="OrganizationServiceJSE">
          <port name="OrganizationEndpointPort" binding="tns:OrganizationEndpointBinding">
            <soap:address location="REPLACE_WITH_ACTUAL_URL"></soap:address>
          </port>
        </service>
      </definitions>
    

     

     

    In this example we use the 'document' style wich results in two XML schema type definitions in the wsdl.

    There is a lot to say about the different encoding styles.

     

    Here is a selection of good articles

     

     

    Also note, that Axis defaults to rpc/encoded, which strictly speaking is not J2EE compliant because the basic

    profile does not allow it.

     

    JAX-RPC Mapping Files

     

    In addition to a service endpoint interface and a WSDL file, the Web Service must include a JAX-RPC mapping file.

     

     

    The example below shows the complete jaxrpc mapping as generated by wscompile.

     

      <java-wsdl-mapping ...>
        <package-mapping>
          <package-type>com.underworld.crimeportal</package-type>
          <namespaceURI>http://com.underworld.crimeportal/types</namespaceURI>
        </package-mapping>
        <package-mapping>
          <package-type>com.underworld.crimeportal</package-type>
          <namespaceURI>http://com.underworld.crimeportal</namespaceURI>
        </package-mapping>
        <java-xml-type-mapping>
          <java-type>com.underworld.crimeportal.OrganizationEndpoint_getContactInfo_ResponseStruct</java-type>
          <root-type-qname xmlns:typeNS="http://com.underworld.crimeportal/types">typeNS:getContactInfoResponse</root-type-qname>
          <qname-scope>complexType</qname-scope>
          <variable-mapping>
            <java-variable-name>result</java-variable-name>
            <xml-element-name>result</xml-element-name>
          </variable-mapping>
        </java-xml-type-mapping>
        <java-xml-type-mapping>
          <java-type>com.underworld.crimeportal.OrganizationEndpoint_getContactInfo_RequestStruct</java-type>
          <root-type-qname xmlns:typeNS="http://com.underworld.crimeportal/types">typeNS:getContactInfo</root-type-qname>
          <qname-scope>complexType</qname-scope>
          <variable-mapping>
            <java-variable-name>String_1</java-variable-name>
            <xml-element-name>String_1</xml-element-name>
          </variable-mapping>
        </java-xml-type-mapping>
        <service-interface-mapping>
          <service-interface>com.underworld.crimeportal.OrganizationServiceJSE</service-interface>
          <wsdl-service-name xmlns:serviceNS="http://com.underworld.crimeportal">serviceNS:OrganizationServiceJSE</wsdl-service-name>
          <port-mapping>
            <port-name>OrganizationEndpointPort</port-name>
            <java-port-name>OrganizationEndpointPort</java-port-name>
          </port-mapping>
        </service-interface-mapping>
        <service-endpoint-interface-mapping>
          <service-endpoint-interface>com.underworld.crimeportal.OrganizationEndpoint</service-endpoint-interface>
          <wsdl-port-type xmlns:portTypeNS="http://com.underworld.crimeportal">portTypeNS:OrganizationEndpoint</wsdl-port-type>
          <wsdl-binding xmlns:bindingNS="http://com.underworld.crimeportal">bindingNS:OrganizationEndpointBinding</wsdl-binding>
          <service-endpoint-method-mapping>
            <java-method-name>getContactInfo</java-method-name>
            <wsdl-operation>getContactInfo</wsdl-operation>
            <wrapped-element></wrapped-element>
            <method-param-parts-mapping>
              <param-position>0</param-position>
              <param-type>java.lang.String</param-type>
              <wsdl-message-mapping>
                <wsdl-message xmlns:wsdlMsgNS="http://com.underworld.crimeportal">wsdlMsgNS:OrganizationEndpoint_getContactInfo</wsdl-message>
                <wsdl-message-part-name>String_1</wsdl-message-part-name>
                <parameter-mode>IN</parameter-mode>
              </wsdl-message-mapping>
            </method-param-parts-mapping>
            <wsdl-return-value-mapping>
              <method-return-value>java.lang.String</method-return-value>
              <wsdl-message xmlns:wsdlMsgNS="http://com.underworld.crimeportal">wsdlMsgNS:OrganizationEndpoint_getContactInfoResponse</wsdl-message>
              <wsdl-message-part-name>result</wsdl-message-part-name>
            </wsdl-return-value-mapping>
          </service-endpoint-method-mapping>
        </service-endpoint-interface-mapping>
      </java-wsdl-mapping>
    

     

    Packaging the service endpoint

     

    The standard deployment descriptor for web components web.xml, declares the service endpoint implementation.

     

       <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">
    
         <servlet>
           <servlet-name>OrganizationEndpoint</servlet-name>
           <servlet-class>com.underworld.crimeportal.web.OrganizationEndpointImpl</servlet-class>
         </servlet>
    
         <servlet-mapping>
           <servlet-name>OrganizationEndpoint</servlet-name>
           <url-pattern>/exactpath/jse</url-pattern>
         </servlet-mapping>
       </web-app>
    

     

    Note, the service endpoint implementation is defined in the <servlet-class> element. This is highly confusing

    because it is not a servlet at all, but a simple plain java object.

     

    Additionally, we need the J2EE Web Service deployment descriptor, webservices.xml

     

       <webservices
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:impl="http://com.underworld.crimeportal/ws4ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://www.ibm.com/webservices/xsd/j2ee_web_services_1_1.xsd"
         version="1.1">
    
         <webservice-description>
           <webservice-description-name>OrganizationServiceJSE</webservice-description-name>
           <wsdl-file>WEB-INF/wsdl/server-web.wsdl</wsdl-file>
           <jaxrpc-mapping-file>WEB-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file>
           <port-component>
             <port-component-name>PortComponent</port-component-name>
             <wsdl-port>OrganizationEndpointPort</wsdl-port>
             <service-endpoint-interface>com.underworld.crimeportal.OrganizationEndpoint</service-endpoint-interface>
             <service-impl-bean>
               <servlet-link>OrganizationEndpoint</servlet-link>
             </service-impl-bean>
           </port-component>
         </webservice-description>
       </webservices>
    

     

    Deploy the Web Service to JBoss

     

    When you deploy the war that contains all the artifacts we just taked about, you should see something like this in the

    JBoss console

     

       13:24:49,453 INFO  [TomcatDeployer] deploy, ctxPath=/samples-server-web, ...
       13:24:49,625 INFO  [WSDLFilePublisher] WSDL published to: file:/.../server/default/data/wsdl/samples-server-web.war/server-web.wsdl
       13:24:49,718 INFO  [AxisService] WSDD published to: ...\server\default\data\wsdl\samples-server-web.war\OrganizationServiceJSE.wsdd
       13:24:49,718 INFO  [AxisService] Web Service deployed: http://localhost:8080/samples-server-web/exactpath/jse
    

     

    To see the WSDL that describes this service, point your browser to

     

       http://localhost:8080/samples-server-web/exactpath/jse?wsdl
    

     

    you will see the WSDl from above, with a corrected location.

     

    Accessing the Service from Java

     

    This service can now be accessed from any webservice client. Here is a simple test case, that shows how a java client

    would first obtain the WSDL from the remote location, and then invoke getContactInfo on the service endpoint

    interface. Please note that in the case of document style web services, the client should be given a pointer to

    the jaxrpc-mapping.xml file, which the standard JAXRPC javax.xml.rpc.ServiceFactory does not support.

     

       public void testWebServiceAccess() throws Exception
       {
          URL wsdlURL = new URL("http://localhost:8080/samples-server-jse/exactpath/jse?wsdl");
          URL mappingURL = new File(resourcePath + "/resources/WEB-INF/OrganizationServiceJSE_Mapping.xml").toURL();
          QName serviceName = new QName("http://com.underworld.crimeportal", "OrganizationServiceJSE");
    
          ServiceFactoryImpl factory = (ServiceFactoryImpl)ServiceFactory.newInstance();
          Service service = factory.createService(wsdlURL, mappingURL, null, serviceName, null);
          OrganizationEndpoint endpoint = (OrganizationEndpoint)service.getPort(OrganizationEndpoint.class);
    
          String info = endpoint.getContactInfo("mafia");
          assertEquals("The 'mafia' boss is currently out of office, please call again.", info);
       }