blogger templates blogger widgets
This is part of a list of blog posts.
To browse the contents go to

JAX-RPC

Create a Dynamic Web application which will act as your WS server.

Create a wsdl document within this project (could be anywhere).


Change the default namespace (just for fun) http://www.example.org/Calculator/ to http://server.com/Calculator/


Note that the endpoint address is set to the default namespace. You could change this now or could be changed automatically when we generate Server skeleton code.

I changed it. And also the operation name.


Now create the request and response types.




Generate the Java Bean Skeleton. (WS Server code)

Right click the wsdl -> Web Services -> Generate Java Bean Skeleton.


Select the appropriate server, projects and also notice the slider. I planned to test it later than including it soon after this installation. So the slider was kept at "start service".

In the next screen select "Enable wrapper style" and "Copy WSDL to project". This will regenerate the wsdl into WEB-INF/wsdl folder by default.

If not target package is selected, it will generate the code into a newly created package based on your namespace.
In our case com.server.calculator. I specified a package (which was created previously).


<wsdl:definitions name="Calculator" targetNamespace="http://server.com/Calculator/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://server.com/Calculator/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

 <wsdl:types>
  <xsd:schema targetNamespace="http://server.com/Calculator/">
   <xsd:element name="calculate">
    <xsd:complexType>
     <xsd:sequence>
      <xsd:element name="in" type="tns:CalcRequestType"/>
     </xsd:sequence>
    </xsd:complexType>
   </xsd:element>
   <xsd:element name="calculateResponse">
    <xsd:complexType>
     <xsd:sequence>
      <xsd:element name="out" type="xsd:string"/>
     </xsd:sequence>
    </xsd:complexType>
   </xsd:element>

   <xsd:complexType name="CalcRequestType">
    <xsd:sequence>
     <xsd:element name="operand1" type="xsd:int"/>
     <xsd:element name="operand2" type="xsd:int"/>
     <xsd:element name="operation" type="tns:operationType"/>
    </xsd:sequence>
   </xsd:complexType>

   <xsd:simpleType name="operationType">
    <xsd:restriction base="xsd:string">
     <xsd:enumeration value="ADD"/>
     <xsd:enumeration value="SUB"/>
    </xsd:restriction>
   </xsd:simpleType>
  </xsd:schema>
 </wsdl:types>
 <wsdl:message name="calculateRequest">
  <wsdl:part element="tns:calculate" name="CalcRequest"/>
 </wsdl:message>
 <wsdl:message name="calculateResponse">
  <wsdl:part element="tns:calculateResponse" name="CalcResponse"/>
 </wsdl:message>
 <wsdl:portType name="Calculator">
  <wsdl:operation name="calculate">
   <wsdl:input message="tns:calculateRequest"/>
   <wsdl:output message="tns:calculateResponse"/>
  </wsdl:operation>
 </wsdl:portType>
 <wsdl:binding name="CalculatorSOAP" type="tns:Calculator">

  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
  <wsdl:operation name="calculate">
   <soap:operation soapAction="http://server.com/Calculator/calculate"/>
   <wsdl:input>
    <soap:body use="literal"/>
   </wsdl:input>
   <wsdl:output>
    <soap:body use="literal"/>
   </wsdl:output>
  </wsdl:operation>
 </wsdl:binding>
 <wsdl:service name="Calculator">
  <wsdl:port binding="tns:CalculatorSOAP" name="CalculatorSOAP">
   <soap:address location="http://localhost:9089/WSServer/Calculator"/>
  </wsdl:port>
 </wsdl:service>
</wsdl:definitions>
</code>


Write the implementation code.

public class CalculatorSOAPImpl implements com.server.Calculator_PortType{
    public java.lang.String calculate(com.server.CalcRequestType in) throws java.rmi.RemoteException {
        //do business operation here or delegate it to a business component
     System.out.println(in.getOperand1());
     System.out.println(in.getOperand2());
     System.out.println(in.getOperation().toString());
     if(in.getOperation().equals(OperationType.ADD)){
      return Integer.toString(in.getOperand1()+in.getOperand2());
     }else {
      return Integer.toString(in.getOperand1()-in.getOperand2());
     }
    }

}

Create another dynamic web application project that will act as your client.

Generating client code

To generate client code, Rightclick wsdl -> Webservices -> Generate client.


Notice that I selected the slider to deploy client and no further because installing and running the client I wanted to do later at my convenience.


Write a servlet to invoke the webservice.

public class TestServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;
       

    public TestServlet() {
        super();
        // TODO Auto-generated constructor stub
    }


 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  System.out.println("Called WS");
  Calculator_Service service = new Calculator_ServiceLocator();
  try {
   Calculator_PortType proxy = service.getCalculatorSOAP(new URL("http://localhost:9089/WSServer/services/CalculatorSOAP"));
   CalcRequestType in = new CalcRequestType();
   in.setOperand1(5);
   in.setOperand2(10);
   in.setOperation(OperationType.ADD);
   String result = proxy.calculate(in);
   System.out.println(result);
  } catch (ServiceException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

}

Notice that the service gets installed on the client server. And a JNDI lookup name is created. Check out the web.xml and code.

<service-ref>
  <description>
  WSDL Service Calculator</description>
  <service-ref-name>service/Calculator</service-ref-name>
  <service-interface>com.server.Calculator_Service</service-interface>
  <wsdl-file>WEB-INF/wsdl/Calculator.wsdl</wsdl-file>
  <jaxrpc-mapping-file>WEB-INF/Calculator_mapping.xml</jaxrpc-mapping-file>
  <service-qname xmlns:pfx="http://server.com/Calculator/">pfx:Calculator</service-qname>
  <port-component-ref>
   <service-endpoint-interface>com.server.Calculator_PortType</service-endpoint-interface>
  </port-component-ref>
 </service-ref>


public class Calculator_PortTypeProxy implements com.server.Calculator_PortType {
  private boolean _useJNDI = true;
  private boolean _useJNDIOnly = false;
  private String _endpoint = null;
  private com.server.Calculator_PortType __calculator_PortType = null;
.....
  private void _initCalculator_PortTypeProxy() {
  
    if (_useJNDI || _useJNDIOnly) {
      try {
        javax.naming.InitialContext ctx = new javax.naming.InitialContext();
        __calculator_PortType = ((com.server.Calculator_Service)ctx.lookup("java:comp/env/service/Calculator")).getCalculatorSOAP();
      }

Now hitting this url,
http://localhost:9089/WSServer/services/CalculatorSOAP

Displays,
{http://server.com/Calculator/}CalculatorSOAP
Hi there, this is a Web service!

You could obtain the wsdl by querying for it to the webservice runtime
http://localhost:9089/WSServer/services/CalculatorSOAP?wsdl


No comments:

Post a Comment