Showing posts with label rest. Show all posts
Showing posts with label rest. Show all posts

Monday, January 2, 2023

My GitHub Repo #04 : HoChiMinh

Code Samples for the Blog Article 
[REST Using Apache Wink - XML/JSON]
MIT License, Copyright (c) 2018-19, Sumith Kumar Puri
https://github.com/sumithpuri








Project Codename

HoChiMinh

Blog Post URL

http://www.techilashots.blog/2015/03/rest-using-apache-wink-xmljson.html

Blog Short URL

https://rebrand.ly/skp-ts-blog-04

Package Prefix

me.sumithpuri.github.hochiminh

GitHub URL

https://github.com/sumithpuri/skp-code-marathon-hochiminh

Contact E-Mail

code@sumithpuri.xyz

Contact Number

+91 9591497974 (WhatsApp, Viber, Telegram)

Historical

 Started this Movement of 1000s of Lines of Java / J2EE* Code to GitHub

 Was a Senior Software Architect (Java/J2EE) in Manila*, 2018 (At Start) 

 Named this Initial Code Journey as [ Manila Code Marathon - 2018 ]

 Code Is Non-Proprietary and Non-Copyright from my Work Experience.

 Was Back to Bangalore, Named as [ Bangalore Code Nights - 2019. ]

 Added More Code under [ -20 Days of Code in Benglauru- ] in 2020

 Celebration of Java/Java EE Code as Java Turned 25 in the Year ~ 2020!

  

Thursday, March 12, 2015

REST Using Apache Wink (XML/JSON)

[GitHub Repository for Code Samples]
https://github.com/sumithpuri/skp-code-marathon-hochiminh
 
Representational State Transfer (REST)
Hypermedia as the Engine of Application State (HATEOAS)
 
 
As mentioned earlier, this is  the second in series on REST Using Apache Wink. You can understand how to use complex return types, such as XML using JAXB and Json using Jackson as the stream reader or stream writer.

Firstly, setup the REST project as described in REST Using Apache Wink

1. Returning XML using JAXB
The class whose object that has to be returned to the client has to be first annotated using the following annotations:

1. XMLRootElement
The root element of the xml that has to be returned, at the class level

2. XMLAttribute
An attribute of the root element that has to be returned

3. XMLElement
An element contained within the root element

This can be used in a nested way to allow multiple levels of nested objects to be returned to the invoker.
 package me.sumithpuri.rest.vo;  
 import javax.xml.bind.annotation.XmlAttribute;  
 /**  
  * @author sumith_puri  
  *  
  */  
 @XmlRootElement(name="product")  
 public class Product {  
      long id;  
      String name;  
      @XmlAttribute  
      public long getId() {  
           return id;  
      }  
      public void setId(long id) {  
           this.id = id;  
      }  
      @XmlElement(name="name")  
      public String getName() {  
           return name;  
      }  
      public void setName(String name) {  
           this.name = name;  
      }  
      public String toString() {  
           String productStr="ID:" + this.id + ", NAME: " + this.name;  
           return productStr;  
      }  
 }  

The respective method(s) now need to annotated to return XML using @Produces.
      @GET  
      @Path("/{id}")  
      @Produces(MediaType.APPLICATION_XML)  
      public Product getProductById(@PathParam(value="id") long id) {  
           Product product = persistenceManager.getProduct(id);  
           return product;  
      }  

We can access this method now using a REST Client
      public void invokeJAXBGET(long id) {  
           System.out.println("Testing JAXB GET command....");       
           RestClient restClient = new RestClient(clientConfig);  
           Resource resource = restClient.resource(REST_WEB_SERVICE+"/"+id);  
           ClientResponse response=resource.accept(MediaType.APPLICATION_XML).get();  
           System.out.println("...JAXB GET command is successful");  
      }  

On the browser, type the url : http://localhost:8080/products/rest/product/3
<product id="3">
<name>Sumith Puri</name>
</product> 

