Wednesday, November 4, 2009

Web Services using AXIS

Use following steps to create a web service using AXIS:
1. Create a web project Calculator.

2. Create a class Addition.java
  package org.me.calculator;
  public class Addition {
    public int add() {
      return 20;
    }

    public String getXML(String xml) {
      return "Hello";
    }
  }

3. Edit web.xml under WEB-INF as add
  <listener>
    <listener-class>
      org.apache.axis.transport.http.AxisHTTPSessionListener
    </listener-class>
  </listener>

  <servlet>
    <servlet-name>AxisServlet</servlet-name>
    <servlet-class>
      org.apache.axis.transport.http.AxisServlet
    </servlet-class>
  </servlet>

  <servlet>
    <servlet-name>AdminServlet</servlet-name>
    <servlet-class>
      org.apache.axis.transport.http.AdminServlet
    </servlet-class>
    <load-on-startup>100</load-on-startup>
  </servlet>

  <servlet>
    <servlet-name>SOAPMonitorService</servlet-name>
    <servlet-class>
      org.apache.axis.monitor.SOAPMonitorService
    </servlet-class>
    <init-param>
      <param-name>SOAPMonitorPort</param-name>
      <param-value>5001</param-value>
    </init-param>
    <load-on-startup>100</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/servlet/AxisServlet</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>*.jws</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>SOAPMonitorService</servlet-name>
    <url-pattern>/SOAPMonitor</url-pattern>
  </servlet-mapping>

<!-- uncomment this if you want the admin servlet -->
<!--
<servlet-mapping>
<servlet-name>AdminServlet</servlet-name>
<url-pattern>/servlet/AdminServlet</url-pattern>
</servlet-mapping>
-->

  <mime-mapping>
    <extension>wsdl</extension>
    <mime-type>text/xml</mime-type>
  </mime-mapping>

  <mime-mapping>
    <extension>xsd</extension>
    <mime-type>text/xml</mime-type>
  </mime-mapping>

4. Create a file server-config.wsdd in WEB-INF, add the following content.
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
  <globalConfiguration>
    <parameter name="adminPassword" value="admin"/>
    <parameter name="attachments.Directory" value="./attachments"/>
    <parameter name="attachments.implementation"
value="org.apache.axis.attachments.AttachmentsImpl"/>
    <parameter name="sendXsiTypes" value="true"/>
    <parameter name="sendMultiRefs" value="true"/>
    <parameter name="sendXMLDeclaration" value="true"/>
    <parameter name="axis.sendMinimizedElements" value="true"/>
    <requestFlow>
      <handler type="java:org.apache.axis.handlers.JWSHandler">
        <parameter name="scope" value="session"/>
      </handler>
      <handler type="java:org.apache.axis.handlers.JWSHandler">
        <parameter name="scope" value="request"/>
        <parameter name="extension" value=".jws"/>
      </handler>
    </requestFlow>
  </globalConfiguration>

  <handler name="LocalResponder"
type="java:org.apache.axis.transport.local.LocalResponder"/>
  <handler name="URLMapper"
type="java:org.apache.axis.handlers.http.URLMapper"/>
  <handler name="Authenticate"
type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>

  <service name="AdminService" provider="java:MSG">
    <parameter name="allowedMethods" value="AdminService"/>
    <parameter name="enableRemoteAdmin" value="false"/>
    <parameter name="className" value="org.apache.axis.utils.Admin"/>
    <namespace>http://xml.apache.org/axis/wsdd/</namespace>
  </service>

  <service name="Version" provider="java:RPC">
    <parameter name="allowedMethods" value="getVersion"/>
    <parameter name="className" value="org.apache.axis.Version"/>
  </service>

  <service name="Addition" provider="java:RPC">
    <parameter name="className" value="org.me.Addition"/>
    <parameter name="allowedMethods" value="*"/>
    <!--<parameter name="allowedMethods" value="getXML"/> -->
  </service>

  <transport name="http">
    <requestFlow>
      <handler type="URLMapper"/>
      <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
    </requestFlow>
  </transport>

  <transport name="local">
    <responseFlow>
      <handler type="LocalResponder"/>
    </responseFlow>
  </transport>
</deployment>

5. Add the required JARs into the web project.

6. Deploy the web project and run using http://localhost:8080/Calculator/services/Addition. You can see the wsdl through http://localhost:8080/Calculator/services/Addition?wsdl

You can also run the Addition.java web service without using server-config.wsdd. The steps are mentioned below:

1. Create Addition.java as mentioned above.

2. Save Addition.java as Addition.jws and put this Addition.jws file into web folder (web root, where jsp and WEB-INF reside).

3. Deploy the web project and run using http://localhost:8080/Calculator/Addition.jws. You can see the wsdl through http://localhost:8080/Calculator/Addition.jws?wsdl

Now, if you have a web service which will return set of custom objects, then how to configure it?
Lets take an examlple. Suppose you have a class Manager.java

