Wednesday, October 23, 2013

Building Webservices using Spring

In this post, I'm going to explain how to write a contract first webservice using Spring.

We are going to create a service for creating a person record. We are going to call the service as 'CreatePersonService'. It will accept first name, middle name and last name as parameters and return a id parameter back as a response.

We need to first define the XSD representing the person record. Also, we need an XSD to represent the request to create the Person record. 

Let us first start with the maven dependencies required:

pom.xml:

We will be using jaxb for generating classes from xsd.

<dependency> 
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-core</artifactId>
    <version>2.1.3.RELEASE</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>
      
<dependency>
    <groupId>org.dom4j</groupId>  
    <artifactId>dom4j</artifactId>  
    <version>1.0</version>
    <type>jar</type>
    <scope>provided</scope>  
</dependency>   

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>3.0</version>
      <type>jar</type> 
      <scope>compile</scope>
</dependency>
<dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <type>jar</type> 
      <scope>compile</scope>
</dependency>
<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
</dependency>
<!-- Spring 3 dependencies -->
<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
</dependency>
 
<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
</dependency>
 
<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
</dependency>
<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
</dependency>

<dependency>
        <groupId>org.apache.ws.xmlschema</groupId>
        <artifactId>xmlschema-core</artifactId>
        <version>2.0.3</version>
</dependency>