2. Returning JSON using Jackson
Jackson is an extension over JAXB to return JSON from REST web service. It can be used as the mapper to convert from JAXB. First, include the relevant Jackson JARs:

We also have to write an application class, to register the mapper.
 package me.sumithpuri.rest.app;  

 import java.util.HashSet;  
 import java.util.Set;  
 import javax.ws.rs.core.Application;  
 import me.sumithpuri.rest.webservice.ProductWebService;  
 import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;  
 import org.codehaus.jackson.map.AnnotationIntrospector;  
 import org.codehaus.jackson.map.ObjectMapper;  
 import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;  


 public class ProductApplication extends Application {  
      @Override  
      public Set<Class<?>> getClasses() {  
           Set<Class<?>> classes = new HashSet<Class<?>>();  
           classes.add(ProductWebService.class);  
           return classes;  
      }  
      @Override  
      public Set<Object> getSingletons() {  
           Set<Object> s = new HashSet<>();  
           ObjectMapper objMapper = new ObjectMapper();  
           AnnotationIntrospector primary = new JaxbAnnotationIntrospector();  
           AnnotationIntrospector secondary = new JaxbAnnotationIntrospector();  
           AnnotationIntrospector pair = AnnotationIntrospector.pair(primary, secondary);  
           objMapper.getDeserializationConfig().withAnnotationIntrospector(pair);  
           objMapper.getSerializationConfig().withAnnotationIntrospector(pair);  
           JacksonJaxbJsonProvider jaxbProvider = new JacksonJaxbJsonProvider();  
           jaxbProvider.setMapper(objMapper);  
           s.add(jaxbProvider);  
           return s;  
      }  
 }  

