Showing posts with label jaxb. Show all posts
Showing posts with label jaxb. Show all posts

Saturday, August 18, 2012

Spring Web Services with Jaxb

In this post I am going to explain how to implement a web service by using spring-ws. For the demonstration purpose I am going to narrow down this sample project as follows.

Functionality of web service : Authenticate a user(I am not going to use any encryption method or a security mechanism since this post is about spring ws :-))

Development/Deployment environment :
  • java 1.6
  • Spring-ws-core with jaxb 
  • Intelij Idea
  • Apache tomcat 
  • SoapUI 4.5.1
 First we need to start with a schema definition which our service is going to support. So for the simplicity I used following definition which is easy to understand.
 



    

    

    
        
            
            
        
    

    
        
            
            
        
    

Above schema definition consist of a simple login request and the corresponding response.Simple it can parse following sample messages.

Request Message
 

   
   
      
         esu
         password
      
   

Response Message
 

   
   
      
         SUCCESS
         esu
      
   

Then you need to create a web project by using your IDE or a build tool like maven. A web service acts like a web app and the the significant difference is that it can identify incoming xml requests and response them with corresponding xml responses as mentioned in above. If you are familiar with Spring mvc you know that we can configure a Dispatcher Servlet in web.xml which can identify HTTP get and post requests from the client browser.In the similar manner you can configure a MessageDispatcherServlet which can identify web server requests.
    
        customer-ws
        org.springframework.ws.transport.http.MessageDispatcherServlet
    
    
        customer-ws
        /*
     
Then you should have customer-ws-servlet.xml where all the spring web service configurations and jaxb marshaling configurations are located. You can find the Servlet here . The important thing to be noticed is the WSDL configuration and schema configuration.
 
    
        
        
        
    

    
        
    
customer service bean creates a wsdl for you according to the schema bean which is configured to the loginschema.xsd. Once you deploy the web service in to the web container you can access the generated wsdl by http://localhost:8080/customerService/customerService.wsdl.

Then its time to implement end point class which the final destination for incoming soap massages. Following is the implementation of the endpoint.
 
@Endpoint
public class CustomerServiceEndPoint {


    @Autowired
    private LoginService loginService;


    @PayloadRoot(localPart = "LoginRequest", namespace = "http://mycompany.com/customer-ws/schemas")
    @ResponsePayload
    public JAXBElement login(@RequestPayload JAXBElement requestElement) throws IOException {
        ObjectFactory objectFactory = new ObjectFactory();
        LoginResponseDetails details = new LoginResponseDetails();

        details.setUsername(requestElement.getValue().getUserName());
        if (loginService.login(requestElement.getValue().getPassword(), requestElement.getValue().getPassword())) {
            details.setStatus("SUCCESS");

            return objectFactory.createLoginResponse(details);
        }
        details.setStatus("FAIL");
        return objectFactory.createLoginResponse(details);

    }
}
You can see the login method is accepting jaxb element called LoginDetails and it passes that details in to service method and authenticate the user and return the response jaxb element. you might be wondering how this happens. It is because we have configure marshalling and unmarshalling in the servlet xml.And also to enable the jaxb class generation I have used jaxb2-maven-plugin in my pom file which you can find the source code on the Google code repository.

Source Code Link : Code
What you have to do is simply check out the source code and then run mvn package command. Then you can see the generated war file. Then deploy it in to apache tomcat. Now you are done.

Following is the screen shot  taken from the soapui to verify that the web service is working or not.


From my next post i hope to show how to write client app to use this web service.

Friday, June 15, 2012

Unmarshalling XML files with jaxb

In this post I am going to explain how to create a schema definition from a sample xml file and use that schema definition file to marshalling and un-marshalling by using jaxb2.

Following is the sample xml formal I want to handle. (Suppose we have a web service and it can accept this kind of requests)

    
        Eshan
        test@gmail.com
    
    
        
            SE-12
            web camera
        
        
            SE-75
            mobile phone
        
    

You can create the schema definition file (xsd) of a given  sample by using modern IDE's. For this purpose I used Intelij xml to xsd converter which makes life easier. But we need to edit the generated xsd file for our simplicity. So following is the schema definition for the above xml file.

    

    
        

            
                
                    
                
            

            
                
                    
                    
                
            

        
    

    
        
            
            
        
    

    
        
            
        
    

    
        
            
            
        
    


Now we have finished the work with schema related stuff. Then we need to generate generate java classes from this xsd file. So its time to deal with jaxb2. In this case I had a problem which is the generated java classes are not in a proper naming convention. (All tha classes has "Type" postfix). To fix that we can use a bindings xml which can be pass as a parameter to jaxb.

    
        
            
        

        
            
        
        
            
        
        
            
        
        
            
        
        

So now we are almost done. Its time to generate java classes from these two xml files (xsd file and binding xml). For this purpose instead of calling jaxb xjc directly, I used maven jaxb plugin which is more flexible. following is the jaxb plugin confutation which comes in your pom file.
 
        
            
                generated-sources/xjc/com/demo/xsd
            
        
        
            
                org.jvnet.jaxb2.maven2
                maven-jaxb2-plugin
                
                    
                        
                            generate
                        
                    
                
                
                    src/main/resources
                    true
                    true
                    false
                    true
                    
                        bindings.xml
                    
                
            
        
    
Once you invoke the maven target it will create the java classes of the complex types in our schema definition file. SO now its time to write a client program which uses those java classes to unmarshall a sample xml file.
package com.demo.xsd;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import java.io.File;

public class Unmarshalling {
    public static void main(String[] args) {

        try {                 
            //sample xml file to be unmarshall
            File file = new File("path/to/sample.xml");
            javax.xml.bind.JAXBContext jc = javax.xml.bind.JAXBContext
                    .newInstance(Order.class);
            javax.xml.bind.Unmarshaller u = jc.createUnmarshaller();
            JAXBElement orderJAXBElement = u.unmarshal(new StreamSource(file),
            Order.class);
            Order order1 = orderJAXBElement.getValue();
            String itemName =order1.getItems().item.get(0).getName();
            System.out.println("Item name " + itemName );

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

So we are done. One important thing to mention is with the jaxb 2 xml validation part is being lost(for ans example lets say we need to restrict a particular element to have only specific string values, then the unmarshalling process should throw and parsing exception)

 But in case of you need to validate xml you can do it by setting the schema file to the unmarshaller object as follows.
SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);  

     jaxbUnmarshaller.setSchema(sf.newSchema(new File("/path/sample.xsd")));