Friday, May 4, 2012

Helloworld RESTful Web service


What is REST?

REST is a term coined by Roy Fielding in his Ph.D. dissertation [1] to describe an architecture style of networked systems. REST is an acronym standing for Representational State Transfer.


I'm going to explain in detail in this article how to build a Spring based REST service.

1. Create a "Dynamic web project" in Eclipse, Name "restService" for example.



2. You need the following Jar files


commons-logging-1.1.1.jar
jstl-1.2.jar
org.springframework.aop-3.1.1.RELEASE.jar
org.springframework.asm-3.1.1.RELEASE.jar
org.springframework.aspects-3.1.1.RELEASE.jar
org.springframework.beans-3.1.1.RELEASE.jar
org.springframework.context-3.1.1.RELEASE.jar
org.springframework.context.support-3.1.1.RELEASE.jar
org.springframework.core-3.1.1.RELEASE.jar
org.springframework.expression-3.1.1.RELEASE.jar
org.springframework.instrument-3.1.1.RELEASE.jar
org.springframework.instrument.tomcat-3.1.1.RELEASE.jar
org.springframework.jdbc-3.1.1.RELEASE.jar
org.springframework.jms-3.1.1.RELEASE.jar
org.springframework.orm-3.1.1.RELEASE.jar
org.springframework.oxm-3.1.1.RELEASE.jar
org.springframework.spring-library-3.1.1.RELEASE.libd
org.springframework.test-3.1.1.RELEASE.jar
org.springframework.transaction-3.1.1.RELEASE.jar
org.springframework.web-3.1.1.RELEASE.jar
org.springframework.web.portlet-3.1.1.RELEASE.jar
org.springframework.web.servlet-3.1.1.RELEASE.jar
org.springframework.web.struts-3.1.1.RELEASE.jar


3. Edit the web.xml file under WEB-INF, add the following lines

<servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>


4. As per the instructions given in the link create Jaxb java classes for the following XSD file

Generating Jaxb java classes

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.lax.com/customer" xmlns="http://www.lax.com/customer" >
<xs:element name="customerDetails" type="CustomerDetails"/>

<xs:complexType name="CustomerDetails">
<xs:sequence>
<xs:element name="customerName" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="customerStreet" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="customerCity" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="customerState" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="customerZip" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>




5. In the same way create Jaxb java classes for the following XSD as well.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.lax.com/statusRes" xmlns="http://www.lax.com/statusRes" >
<xs:element name="statusRes" type="StatusRes"/>

<xs:complexType name="StatusRes">
<xs:sequence>
<xs:element name="resMsg" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>


6. Under WEB-INF folder create a file called springmvc-servlet.xml (The file name has a significance, it should be <servlet-name>-servlet.xml). Add the following lines in this file.


<?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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 
    <!-- Enable annotation scanning -->
    <context:component-scan base-package="com.lax"/>

    <bean name="viewResolver2" class="org.springframework.web.servlet.view.BeanNameViewResolver"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
      <list>
        <ref bean="stringHttpMessageConverter"/>
        <ref bean="marshallingHttpMessageConverter"/>
      </list>
    </property>
</bean>

<bean id="marshallingView" class="org.springframework.web.servlet.view.xml.MarshallingView">
    <constructor-arg ref="jaxbMarshaller"/>
</bean>
<bean id="stringHttpMessageConverter" 
       class="org.springframework.http.converter.StringHttpMessageConverter"/>

<bean id="marshallingHttpMessageConverter" 
      class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
    <constructor-arg ref="jaxbMarshaller"/>
  <property name="supportedMediaTypes" value="application/xml" />
</bean>
    
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="classesToBeBound">
        <list>
            <value>com.lax.oxm.customer.CustomerDetails</value>
            <value>com.lax.oxm.res.StatusRes</value>
        </list>
    </property>