Next, change the Apache Wink configuration in your web.xml as follows:
 <?xml version="1.0" encoding="UTF-8"?>  
 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  
  <display-name>products</display-name>  
  <servlet>  
   <servlet-name>restService</servlet-name>  
   <servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>  
   <init-param>  
    <!-- <param-name>applicationConfigLocation</param-name> -->  
    <!-- <param-value>/WEB-INF/application</param-value> -->  
    <param-name>javax.ws.rs.Application</param-name>  
    <param-value>me.sumithpuri.rest.app.ProductApplication</param-value>  
   </init-param>  
  </servlet>  
  <servlet-mapping>  
   <servlet-name>restService</servlet-name>  
   <url-pattern>/rest/*</url-pattern>  
  </servlet-mapping>  
 </web-app>  

The next is to add the relevant method to the service, and mark that it returns JSON. 
      @GET  
      @Path("/json/{id}")  
      @Produces(MediaType.APPLICATION_JSON)  
      public Product getProductJsonById(@PathParam(value="id") long id) {  
           Product product = persistenceManager.getProduct(id);  
           return product;  
      }  

Now, add the method to the client to test out the method.
      public void invokeJSONGET(long id) {  
           System.out.println("Testing JSON GET command....");       
           RestClient restClient = new RestClient(clientConfig);  
           Resource resource = restClient.resource(REST_WEB_SERVICE+"/json/"+id);  
           ClientResponse response=resource.accept(MediaType.APPLICATION_JSON).get();  
           System.out.println("...JSON GET command is successful");  
      }  

On the browser, type the url : http://localhost:8080/products/rest/product/json/3 
{"id":3,"name":"Sumith Puri"}

You may download the war, including source, for reference from here.


[GitHub Repository for Code Samples]
https://github.com/sumithpuri/skp-code-marathon-hochiminh
 

Sunday, February 15, 2015

REST Using Apache Wink

Representational State Transfer (REST)
Hypermedia as the Engine of Application State (HATEOAS)
  
 
I built this Product Web Service using Apache Wink. It can perform add, update, delete and retrieval of products in memory. I intend to explain the basics of REST using Apache Wink using this. REST stands for Representational State Transfer. REST is based on the concepts of Roy Fielding’s dissertation work as part of his thesis. It works on the HTTP protocol and has the following differences when compared to SOAP:
  • Works on HTTP protocol, as compared to SOAP which creates their own protocol
  • Uses HTTP GET, PUT, POST, DELETE as compared to SOAP which uses only POST
  • It uses the HTTP infrastructure, whereas SOAP is transport neutral     
  • The producer and consumer are aware of the content being exchanged     
  • It does not support many Non Functional Requirements or any WS-* Standards

INSTALLATIONS REQUIRED
Eclipse 4.2.0
Apache Wink 1.4.0
Apache Tomcat 8.0.9
JDK 1.7.0 / JRE 1.7.0
 

SERVER / WEB SERVICE
The steps to build the web service using Apache Wink are given below:

1.     Create a Dynamic Web Project in Eclipse

2.     Build the Core Application that performs CRUD 
 /**   
  *    
  */   
  package me.sumithpuri.rest.persistence;   
     
     
  import java.util.ArrayList;   
  import java.util.List;   
     
  import me.sumithpuri.rest.vo.Product;   
     
  /**   
  * @author sumith_puri   
  *   
  */   
  public class ProductPersistenceManager {   
     
    private List<Product> productDatabase = new ArrayList<Product>();   
    private static ProductPersistenceManager persistenceManager;   
    private static int id=0;   
       
    private ProductPersistenceManager() {   
          
    }   
       
    public void add(Product product) {   
          
       System.out.println("database: added one product");   
          
       // atomic id creation   
       id++;   
       product.setId(id);   
       productDatabase.add(product);   
    }   
       
    public List<Product> get() {   
       System.out.println("database: retrieved all products");   
       return productDatabase;   
    }   
       
    public void update(long productId, String productName) {   
       System.out.println("database: modified one product");   
          
       for(int i=0;i<productDatabase.size();i++) {   
            
         Product product = productDatabase.get(i);   
         if(product.getId()==productId) {   
            product.setName(productName);   
            productDatabase.remove(i);   
            productDatabase.add(i,product);   
         }   
       }   
       return;   
    }   
       
    public void delete(long productId) {   
       System.out.println("database: deleted one product");   
          
       for(int i=0;i<productDatabase.size();i++) {   
            
         Product product = productDatabase.get(i);   
         if(product.getId()==productId) productDatabase.remove(i);   
       }   
       return;   
    }   
       
    public static ProductPersistenceManager getInstance() {   
          
       if(persistenceManager==null) {   
         synchronized(ProductPersistenceManager.class) {   
            if(persistenceManager==null) {   
              persistenceManager = new ProductPersistenceManager();   
            }   
         }   
       }   
       return persistenceManager;   
    }   
  }   

3. Add the Supporting JAR files in the Build Path

4. Create the REST Web Service using Apache Wink (GET, POST, DELETE, PUT)
 package me.sumithpuri.rest.webservice;  
   
   
 import java.util.List;  
   
 import javax.ws.rs.DELETE;  
 import javax.ws.rs.GET;  
 import javax.ws.rs.POST;  
 import javax.ws.rs.PUT;  
 import javax.ws.rs.Path;  
 import javax.ws.rs.PathParam;  
 import javax.ws.rs.Produces;  
 import javax.ws.rs.core.MediaType;  
   
 import me.sumithpuri.rest.persistence.ProductPersistenceManager;  
 import me.sumithpuri.rest.vo.Product;  
   
 /**  
  * @author sumith_puri  
  *  
  */  
 @Path("product")  
 public class ProductWebService {  
   
     ProductPersistenceManager persistenceManager = ProductPersistenceManager.getInstance();  
       
     @GET  
     @Produces(MediaType.TEXT_PLAIN)  
     public String getProducts() {  
           
         List<Product> products = persistenceManager.get();  
         String productList = new String();  
           
         for(Product producti: products) {  
             productList+=producti.toString() + "\n";  
         }  
           
         // return as plain text - other types include xml, json  
         return productList;  
     }  
       
     @POST  
     public String addProducts(String productStr) {  
           
         Product product = new Product();  
         product.setName(productStr);  
         persistenceManager.add(product);  
           
         return productStr;  
     }  
       
     @DELETE  
     @Path("/{id}")  
     public void deleteProduct(@PathParam(value="id") long id) {  
           
         persistenceManager.delete(id);  
         return;  
     }  
       
     @PUT  
     @Path("/{id}")  
     public void modifyProduct(@PathParam(value="id") long id, String productName) {  
           
         persistenceManager.update(id, productName);  
         return;  
     }  
 }  
   