Also in order to configure jaxb, you will need the following in the plugin section of pom.xml:
<plugin>  
        <groupId>org.codehaus.mojo</groupId>  
        <artifactId>jaxb2-maven-plugin</artifactId>  
        <version>1.4</version>  
        <executions>  
              <execution>  
                 <goals>  
                      <goal>xjc</goal>  
                 </goals>  
                 <phase>generate-sources</phase>  
              </execution>  
        </executions>  
        <configuration>  
            <clearOutputDir>false</clearOutputDir>  
            <outputDirectory>src/main/java</outputDirectory>  
            <schemaDirectory>src/main/webapp/schemas</schemaDirectory>  
            <includeSchema>**/*.xsd</includeSchema>             
            <enableIntrospection>false</enableIntrospection>  
        </configuration>  
</plugin>  


Service Interface and Implementation:

Create the following Interface and impl class:

public interface PersonService {
      public String createPerson(String firstName,String middleName,String lastName);
}

@Service
public class PersonServiceImpl implements PersonService{
       public String createPerson(String firstName,String middleName,String lastName){
                String userId = "";
                //Create Person
  
                return userId;
       }
}

Person XSD:

Create a xsd 'Person.xsd' in webapp/schemas folder to represent Person as below. Note the use of namespace attributes. I have used a namespace "http://schemas.myproduct.myorg.com". It will create package structure of the form "com.myorg.myproduct.schemas" for this namespace usage.


<?xml version="1.0" encoding="UTF-8"?>  
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns="http://schemas.myproduct.myorg.com" 
      targetNamespace="http://schemas.myproduct.myorg.com" 
      elementFormDefault="qualified" attributeFormDefault="unqualified">  

      <xs:element name="Person" type="Person"/>  
      <xs:complexType name="Person">  
           <xs:sequence>  
                <xs:element name="FirstName" type="xs:string"/>  
                <xs:element name="MiddleName" type="xs:string"/>  
                <xs:element name="LastName" type="xs:string"/>  
           </xs:sequence>  
      </xs:complexType>  
</xs:schema> 

CreatePersonOperation XSD:

Create a xsd 'CreatePersonOperation.xsd' in webapp/schemas folder to represent the request operation for our webservice as below.

<?xml version="1.0" encoding="UTF-8"?>  
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns="http://com/myorg/myproduct/webservices/createpersonservice" 
      targetNamespace="http://com/myorg/myproduct/webservices/createpersonservice" 
      elementFormDefault="qualified" attributeFormDefault="unqualified">
  
  
    <xs:element name="CreatePersonRequest">  
           <xs:complexType>  
                <xs:sequence>  
                      <xs:element name="FirstName" type="xs:string"/>
                        <xs:element name="MiddleName" type="xs:string"/>  
                 <xs:element name="LastName" type="xs:string"/>  
                </xs:sequence>  
           </xs:complexType>  
     </xs:element>  
     <xs:element name="CreatePersonResponse">  
           <xs:complexType>  
                <xs:sequence>  
                    <xs:element name="response" type="xs:string"/>  
                </xs:sequence>  
           </xs:complexType>  
      </xs:element>  
  
</xs:schema>

Changes to Spring config xml:

Add the following namespace attributes to the config xml. Also make sure the annotation config is there to allow spring container to create the necessary beans.

<beans xmlns="http://www.springframework.org/schema/beans"  
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:sws="http://www.springframework.org/schema/web-services"
        xmlns:mvc="http://www.springframework.org/schema/mvc"  
        xmlns:context="http://www.springframework.org/schema/context"  
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
        http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd">  
        
     
       <context:component-scan base-package="com.myorg" />
       <mvc:annotation-driven/>
       <sws:annotation-driven/>
       
       <bean id="CreatePersonService" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition" lazy-init="true">  
         <property name="schemaCollection">  
         <bean class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">  
                <property name="inline" value="true" />  
                <property name="xsds">  
                        <list>  
                        <value>schemas/CreatePersonOperation.xsd</value>  
                        </list>  
                </property>  
                </bean>  
                </property>  
                <property name="portTypeName" value="CreatePersonService"/>  
                <property name="serviceName" value="CreatePersonService" />  
                <property name="locationUri" value="/endpoints"/>  
      </bean>      

</beans>

Changes to web.xml:

The webservice request will go through as a http request and is handled by the container. So we need to configure this in web.xml as below:

<servlet>  
        <servlet-name>webservices</servlet-name>  
        <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>  
            <init-param>  
                <param-name>transformWsdlLocations</param-name>  
                <param-value>true</param-value>  
            </init-param>  
            <init-param>  
                <param-name>contextConfigLocation</param-name>  
                 <param-value></param-value>  
            </init-param>  
            <load-on-startup>1</load-on-startup>  
       </servlet>  
       <servlet-mapping>  
            <servlet-name>webservices</servlet-name>  
            <url-pattern>*.wsdl</url-pattern>  
       </servlet-mapping>  
       <servlet-mapping>  
            <servlet-name>webservices</servlet-name>  
            <url-pattern>/endpoints/*</url-pattern>  
       </servlet-mapping>
</servlet>       

Endpoint Class:

Create a class which represents the webservice endpoint as below. Note that this class needs to be created after you compile the project once and there by generating the JAXB mapping classes from the xsd. I have also provided the import statements for this class for clarity.

package com.myorg.service.endpoint;

import org.springframework.beans.factory.annotation.Autowired;

import com.myorg.myproduct.webservices.createpersonservice.CreatePersonRequest;
import com.myorg.myproduct.webservices.createpersonservice.CreatePersonResponse;
import com.myorg.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;  
import org.springframework.ws.server.endpoint.annotation.RequestPayload;  
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;


@Endpoint
public class PersonServiceEndPoint {
private static final String TARGET_NAMESPACE = "http://com/myorg/myproduct/webservices/createpersonservice";
 
        @Autowired
        private PersonService personService;

  
        public void setPersonService(PersonService personService) {
                this.personService = personService;
        }




        @PayloadRoot(localPart = "CreatePersonRequest", namespace = TARGET_NAMESPACE)  
        public @ResponsePayload CreatePersonResponse createPerson(@RequestPayload CreatePersonRequest request) {
                CreatePersonResponse response = new CreatePersonResponse();
  
                String userId = personService.createPerson(request.getFirstName(), request.getMiddleName(), request.getLastName());
                response.setResponse(userId);
                return response;
        }
}


After compiling the project, you will notice that additional classes would have been created under com.myorg.myproduct.webservices.createpersonservice and com.myorg.myproduct.schemas  packages. Notice that a WSDL is not generated as a static resource file. Instead, the WSDL file is generated dynamically on the fly by the Spring container.

To test you can run the following in the browser to obtain the wsdl:
http://localhost:8080/testbed/endpoints/CreatePersonService.wsdl

Sunday, October 20, 2013

Popups using Javascript and CSS

In this post, I'm writing about an interesting way of displaying popups using javascript and css.

These popups do not show up in a new window, but rather in the same page as a different box. You might have seen these kind of popups while logging in or during display of your profile details in various social networking sites or email websites like gmail.

The idea here is to use css and div to display a box which embeds a separate html form of its own.
Lets first create a the form elements for login:

<div id="popupbox"> 
<form name="login" action="" method="post">
<div id="centertag">Username:</div>
<div id="centertag"><input name="username" size="14" /></div>
<div id="centertag">Password:</div>
<div id="centertag"><input name="password" type="password" size="14" /></div>
<a href="javascript:document.form.submit();"">
<div id="centertag">
        <span id="squares">
             <div id="1"><span>Login</span></div>    
        </span>
</div>
</a>
</form>
<br />
</div> 

The centertag style is used center align the login fields. The squares style is used to show the square box substitute for button (showing 'Login'). However, the style to look for is the 'popupbox' which will create the login popup box. Note that we have used absolute positioning to place the login box in the required position.

Lets take a look at the css styles:

<style type="text/css">
  #popupbox{
      margin: 0; 
      margin-left: 40%; 
      margin-right: 40%;
      margin-top: 50px; 
      padding-top: 10px; 
      width: 20%; 
      height: 150px; 
      position: absolute; 
      background: #FFFFFF; 
      border: solid #68BEC9 1px; 
      z-index: 9; 
      font-family: arial; 
      visibility: hidden; 
  }
  
  #centertag{
      text-align: center;
      margin-bottom: 5px; 
  }
 
  #squares div {
      display: block;
      float: left;

      width: 112px;
      height: 30px;
      line-height: 30px;
      background: #E0E0E0;
      text-align: center;
      font-family: Arial, Helvetica, sans-serif;
      border: solid #68BEC9 1px; 
      margin-right: 5px; 
  }
  span {
      display: inline-block;
      vertical-align: middle;
      line-height: normal;      
      margin-top: 5px;
  }
 </style>


The last part is the javascript function to show this login popup.

<script language="JavaScript" type="text/javascript">
  function login(showhide){
    if(showhide == "show"){
        document.getElementById('popupbox').style.visibility="visible";
    }
  }
</script>

Invoking the above function will display the login popup as shown below:

<a href="javascript:login('show');">login</a></p>

Wednesday, October 16, 2013

Site Map

All Posts by Category:

1. Patterns:



2. Spring Framework:

Spring AOP:
               Spring AOP Part-I
               Spring AOP Part-II
               Spring AOP Part-III


Spring MVC
              Spring MVC Part-I
              Spring MVC part-II

Spring Webflow:
             Spring Webflow Part-I
             Spring Webflow Part-II
             Spring Webflow Part-III
             Spring Webflow Part-IV



Spring Webservices:
             Building Webservices Using Spring

3. Architecture

Restful Services
          Restful Architecture
       

4. Hibernate 

Hibernate tutorial Series:
                    Hibernate tutorial Part I
                    Hibernate tutorial Part II


Spring Beans Autowiring

In this post I'm going to write about Autowiring feature in Spring.


Overview:

Generally, in Spring, you will define the beans and inject other beans into their properties by configuring them in xml. For eg, if we have a DAO, UserDAO and a service class UserService, which has a property reference for the DAO, then, the bean configuration would look like this:
<bean id="userDAO" class="com.myorg.service.dao.UserDAO">
</bean>

<bean id="userSvc" class="com.myorg.service.UserService">
      <propertyname="userDAO" ref="userDAO"/>
</bean>

Spring provides a feature called Autowiring, wherein the decision to wire the bean properties could be left to the Spring framework and this saves us a lot of configuration hassle.

There are four types of autowiring:
  1. byName
  2. byType
  3. constructor
  4. autodetect

1. Autowiring - byName:

In this type of wiring, Spring attempts to find the beans which has the same name/id as that of the bean property. In our above DAO/Service example, the UserService has a property userDAO. We can ignore the property config for userDAO by specifying autowiring by name as below:

<bean id="userSvc" class="com.myorg.service.UserService"  autowire="byName">
</bean>

2. Autowiring - byType:

In this type of wiring, Spring attempts to find the beans which have the same type as that of the bean property. This overcomes the disadvantage in 'byName', wherein you should always have the beans with same name/id as that of the property.
<bean id="userSvc" class="com.myorg.service.UserService"  autowire="byType">      
</bean>

Pitfalls of bytpe:

Wiring by type has a disadvantage. If Spring finds more than one matching bean, it will throw an exception. 

To overcome this, you can mark a bean as a primary candidate for autowiring. To get this working, you need to set the 'primary' attribute to true for the bean which you want to autowire and also set this attribute to 'false' for all other beans which have the same type (Since by default for all beans Spring treats this value as true).

Another option is, to set the 'autowire-candidate' to false for those beans which you do not want to be considered for autowiring.

3. Autowiring - constructor:

In this type of wiring, Spring attempts to find the beans which match the same type as that of the constructor arguments of a bean. This eliminates the need for constructor-arg configuration. However, note that when you are using constructor wiring, you cannot use constructor-args for some arguments and wiring for some.

For eg.,the UserDAO will need a datasource object to be injected in its constructor. To configure this, we can use constructor wiring as below:
<bean id="userDAO" class="com.myorg.service.dao.UserDAO" autowire="constructor">
</bean>

Spring will automatically detect the DataSource object defined in the bean configuration file and inject it into the UserDAOs constructor.

4. Autowiring - autodetect:

In this type of wiring, Spring attempts constructor wiring first. It it fails to find a matching bean, then it attempts wiring bytype.


Wiring Nulls:

One interesting feature provided by Spring is that we can also wire a null to a property. This feature is helpful, when the properties have some initial value and we need to nullify them.
<propertyname="country"><null/></property>


In general, you can mix and match different wiring types based on your need and this will help in reducing explicit configuration.

Spring Annotations for Autowiring:

Spring provides two configurations for supporting annotations:
1. context:annotation-config: This configuration when placed in your beans config file, will tell Spring to consider some of the annotations. However, you still need to declare your beans in the config file.

2. context:component-scan: This configuration when placed in your beans config file, will completely eliminate the need for declaring your beans in config file. This config provides autowiring and autodiscovery.

Following are some of the annotations provided by Spring to annotate the beans:
  1. @Component - Indicates that the class is a Spring component.
  2. @Controller  - Indicates that the class is a Spring MVC Controller
  3. @Repository - Indicates that the class is a data repository
  4. @Service  - Indicates that the class is a Service
Also, use the @Autowired configuration to make use of the autowiring ability provided by Spring. Note that @Autowiring always wires by type. If there is more than one bean with the same type, then you can use @Qualifier to remove the ambiguity as explained below:

Lets say there is an interface UserDataService which has two implementations.
public interface UserDataService {
       public User getUser(long userId);
}

@Service
public class UserDataServiceImpl implements UserDataService{
        public User getUser(long userId){ ....  }
}

@Service
public class PrivilegedUserDataServiceImpl implements UserDataService{
        public User getUser(long userId){ ....  }
}

@Controller
public  class UserController {   
        @Autowired
        private UserDataService userSvc;
        
        ...
        
}
Since there are two implementations Spring container will not know which one to bind and it will throw an exception "org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.myorg.service.UserDataService] ".

To overcome this, we can use the @Qualifier annotation to specify which bean we want to be injected. 
public interface UserDataService {
       public User getUser(long userId);
}

@Service
public class UserDataServiceImpl implements UserDataService{
        public User getUser(long userId){ ....  }
}

@Service(value="privileged")
public class PrivilegedUserDataServiceImpl implements UserDataService{
        public User getUser(long userId){ ....  }
}

@Controller
public  class UserController {   
        @Autowired
        @Qualifier("privileged")
        private UserDataService userSvc;
        
        ...
        
}
In the above example, we have provided a name "privileged" to the PrivilegedUserDataServiceImpl and then the same name is used in the @Qualifier annotation.

Sunday, October 6, 2013

Spring AOP - Part III

For part I, refer to: Spring AOP - Part I
For part II, refer to: Spring AOP - Part II

Continuing further on AOP examples, in this post, we will see how can we pass arguments to the Aspect classes.


Passing parameters to Aspect classes:

In this example, we will write a very basic auditing service, which will store audit details of who accessed a particular service.

The audit details could be stored in database. But that part is not shown here to keep the details simple.

Let us say we have an Account service, which offers CRUD on the account. The username parameter which is the first parameter for all the methods, indicates the user who will perform a CRUD on the account.
public interface AccountService {
    public long createAccount(String username, Account account);
    public void updateAccount(String username, Account account);
    public void deleteAccount(String username, Account account);
}

Define a corresponding AccountServiceImpl which will actually perform the CRUD. (not shown here).

Define an AuditService to define the audit operation and its implementation. Note that the audit service also has a "username" parameter which will passed from the target class (i.e, AccountService). Note that JoinPoint should always be first parameter, followed by the custom arguments.
public interface AuditService {
    public void performAudit(JoinPoint joinPoint,String username);
}
public class AuditServiceImpl implements AuditService{
        public void performAudit(JoinPoint joinPoint,String username) {
                 //log or store in database
        }
}

Spring config xml:

Note the String parameter passed to AccountService methods and the 'username' parameter name within args. This parameter name should match the actual name in AccountService.

<aop:aspect ref="auditService">  
         <aop:pointcut  id ="audit" expression="execution(* com.myorg.service.AccountService.*(String,..)) and args(username,..)"/>
         <aop:before  method="performAudit"  pointcut-ref="audit"/>
</aop:aspect>

AOP Introductions:

We can add new functionality to existing classes by using AOP Introductions. Internally, Spring will invoke these methods through the proxy implementation and this call will not go to the target class.

Lets say we create a new interface AccountAudit to define some special audits related to Account service.
public interface AccountAudit{
    public void performAudit();
}

We will define an implementation for this;
public class AccountAuditImpl implements AccountAudit{
    public void performAudit(){
        //audit
    }
}
We will need AccountService also to implement the same interface using AOP. We need to define this in the spring context xml as below:
<aop:aspect>
   <aop:declare-parents types-matching="com.org.AccountService+"
          implement-interface="com.org.AccountAudit"
          default-impl="com.org.AccountAuditImpl"/>
</aop:aspect>

Now, effectively this means that the AccountService could be type casted to AccountAudit as below and we can invoke the performAudit() method using AccountService reference.

((AccountAudit) accServ).performAudit();


Applications of AOP:


In general, AOP can be best used in logging, security, transaction, auditing.

However, a word of caution while using AOP.  Though AOP is very powerful, avoid using AOP for implementing business logic, as it will result in a maintenance nightmare since it will be hard to figure out that some part of the business logic is in the aspect classes.