</bean>

  <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
      <property name="prefix" value="/WEB-INF/jsp/"/>
      <property name="suffix" value=".jsp"/>
  </bean>
</beans>


The classes mentioned under the tags

<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="classesToBeBound">
        <list>
            <value>com.lax.oxm.customer.CustomerDetails</value>
            <value>com.lax.oxm.res.StatusRes</value>
        </list>
    </property>
</bean>

are the classes you generate in steps 4 & 5


7. Create the following Controller Java class

package com.lax.controller;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.lax.oxm.customer.CustomerDetails;
import com.lax.oxm.res.StatusRes;

@Controller
@RequestMapping("/sampleAnnotationCnt")
public class SampleAnnotationController{

 private static final String XML_VIEW_NAME = "marshallingView";

 @RequestMapping(value="/processCustomerDetails.htm", method=RequestMethod.POST)
 public ModelAndView processCustomerDetails(@RequestBody CustomerDetails customerDetails) throws Exception {
   System.out.println(customerDetails.getCustomerName());
  StatusRes statusRes = null;
  statusRes = new StatusRes();
  statusRes.setResMsg("successful");
   return new ModelAndView(XML_VIEW_NAME, BindingResult.MODEL_KEY_PREFIX, statusRes);
 } 
}

8. Creating a client for the service

Jars required
commons-httpclient-3.1-jbossorg-1.jar
commons-logging-1.1.1.jar
commons-codec-2.0-20110918.143203-58.jar

9. Create the following java class and execute it to invoke the REST Webservice

package com.lax.restclient;

import java.io.IOException;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;

public class RestClient {

 public static void main(String[] args) {
  String response = null;
  String body = "<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:customerDetails xmlns:ns2="http://www.lax.com/customer"><customerName>Balamurugan</customerName><customerStreet>5000 Vinoy blvd</customerStreet><customerCity>Charlotte</customerCity><customerState>NC</customerState><customerZip>28262</customerZip></ns2:customerDetails>";
  String url = "http://localhost:8080/restService/sampleAnnotationCnt/processCustomerDetails.htm";
  PostMethod postMethod = new PostMethod(url);
  postMethod.setRequestBody(body);
  postMethod.setRequestHeader("Content-type", "application/xml");
  HttpClient httpClient = new HttpClient();
  try {
   int status = httpClient.executeMethod(postMethod);
   response = postMethod.getResponseBodyAsString();
   System.out.println("Status : "+status);
   System.out.println("Response : "+response);
  } catch (HttpException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}


Friday, September 23, 2011

Oracle FORALL Insert RETURNING PRIMARY KEY VALUE

Requirement:
I have a list of values in an Oracle collection Object which I want insert into a table. The table has a primary key column value which will be populated from a Sequence. Once these Primary Keys are populated I need those Primary Key values to insert into another table to create an association/relationship.

Solution:

CREATE TABLE test (test_id VARCHAR2(50), test_name VARCHAR(50), CONSTRAINT t_pk PRIMARY KEY (test_id));
CREATE SEQUENCE test_tbl_pk_seq;

Here is the PL/SQL Block to get the requirement done.

DECLARE
TYPE TBL_TYPE IS TABLE OF VARCHAR2(50);
NAME_TBL TBL_TYPE;
PK_TBL TBL_TYPE;
BEGIN
name_tbl := NEW tbl_type();
pk_tbl := NEW tbl_type();

FOR i IN 1..10
LOOP
name_tbl.EXTEND;
name_tbl(i) := 'NAME-'||i;
END LOOP;

FORALL i IN 1..name_tbl.LAST
INSERT INTO test (test_id, test_name) VALUES ('T-'||test_tbl_pk_seq.NEXTVAL, name_tbl(i)) RETURNING test_id BULK COLLECT INTO pk_tbl;

FOR i IN 1..pk_tbl.LAST
LOOP
DBMS_OUTPUT.PUT_LINE(pk_tbl(i));
END LOOP;
END;