5.  Configure Application for Apache Wink
To allow Apache Wink to locate this service as a REST web service, you can either define an additional class or configure an application file. We are using an application to mention all our web service.

You can place this under WEB-INF/ and name the file as simply ‘application’ (without any extension).
 me.sumithpuri.rest.webservice.ProductWebService  

Next, you need to specify the servlet related configuration for allowing Apache Wink REST Servlet to locate this appliatiocn configuration, by specifying the location of ‘application’ as the parameter ‘applicationConfigLocation’ in WEB-INF/web.xml
 <?xml version="1.0" encoding="UTF-8"?>  
 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  
  <display-name>products</display-name>  
  <servlet>  
   <servlet-name>restService</servlet-name>  
   <servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>  
   <init-param>  
    <param-name>applicationConfigLocation</param-name>  
    <param-value>/WEB-INF/application</param-value>  
   </init-param>  
  </servlet>  
  <servlet-mapping>  
   <servlet-name>restService</servlet-name>  
   <url-pattern>/rest/*</url-pattern>  
  </servlet-mapping>  
 </web-app>  

6. Deploy as Apache Tomcat Web App, Directly

CLIENT / WEB SERVICE CLIENT
The steps to test the web service or write a REST client are as follows:

1. Create a Java Project in Eclipse
2. Include the Support Client JAR files in the Classpath

3. Build the client to test or access GET method
4. Build the client to test or access POST method
5. Build the client to test or access DELETE method
6. Build the client to test or access PUT method
 package me.sumithpuri.rest.client;  
   
 import javax.ws.rs.core.MediaType;  
   
 import org.apache.wink.client.ClientConfig;  
 import org.apache.wink.client.Resource;  
 import org.apache.wink.client.RestClient;  
   
   
 /**  
  * @author sumith_puri  
  *  
  */  
 class ProductRESTClient {  
   
     static String REST_WEB_SERVICE="http://localhost:8080/products/rest/product";  
     static ClientConfig clientConfig = new ClientConfig();  
   
     /**  
      * @param args  
      */  
     public static void main(String[] args) throws Exception {  
                   
         try {  
               
             ProductRESTClient restClient = new ProductRESTClient();              
             System.out.println("Apache Wink Based REST Client");  
             System.out.println("Sumith Kumar Puri (c) 2015");  
             System.out.println("=============================");  
               
             restClient.configureClient();  
             System.out.println();  
               
             restClient.invokeGET();  
             System.out.println();  
                       
             String product="Sumith Puri" + (int) (Math.random()*9999);  
             restClient.invokePOST(product);  
               
             System.out.println();  
             product="Sumith Puri" + (int) (Math.random()*9999);  
             restClient.invokePOST(product);  
               
             System.out.println();  
             product="Sumith Puri" + (int) (Math.random()*9999);  
             restClient.invokePOST(product);  
               
             System.out.println();  
             product="Sumith Puri" + (int) (Math.random()*9999);  
             restClient.invokePOST(product);  
               
             System.out.println();  
             restClient.invokeGET();  
               
             System.out.println();  
             restClient.invokeDELETE(2L);  
               
             System.out.println();  
             restClient.invokeGET();  
               
             System.out.println();  
             product="Sumith Puri" + (int) (Math.random()*9999);  
             restClient.invokePOST(product);  
               
             System.out.println();  
             product="Sumith Puri" + (int) (Math.random()*9999);  
             restClient.invokePOST(product);  
   
             System.out.println();  
             restClient.invokeDELETE(4L);  
   
             System.out.println();  
             restClient.invokeGET();  
               
             System.out.println();  
             restClient.invokePUT(3L,"Sumith Puri");  
               
             System.out.println();  
             restClient.invokeGET();  
         } catch (Exception e) {  
               
             e.printStackTrace();  
         }  
     }  
       
   
     public void configureClient() {  
   
     }  
       
     public void invokeGET() {  
           
         System.out.println("Testing GET command....");      
         RestClient restClient = new RestClient(clientConfig);  
         Resource resource = restClient.resource(REST_WEB_SERVICE);  
         String response = resource.accept("text/plain").get(String.class);  
         System.out.printf(response);  
         System.out.println("...GET command is successful");  
     }  
       
     public void invokePOST(String product) {  
           
         System.out.println("Testing POST command...");  
         RestClient restClient = new RestClient(clientConfig);  
         Resource resource = restClient.resource(REST_WEB_SERVICE);  
         resource.contentType(MediaType.TEXT_PLAIN).accept(MediaType.TEXT_PLAIN).post(String.class,product);  
         System.out.println("...POST command is successful");  
     }  
   
       
     public void invokePUT(Long id, String productName) {  
           
         System.out.println("Testing PUT command...");  
         RestClient restClient = new RestClient(clientConfig);  
         Resource resource = restClient.resource(REST_WEB_SERVICE+"/"+id);  
         resource.contentType(MediaType.TEXT_PLAIN).accept(MediaType.TEXT_PLAIN).put(String.class, productName);  
         System.out.println("...PUT command is successful");  
     }  
       
     public void invokeDELETE(Long id) {  
           
         System.out.println("Testing DELETE command...");  
         RestClient restClient = new RestClient(clientConfig);  
         Resource resource = restClient.resource(REST_WEB_SERVICE+"/"+id);  
         resource.contentType(MediaType.TEXT_PLAIN).accept(MediaType.TEXT_PLAIN).delete();  
         System.out.println("...DELETE command is successful");  
     }  
 }  
   