package company;
public class Manager {
  /**
  * Get all employees
  * @return array of Employee array
  */
  public Employee[] getAllEmployees() {
    List empList = new ArrayList();
    empList.add(new Employee("Joe", 2000, "Engineer"));
    return (Employee[])empList.toArray();
  }

  /**
  * Save employees
  * @param employees array of Employee objects
  */
  public void setEmployee(Employee[] employees) {
  }
}

Employee.java:

package company;
public class Employee {
  private String name;
  private double salary;
  private String designation;

  public Employee() { }

  public Employee(String name, double salary, String designation) {
    this.name = name;
    this.salary = salary;
    this.designation = designation;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public double getSalary() {
    return salary;
  }

  public void setSalary(double salary) {
    this.salary = salary;
  }

  public String getDesignation() {
    return designation;
  }

  public void setDesignation(String designation) {
    this.designation = designation;
  }
}

Then you need to update the server-config.wsdd. Add below lines:

<service name="EmployeeWS" provider="java:RPC">
  <parameter name="allowedMethods" value="*"/>
  <parameter name="className" value="company.Manager"/>

  <beanMapping languageSpecificType="java:company.Employee"
      qname="ns1:Employee" xmlns:ns1="urn:company"/>
</service>

Web Services using JAX-WS

Use following steps to create a web service using JAX-WS.
1. Create a web project, say Calculator.
2. Create a class Addition.java

  package org.me.calculator;

  import javax.jws.WebMethod;
  import javax.jws.WebParam;
  import javax.jws.WebService;

  @WebService()
  public class Addition {
    /**
    * Web service operation
    */
    @WebMethod(operationName = "add")
    public int add(@WebParam(name = "a") int a, @WebParam(name = "b") int b) {
      return a + b;
    }

  }

3. Edit web.xml under WEB-INF, add
  <listener>
    <listener-class>
      com.sun.xml.ws.transport.http.servlet.WSServletContextListener
    </listener-class>
  </listener>
  <servlet>
    <servlet-name>CalculatorWS
    <servlet-class>
      com.sun.xml.ws.transport.http.servlet.WSServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>CalculatorWS
    <url-pattern>/webservice/*</url-pattern>
  </servlet-mapping>

4. Add sun-jaxws.xml in WEB-INF. and add the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<endpoints version="2.0" xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime">
  <endpoint implementation="org.me.calculator.Addition" name="Addition" url-pattern="/webservice/Addition"/>
</endpoints>

5. Add required JAR into the project.

6. Deploy the project and run using http://localhost:8080/Calculator/webservice/Addition. You can see the WSDL using http://localhost:8080/Calculator/webservice/Addition?wsdl

Monday, October 26, 2009

Web Services using JAX-RS

JAX-RS stands for Java API for RESTful Web Services. RESTful API came in JSR-311.
I am using Apache CFX to develop web service for RESTful. You can download the libraries from http://cxf.apache.org/. More documentation is available at http://cxf.apache.org/docs/jax-rs.html

Use the following steps to create a web service.

1. Create a web project, say Calculator

2. Create Addition.java

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

@Path("/addition/")
@Produces("text/html")
@Consumes("text/html")
public class Addition {

  @GET
  @Path("/add/{a}/{b}")
  public int add(@PathParam("a") int a, @PathParam("b") int b) {
    return a + b;
  }
}

3. Add the following in web.xml under WEB-INF.
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>WEB-INF/beans.xml</param-value>
</context-param>

<listener>
  <listener-class>
    org.springframework.web.context.ContextLoaderListener
  </listener-class>
</listener>

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

<servlet-mapping>
  <servlet-name>CXFServlet</servlet-name>
  <url-pattern>/service/*</url-pattern>
</servlet-mapping>

4. Create beans.xml, and put it into WEB-INF. The content of beans.xml is

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jaxrs="http://cxf.apache.org/jaxrs"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://cxf.apache.org/jaxrs
    http://cxf.apache.org/schemas/jaxrs.xsd">

  <!-- do not use import statements if CXFServlet init parameters link     to this beans.xml -->

  <import resource="classpath:META-INF/cxf/cxf.xml" />
  <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

  <jaxrs:server id="services" address="/service">
    <jaxrs:serviceBeans>
      <ref bean="additionBean" />
    </jaxrs:serviceBeans>
    <jaxrs:extensionMappings>
      <entry key="xml" value="application/xml" />
    </jaxrs:extensionMappings>
  </jaxrs:server>

  <bean id="additionBean" class="calculator.Addition" />
</beans>

5. Add libraries to the web project.

6. You can access the web service using http://localhost:8080/Calculator/service/service/addition/add/23/36.

Here we are passing 23 and 36 to our add method in Addition.java.
The result you will see is 59.

You can see the wadl using http://localhost:8080/Calculator/service/service/addition?_wadl&_type=xml