OUTPUT (FIRST ACCESS)
Apache Wink Based REST Client
Sumith Kumar Puri (c) 2015
=============================

Testing GET command....
...GET command is successful

Testing POST command...
...POST command is successful

Testing POST command...
...POST command is successful

Testing GET command....
ID:1, NAME: Sumith Puri3169
ID:2, NAME: Sumith Puri6052
...GET command is successful

Testing DELETE command...
...DELETE command is successful

Testing GET command....
ID:1, NAME: Sumith Puri3169
...GET command is successful

Testing POST command...
...POST command is successful

Testing POST command...
...POST command is successful

Testing DELETE command...
...DELETE command is successful

Testing GET command....
ID:1, NAME: Sumith Puri3169
ID:3, NAME: Sumith Puri732
...GET command is successful

Testing PUT command...
...PUT command is successful

Testing GET command....
ID:1, NAME: Sumith Puri3169
ID:3, NAME: Sumith Puri
...GET command is successful


DOWNLOADS
You may download the products.war (including source) web service as well as the products-client.jar (including source).


CONCLUSION
In this blog, you have seen how to build REST web services using Apache Wink for basic data types. Next, I will blog on how to include Jackson or Jettison as the stream reader or stream writer JSON libraries, so that we can read and write complex or application object types. It will be titled ‘REST Using Apache Wink and Jackson/Jettison’.


[GitHub Repository for Code Samples]
https://github.com/sumithpuri/skp-code-marathon-hochiminh