By kswaughs | Thursday, June 9, 2016

AngularJS Rest Service Example

Use Case
1. Display the list of topics available in www.kswaughs.com
2. Allows user to enter the topic and prints error message if topic is not available
3. Make a rest service call with GET method and print titles of requested topic blog posts

HTML & AngularJS code
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script>
    var app = angular.module('AngularRestApp', []);
    app.controller('restExample', function($scope, $http) {

        $scope.topics = [ 'Java', 'Camel', 'Apache-CXF', 'Junit', 'REST', 'spring' ];

        $scope.submit = function() {

            if ($scope.topics.indexOf($scope.topic) == -1) {
                $scope.error = 'Entered Topic is Not available.' +
                               ' Also, It is a Case sensitive';
            } else {
                $scope.error = '';
                $scope.getBlogPosts();
            }
        };

        $scope.getBlogPosts = function() {

            $http.get(
                    "http://www.kswaughs.com/feeds/posts/summary/-/"
                            + $scope.topic + "?alt=json").then(
                    function(response) {
                        $scope.myData = response.data.feed.entry;
                        $scope.myPost = $scope.topic;
                    });

        };

    });
</script>
</head>
<body>
    <div ng-app="AngularRestApp" ng-controller="restExample">
        <b>List of topics available in www.kswaughs.com</b>
            <ul>
                <li ng-repeat="x in topics">{{$index+1}} {{x}}</li>
            </ul>
            <br/>    
            <label>Topic:</label>
            <input type="text" ng-model="topic" placeholder="Enter topic here"> 
            <input type="button" value="Get Posts" ng-click="submit()" />

        <p ng-bind="error" style="color:red"></p>
        <hr />
        <p>
            <b>Posts of {{myPost}} </b>
        </p>
        <ul>
            <li ng-repeat="entry in myData">
                <a ng-repeat="link in entry.link | filter:{rel: 'alternate'}"
                href="{{link.href}}">{{entry.title.$t}}</a>
            </li>
        </ul>
    </div>
</body>
</html>

DEMO


List of topics available in www.kswaughs.com
  • {{$index+1}} {{x}}

 


Posts of {{myPost}}


Recommend this on


By kswaughs | Friday, April 1, 2016

Rest service with Jersey-Filters-Interceptors-Exceptions

This tutorial explains how to develop a rest service with Jersey API and will go through the below components involved in developing with Jersey framework.

1. Maven Dependencies

2. Define Rest service with Jax-RS annotations

3. Jersey servlet configuration

4. Exception Handling

5. Filters Configuration

6. Interceptors Configuration

1. Maven Dependencies

pom.xml
<dependencies>
    <dependency>
        <groupId>org.glassfish.jersey.bundles</groupId>
        <artifactId>jaxrs-ri</artifactId>
        <version>2.22.2</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.12</version>
    </dependency>
</dependencies>

2. Define Rest service with Jax-RS annotations

Create a Rest service with GET method.

BookService
package com.kswaughs.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.kswaughs.rest.beans.Book;

@Path("/book")
@Produces(MediaType.APPLICATION_JSON)
public class BookService {
    
    @GET
    @Path("/{authorID}")
    public Response getBooks(@PathParam("authorID") String authorID) {
        
        Book book = new Book();
        
        book.setId(authorID);
        book.setName("A Monk who sold his Ferrari");
        book.setAuthor("Robin Sharma");
        
        return Response.status(200).
                entity(book).build();
    }

}

Below is the Book entity

Book
package com.kswaughs.rest.beans;

public class Book {
    
    private String id;
    
    private String name;
    
    private String author;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
    
}

3. Jersey servlet configuration

web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>jaxrs-book-service</display-name>

    <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.kswaughs.rest, org.codehaus.jackson.jaxrs</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
</web-app>

Testing :

method : GET
URL : http://localhost:8080/simple_rest/book/123

Response
{
   "id": "123",
   "name": "A Monk who sold his Ferrari",
   "author": "Robin Sharma"
}

4. Exception Handling

Let us create below exception classes one for 'Invalid Author' and other for 'Books not found'.

AuthorException
package com.kswaughs.rest.beans;

public class AuthorException extends Exception {
    
    public AuthorException(String message) {
        super(message);
    }
}

BookException
package com.kswaughs.rest.beans;

public class BookException extends Exception{
    
    public BookException(String message) {
        super(message);
    }
}

We will modify our BookService GET method to validate the above errors.

BookService
package com.kswaughs.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.kswaughs.rest.beans.AuthorException;
import com.kswaughs.rest.beans.Book;
import com.kswaughs.rest.beans.BookException;

@Path("/book")
@Produces(MediaType.APPLICATION_JSON)
public class BookService {
    
    @GET
    @Path("/{authorID}")
    public Response getBooks(@PathParam("authorID") String authorID) throws Exception {
        
        if("0".equals(authorID)) {
            throw new AuthorException("invalid author");
        }
        
        if("1".equalsIgnoreCase(authorID)) {
            throw new BookException("Books Not found");
        }
        
        Book book = new Book();
        
        book.setId("122");
        book.setName("A Monk who sold his Ferrari");
        book.setAuthor("Robin Sharma");
        
        return Response.status(200).
                entity(book).build();
    }

}

Write custom Exception handlers that implements ExceptionMapper class for each kind of exception and annotate each class with @Provider.

AuthorExceptionHandler
package com.kswaughs.rest.handlers;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

import com.kswaughs.rest.beans.AuthorException;
import com.kswaughs.rest.beans.Book;

@Provider
public class AuthorExceptionHandler implements
    ExceptionMapper<AuthorException> {

    @Override
    public Response toResponse(AuthorException  err) {
        
        System.out.println("Exception occured:" + err);
        
        Book resp = new Book();
        resp.setId("404");
        resp.setName("Author not found");
        
        return Response.status(Status.NOT_FOUND).entity(resp).build();
    }
}

BookExceptionHandler
package com.kswaughs.rest.handlers;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

import com.kswaughs.rest.beans.Book;
import com.kswaughs.rest.beans.BookException;

@Provider
public class BookExceptionHandler implements
    ExceptionMapper<BookException> {

    @Override
    public Response toResponse(BookException  err) {
        
        System.out.println("Exception occured:" + err);
        
        Book resp = new Book();
        resp.setId("404");
        resp.setName("Books not found");
        
        return Response.status(Status.NOT_FOUND).entity(resp).build();
    }
}

Test : 1

method : GET
URL : http://localhost:8080/simple_rest/book/0

Response
{
   "id": "404",
   "name": "Author not found",
   "author": null
}

Console Logs:
Exception occured:com.kswaughs.rest.beans.AuthorException: invalid author

Test : 2

method : GET
URL : http://localhost:8080/simple_rest/book/1

Response
{
   "id": "404",
   "name": "Books not found",
   "author": null
}

Console Logs:
Exception occured:com.kswaughs.rest.beans.BookException: Books Not found

5. Filters Configuration

Filters are mainly used to manipulate request and response parameters like HTTP headers, URIs & HTTP methods.

Create a custom class that implements ContainerRequestFilter, ContainerResponseFilter to update request and response headers. Here, we are calculating the request processing time and sending this value in response header. Start time is calculated and stored in request headers before processing the request and processing time is calculated and sending in response headers after processing the request.

BookFilter
package com.kswaughs.rest.filters;

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

import com.kswaughs.rest.bindings.UpdateHeader;

@UpdateHeader
@Provider
public class BookFilter implements ContainerRequestFilter, ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext reqCtx) throws IOException {
        
        System.out.println("Adding start time in request headers");
        
        reqCtx.getHeaders().add("startTime", String.valueOf(System.currentTimeMillis()));
        
    }

    @Override
    public void filter(ContainerRequestContext reqCtx,
            ContainerResponseContext respCtx) throws IOException {

        System.out.println("Adding ProcessingTime in response headers");
        
        long startTime = Long.parseLong( reqCtx.getHeaderString("startTime") );
        
        respCtx.getHeaders().add("ProcessingTime", 
            String.valueOf(System.currentTimeMillis()-startTime ) + " millisecs" );
    }

}

When we configure the package name of this filter in init-param of jersey servlet in web.xml, This filter will be executed for all methods of all rest services. We use Name binding so that a specific filter or interceptor will be executed only for a specific resource method.

To configure a Name binding, create a new annotation interface and use the @NameBinding annotation on this interface.

UpdateHeader
package com.kswaughs.rest.bindings;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import javax.ws.rs.NameBinding;

@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface UpdateHeader {

}

In the above, BookFilter class is already annotated with @UpdateHeader.

Now adding a new POST method and we will apply this filter to this method only.

BookService
package com.kswaughs.rest;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.kswaughs.rest.beans.AuthorException;
import com.kswaughs.rest.beans.Book;
import com.kswaughs.rest.beans.BookException;
import com.kswaughs.rest.beans.BookResponse;
import com.kswaughs.rest.bindings.UpdateHeader;

@Path("/book")
@Produces(MediaType.APPLICATION_JSON)
public class BookService {
    
    @GET
    @Path("/{authorID}")
    public Response getBooks(@PathParam("authorID") String authorID) throws Exception {
        
        if("0".equals(authorID)) {
            throw new AuthorException("invalid author");
        }
        
        if("1".equalsIgnoreCase(authorID)) {
            throw new BookException("Books Not found");
        }
        
        Book book = new Book();
        
        book.setId("122");
        book.setName("A Monk who sold his Ferrari");
        book.setAuthor("Robin Sharma");
        
        return Response.status(200).
                entity(book).build();
    }
    
    @POST
    @Path("/add")
    @UpdateHeader
    public Response addBook(@Context HttpHeaders headers,  Book book) {
        
        System.out.println("Req Headers :" + headers.getRequestHeaders());
                
        BookResponse resp = new BookResponse();
        resp.setId(book.getId());
        resp.setStatus("Book added successfully.");
        
        return Response.status(200).
                entity(resp).build();
    }

}

Below is the response entity bean of this new method.

BookResponse
package com.kswaughs.rest.beans;

public class BookResponse {

    private String id;

    private String status;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}

Test with Filters

method : POST
operation : add
URL : http://localhost:8080/simple_rest/book/add

Request
{ "id" : "2222", 
  "name" : "P.S I Love you",
  "author" : "Cecelia Ahern"
}

Response
{
   "id": "2222",
   "status": "Book added successfully."
}

Console Logs:
Adding start time in request headers
Req Headers :{accept-encoding=[gzip,deflate], content-type=[application/json], content-length=[78], host=[localhost:8080], connection=[Keep-Alive], user-agent=[Apache-HttpClient/4.1.1 (java 1.5)], startTime=[1459520672878]}
Adding ProcessingTime in response headers

Response Headers
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
ProcessingTime: 3 millisecs
Content-Type: application/json
Content-Length: 49
Date: Fri, 01 Apr 2016 14:24:32 GMT

6. Interceptors Configuration

Interceptors are used to manipulate entity input/output streams. In another sense, request and response body.

In this example, We are creating a new class that implements ReaderInterceptor, WriterInterceptor and override the required methods with sysout statements.

BookInterceptor
package com.kswaughs.rest.interceptors;

import java.io.IOException;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.ReaderInterceptorContext;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;

import com.kswaughs.rest.bindings.UpdateHeader;

@Provider
@UpdateHeader
public class BookInterceptor implements  ReaderInterceptor, WriterInterceptor {

    @Override
    public Object aroundReadFrom(ReaderInterceptorContext ctx)
            throws IOException, WebApplicationException {
        
          System.out.println("Intercepted request");
        
        return ctx.proceed();
    }

    @Override
    public void aroundWriteTo(WriterInterceptorContext ctx)
            throws IOException, WebApplicationException {
        
        System.out.println("Intercepted response");
        
        ctx.proceed();
        
    }
}

Test with Interceptors

method : POST
operation : add
URL : http://localhost:8080/simple_rest/book/add

Request
{ "id" : "2222", 
  "name" : "P.S I Love you",
  "author" : "Cecelia Ahern"
}

Response
{
   "id": "2222",
   "status": "Book added successfully."
}

Console Logs:
Adding start time in request headers
Intercepted request
Req Headers :{accept-encoding=[gzip,deflate], content-type=[application/json], content-length=[78], host=[localhost:8080], connection=[Keep-Alive], user-agent=[Apache-HttpClient/4.1.1 (java 1.5)], startTime=[1459521292860]}
Adding ProcessingTime in response headers
Intercepted response

Response Headers
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
ProcessingTime: 7 millisecs
Content-Type: application/json
Content-Length: 49
Date: Fri, 01 Apr 2016 14:34:52 GMT

Recommend this on


By kswaughs | Wednesday, February 24, 2016

Rest Service with Spring Boot

What is Spring Boot ?

  • Spring Boot simplifies the process of configuring and deploying the spring based applications.
  • Spring Boot is not a framework. It helps us to build, package and deploy Spring applications with minimal or no configurations.
  • Web applications or web services including RESTful services can be built as JAR file that can be run as stand-alone java application and no need to deploy in any external application server.

Spring Boot - Rest Service Example

In this below example, I will show you how to create a RESTful service with Spring Boot.

Step 1 : Use below maven dependency in your pom.xml. This jar will internally pulls all the required dependent jars in your classpath.

pom.xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>1.3.0.RELEASE</version>
    </dependency>
</dependencies>

Step 2 : Create a main class which will initialize and runs the spring boot application.

BootApp
package com.kswaughs.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan({ "com.kswaughs.web" })
public class BootApp {
 
    public static void main(String[] args) {
  
        SpringApplication.run(new Object[] { BootApp.class }, args);

    }

}

Step 3 : Create Controller class to serve the rest service requests

UserController
package com.kswaughs.web.controller;

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.bind.annotation.RestController;

import com.kswaughs.web.beans.UserReq;
import com.kswaughs.web.beans.UserResp;

@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
    public UserResp getUser(@PathVariable String id) {

        UserResp resp = new UserResp();
  
        resp.setId(id);
        resp.setStatus("SUCCESS");
        resp.setMessage("GET Method Processed successfully");

        return resp;
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public UserResp addUser(@RequestBody UserReq req) {

        UserResp resp = new UserResp();
  
        resp.setId(req.getId());
        resp.setStatus("SUCCESS");

        StringBuilder msg = new StringBuilder()
            .append("Hi ")
            .append(req.getName())
            .append(", POST method Processed successfully");
  
        resp.setMessage(msg.toString());
  
        return resp;
    }

}

Step 4 : Create below model objects to convert JSON requests and responses into java objects.

Request Object - UserReq
package com.kswaughs.web.beans;

public class UserReq {
 
    private String id;
 
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("UserReq [id=");
        builder.append(id);
        builder.append(", name=");
        builder.append(name);
        builder.append("]");
        return builder.toString();
    }
}

Response Object - UserResp
package com.kswaughs.web.beans;

public class UserResp {
 
    private String status;
 
    private String id;
 
    private String message;

    public String getStatus() {
         return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("UserResp [status=");
        builder.append(status);
        builder.append(", id=");
        builder.append(id);
        builder.append(", message=");
        builder.append(message);
        builder.append("]");
        return builder.toString();
    }
}

Step 5 : Start the application. You can start this application as a normal stand-alone java application and I am explaining below different ways of running this application.

  1. Run from Eclipse
  2. Run from Maven command
  3. Run from jar

1. Run from Eclipse

From Eclipse IDE, Go to BootApp.java class and Run as Java application.

2. Run from Maven command

Add below artifact as your parent pom in your pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.0.RELEASE</version>
</parent>

Run with maven command mvn spring-boot:run.

3. Run from jar

Add below maven build plugin

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Run maven command mvn package and it generates jar file with project_name in target directory.

Run the command java -jar target/project_name-1.0.jar from command line.

Step 6: Test the application

  
 Test 1 : 
 operation : get
 method : GET
 URL : http://localhost:8080/user/get/12345
 Response :
 
 {
    "status": "SUCCESS",
    "id": "12345",
    "message": "GET Method Processed successfully"
 }
 Test 2 :
 operation : add
 method : POST
 URL : http://localhost:8080/user/add
 Request
 { "id" : "2222", "name" : "kswaughs" }

 Response
 {
    "status": "SUCCESS",
    "id": "2222",
    "message": "Hi kswaughs, POST method Processed successfully"
 }

Recommend this on


By kswaughs | Thursday, December 24, 2015

Spring restful service without web.xml

Spring 3 WebMVC provides a lot of features and makes Spring developers easier to develop several applications like Web applications and REST services. Spring 3.2.10.RELEASE version has more advanced features with Spring annotations where developers need not to define web.xml or any other kind of context xmls.

In this below example, I will show you how to use Spring 3 MVC annotations to develop a RESTful service.

Step 1 : Create a Configuration class that extends WebMvcConfigurerAdapter which is equivalent to spring dispatcher application context xml.

SpringWebConfig
package com.kswaughs.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@EnableWebMvc 
@Configuration
@ComponentScan({ "com.kswaughs.web" })
public class SpringWebConfig extends WebMvcConfigurerAdapter {
   
}

Step 2 : Create a Spring Web Initializer class that extends AbstractAnnotationConfigDispatcherServletInitializer which is equivalent to web.xml.

SpringWebInitializer
package com.kswaughs.servlet;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import com.kswaughs.config.SpringWebConfig;

public class SpringWebInitializer extends
    AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class[] getServletConfigClasses() {
        return new Class[] { SpringWebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Class[] getRootConfigClasses() {
        return new Class[] {};
    }

}

Step 3 : Create Controller class to serve the rest service requests

UserController
package com.kswaughs.web.controller;

import org.springframework.stereotype.Controller;
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.bind.annotation.ResponseBody;

import com.kswaughs.web.beans.UserReq;
import com.kswaughs.web.beans.UserResp;

@Controller
@RequestMapping("usersvc")
public class UserController {

    @RequestMapping(value = "get/{id}", method = RequestMethod.GET)
    @ResponseBody
    public UserResp getUser(@PathVariable String id) {

        UserResp resp = new UserResp();
  
        resp.setId(id);
        resp.setStatus("SUCCESS");
        resp.setMessage("GET Method Processed successfully");

        return resp;
    }

    @RequestMapping(value = "add", method = RequestMethod.POST)
    @ResponseBody
    public UserResp addUser(@RequestBody UserReq req) {

        UserResp resp = new UserResp();
  
        resp.setId(req.getId());
        resp.setStatus("SUCCESS");

        StringBuilder msg = new StringBuilder()
            .append("Hi ").append(req.getName())
            .append(", POST method Processed successfully");
  
        resp.setMessage(msg.toString());

        return resp;
    }
}

Step 4 : Create below model objects to convert JSON requests and responses into java objects.

Request Object - UserReq
package com.kswaughs.web.beans;

public class UserReq {
 
    private String id;
 
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("UserReq [id=");
        builder.append(id);
        builder.append(", name=");
        builder.append(name);
        builder.append("]");
        return builder.toString();
    }
}

Response Object - UserResp
package com.kswaughs.web.beans;

public class UserResp {
 
    private String status;
 
    private String id;
 
    private String message;

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("UserResp [status=");
        builder.append(status);
        builder.append(", id=");
        builder.append(id);
        builder.append(", message=");
        builder.append(message);
        builder.append("]");
        return builder.toString();
    }
}

Step 5 : Testing the service. Run the maven build and generated the war with name 'spring-rest-1.0' and deployed in Tomcat 7 server.

  
Test 1
operation : get
method : GET
URL : http://localhost:8080/spring_rest-1.0/usersvc/get/12345
Response >>
{
    "message": "GET Method Processed successfully",
    "id": "12345",
    "status": "SUCCESS"
}
Test 2
operation : add
method : POST
URL : http://localhost:8080/spring_rest-1.0/usersvc/add
Request >>
{     
    "id" : "2222", 
    "name" : "kswaughs"    
}

Response >>
{
    "status": "SUCCESS",
    "id": "2222",
    "message": "Hi kswaughs, POST method Processed successfully"
}

Use Below maven dependencies in your pom.xml. In maven war plugin, set failOnMissingWebXml to false, Otherwise maven war plugin will fail to generate WAR when web.xml is not used.

pom.xml
<properties>
    <spring.version>3.2.10.RELEASE</spring.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>1.9.13</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.13</version>
    </dependency>
</dependencies>
<build>
    <defaultGoal>install</defaultGoal>
    <plugins>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
                <archive>
                    <manifestEntries>
                        <Build-Jdk>1.6</Build-Jdk>
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

Recommend this on


By kswaughs | Thursday, November 26, 2015

How to read headers from REST response with Apache CXF

In my previous post, I have explained how to pass headers to RESTful services using Apache CXF.

CXF Rest client passing headers to request

For the same example, we will see how to read/parse headers from the REST response.

There are two ways to read/parse the headers from REST response

  • Example 1 - Using getHeaderString method of Response object to read a single header value
  • Example 1 - Using MultivaluedMap to read all header values

Using getHeaderString method of Response

Example 1
package com.example.cxfrs;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.core.Response;

import com.example.cxfrs.beans.UserRequest;
import com.example.cxfrs.beans.UserResponse;
import org.apache.cxf.jaxrs.client.WebClient;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

public class CXFRestPostClient {

 public static void main(String[] args) {

  // Adding JacksonJsonProvider to convert JSON String to Java object
  List<Object> providers = new ArrayList<Object>();
  providers.add(new JacksonJsonProvider());

  // Build REST request
  UserRequest req = new UserRequest();
  req.setId("1234578");
  req.setName("kswaughs");

  // Create WebClient 
  WebClient client = WebClient.create(
    "http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/add",
    providers);

  // Adding headers
  client = client.accept("application/json").type("application/json")
    .header("consumer_id", "StandAloneRestClient")
    .header("consumer_location", "US");

  // Call the REST service
  Response r = client.post(req);
  
  //Read/parse the response headers
  System.out.println("date:"+ r.getHeaderString("Date"));
  
  // Read/parse the response
  UserResponse resp = r.readEntity(UserResponse.class);
  
  System.out.println(resp);
 }

Server log - Response

ID: 5
Response-Code: 200
Content-Type: application/json
Headers: {Content-Type=[application/json], Date=[Fri, 27 Nov 2015 06:50:34 GMT]}
Payload: {"id":"1234578","status":"Success"}

Output is

date:Fri, 27 Nov 2015 06:50:34 GMT
UserResponse [status=Success, id=1234578]

Using MultivaluedMap to read all header values

Example 2
package com.example.cxfrs;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;

import com.example.cxfrs.beans.UserRequest;
import com.example.cxfrs.beans.UserResponse;
import org.apache.cxf.jaxrs.client.WebClient;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

public class CXFRestPostClient {

 public static void main(String[] args) {

  // Adding JacksonJsonProvider to convert JSON String to Java object
  List<Object> providers = new ArrayList<Object>();
  providers.add(new JacksonJsonProvider());

  // Build REST request
  UserRequest req = new UserRequest();
  req.setId("1234578");
  req.setName("kswaughs");

  // Create WebClient 
  WebClient client = WebClient.create(
    "http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/add",
    providers);

  // Adding headers
  MultivaluedMap<String, String> reqHeaders = new MultivaluedHashMap<String, String>();
  reqHeaders.add("consumer_id", "StandAloneRestClient");
  reqHeaders.add("consumer_location", "US");
  
  client = client.accept("application/json")
                 .type("application/json")
                 .headers(reqHeaders);

  // Call the REST service
  Response r = client.post(req);
  
  //Read/parse the response headers
  MultivaluedMap<String, String> respHeaders = r.getStringHeaders();
  System.out.println("respHeaders:\n" + respHeaders);
  
  // Read/parse the response
  UserResponse resp = r.readEntity(UserResponse.class);
  
  System.out.println(resp);
 }
}

Output is

respHeaders:
{content-type=[application/json], Date=[Fri, 27 Nov 2015 07:13:16 GMT], Server=[Apache-Coyote/1.1], transfer-encoding=[chunked], Content-Type=[application/json]}

UserResponse [status=Success, id=1234578]

Recommend this on


How to pass headers to REST request with Apache CXF

In my previous posts, I have explained how to call RESTful services using Apache CXF.

CXF Rest client to call POST method using WebClient

CXF Rest client to call GET method using WebClient

For the same example, we will see how to add custom headers to the REST request.

There are two ways to add the headers.

  • Example 1 - Chained method calls of header(key, value) on WebClient object
  • Example 1 - Using MultivaluedMap to pass multiple headers

Using header(key, value) method on WebClient object

Example 1
package com.example.cxfrs;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.core.Response;

import com.example.cxfrs.beans.UserRequest;
import com.example.cxfrs.beans.UserResponse;
import org.apache.cxf.jaxrs.client.WebClient;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

public class CXFRestPostClient {

 public static void main(String[] args) {

  List<Object> providers = new ArrayList<Object>();
  providers.add(new JacksonJsonProvider());

  UserRequest req = new UserRequest();
  req.setId("1234578");
  req.setName("kswaughs");

  WebClient client = WebClient.create(
          "http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/add",
          providers);

  client = client.accept("application/json").type("application/json")
    .header("consumer_id", "StandAloneRestClient")
    .header("consumer_location", "US");

  Response r = client.post(req);
  UserResponse resp = r.readEntity(UserResponse.class);

  System.out.println(resp);
 }
}

Using MultivaluedMap to pass multiple headers

Example 2
package com.example.cxfrs;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;

import com.example.cxfrs.beans.UserRequest;
import com.example.cxfrs.beans.UserResponse;
import org.apache.cxf.jaxrs.client.WebClient;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

public class CXFRestPostClient {

 public static void main(String[] args) {

  List<Object> providers = new ArrayList<Object>();
  providers.add(new JacksonJsonProvider());
  
  UserRequest req = new UserRequest();
  req.setId("1234578");
  req.setName("kswaughs");

  WebClient client = WebClient.create(
       "http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/add", 
       providers);
  
  MultivaluedMap<String, String> headers = 
       new MultivaluedHashMap<String, String>();
  
  headers.add("consumer_id", "StandAloneRestClient");
  headers.add("consumer_location", "US");
  
  client = client.accept("application/json").
                  type("application/json").
                  headers(headers);
  
  Response r = client.post(req);
  UserResponse resp = r.readEntity(UserResponse.class);

  System.out.println(resp);
 }
}

In the server console, See the passed header values highlighted in bold

ID: 1
Address: http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/add
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/json
Headers: {Accept=[application/json], cache-control=[no-cache], connection=[keep-alive], consumer_id=[StandAloneRestClient], consumer_location=[US], Content-Length=[34], content-type=[application/json], host=[127.0.0.1:8080], pragma=[no-cache], user-agent=[Apache CXF 3.1.2]}
Payload: {"id":"1234578","name":"kswaughs"}

Recommend this on


By kswaughs | Wednesday, November 25, 2015

CXF Rest Client to call POST method

I have a sample REST service with POST method running in my local system. This method is used to add user details.

The URL is 'http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/add'

Request is

{ "id" : "12346" , "name":"kswaughs" }

Response is

{
   "id": "12346",
   "status": "Success"
}

Create a POJO class to send the request

Request Object - UserRequest
package com.example.cxfrs.beans;

public class UserRequest {

 private String id;

 private String name;

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

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

Create a POJO class to parse the JSON response into java object

Response Object - UserResponse
package com.example.cxfrs.beans;

public class UserResponse {

 private String status;

 private String id;

 public String getStatus() {
  return status;
 }

 public void setStatus(String status) {
  this.status = status;
 }

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("UserResponse [status=");
  builder.append(status);
  builder.append(", id=");
  builder.append(id);
  builder.append("]");
  return builder.toString();
 }
}

A simple stand-alone client code using WebClient and JacksonJsonProvider.

Sample Client code to call POST Method
package com.example.cxfrs;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.core.Response;

import com.example.cxfrs.beans.UserRequest;
import com.example.cxfrs.beans.UserResponse;
import org.apache.cxf.jaxrs.client.WebClient;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

public class CXFRestPostClient {

 public static void main(String[] args) {

  List<Object> providers = new ArrayList<Object>();
  providers.add(new JacksonJsonProvider());
  
  UserRequest req = new UserRequest();
  req.setId("1234578");
  req.setName("kswaughs");

  WebClient client = WebClient
    .create("http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/add", providers);
  
  client = client.accept("application/json").type("application/json");
  
  Response r = client.post(req);
  UserResponse resp = r.readEntity(UserResponse.class);
  System.out.println(resp);
 }
}

Output is

UserResponse [status=Success, id=1234578]

Use Below maven dependency in your pom.xml to use CXF Client

<!-- To use WebClient API -->
<dependency>
 <groupId>org.apache.cxf</groupId>
 <artifactId>cxf-rt-rs-client</artifactId>
 <version>3.1.2</version>
</dependency>
<!-- To parse JSON String to Java objects --> 
<dependency>
 <groupId>org.codehaus.jackson</groupId>
 <artifactId>jackson-jaxrs</artifactId>
 <version>1.9.0</version>
</dependency> 

If you dont provide JacksonJsonProvider to WebClient, You will get below JSON parsing error.

 
org.apache.cxf.jaxrs.utils.JAXRSUtils logMessageHandlerProblem
SEVERE: No message body writer has been found for class org.example.cxfrs.beans.UserRequest, ContentType: application/json
Nov 25, 2015 3:00:48 PM org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
WARNING: Interceptor for {http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/add}WebClient has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: No message body writer has been found for class org.example.cxfrs.beans.UserRequest, ContentType: application/json
 at org.apache.cxf.jaxrs.client.WebClient$BodyWriter.doWriteBody(WebClient.java:1227)
 at org.apache.cxf.jaxrs.client.AbstractClient$AbstractBodyWriter.handleMessage(AbstractClient.java:1052)
 at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
 at org.apache.cxf.jaxrs.client.AbstractClient.doRunInterceptorChain(AbstractClient.java:636)
 at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1091)
 at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:894)
 at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:865)
 at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:331)
 at org.apache.cxf.jaxrs.client.WebClient.post(WebClient.java:340)
 at org.example.cxfrs.CXFRestPostClient.main(CXFRestPostClient.java:30)
Caused by: javax.ws.rs.ProcessingException: No message body writer has been found for class org.example.cxfrs.beans.UserRequest, ContentType: application/json
 at org.apache.cxf.jaxrs.client.AbstractClient.reportMessageHandlerProblem(AbstractClient.java:754)
 at org.apache.cxf.jaxrs.client.AbstractClient.writeBody(AbstractClient.java:485)
 at org.apache.cxf.jaxrs.client.WebClient$BodyWriter.doWriteBody(WebClient.java:1222)
 ... 9 more

Exception in thread "main" javax.ws.rs.ProcessingException: org.apache.cxf.interceptor.Fault: No message body writer has been found for class org.example.cxfrs.beans.UserRequest, ContentType: application/json
 at org.apache.cxf.jaxrs.client.WebClient.doResponse(WebClient.java:1147)
 at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1092)
 at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:894)
 at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:865)
 at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:331)
 at org.apache.cxf.jaxrs.client.WebClient.post(WebClient.java:340)
 at org.example.cxfrs.CXFRestPostClient.main(CXFRestPostClient.java:30)
Caused by: org.apache.cxf.interceptor.Fault: No message body writer has been found for class org.example.cxfrs.beans.UserRequest, ContentType: application/json
 at org.apache.cxf.jaxrs.client.WebClient$BodyWriter.doWriteBody(WebClient.java:1227)
 at org.apache.cxf.jaxrs.client.AbstractClient$AbstractBodyWriter.handleMessage(AbstractClient.java:1052)
 at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
 at org.apache.cxf.jaxrs.client.AbstractClient.doRunInterceptorChain(AbstractClient.java:636)
 at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1091)
 ... 5 more
Caused by: javax.ws.rs.ProcessingException: No message body writer has been found for class org.example.cxfrs.beans.UserRequest, ContentType: application/json
 at org.apache.cxf.jaxrs.client.AbstractClient.reportMessageHandlerProblem(AbstractClient.java:754)
 at org.apache.cxf.jaxrs.client.AbstractClient.writeBody(AbstractClient.java:485)
 at org.apache.cxf.jaxrs.client.WebClient$BodyWriter.doWriteBody(WebClient.java:1222)
 ... 9 more

Related Links
Apache Camel SOAP Service Client
Apache CXF Rest Client to call GET method

Recommend this on


CXF Rest Client to call REST service - GET method

I have a sample REST service with GET method running in my local system. This method is used to fetch user details..

The URL is 'http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/details/123'

Response is

{
   "status": "Success",
   "id": "123",
   "name": "kswaughs"
}

Create a model object to parse JSON response into java object.

Response Object - User
package com.example.cxfrs.beans;

public class User {

 private String status;

 private String id;

 private String name;

 public String getStatus() {
  return status;
 }

 public void setStatus(String status) {
  this.status = status;
 }

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

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

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("User [status=");
  builder.append(status);
  builder.append(", id=");
  builder.append(id);
  builder.append(", name=");
  builder.append(name);
  builder.append("]");
  return builder.toString();
 } 
}

A simple stand-alone client code using WebClient and JacksonJsonProvider.

Sample Client code to call get Method
package com.example.cxfrs;

import java.util.ArrayList;
import java.util.List;

import com.example.cxfrs.beans.User;
import org.apache.cxf.jaxrs.client.WebClient;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

public class CXFRestClient {

 public static void main(String[] args) {

  List<Object> providers = new ArrayList<Object>();
  providers.add(new JacksonJsonProvider());

  WebClient client = WebClient
    .create("http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/details", providers);
  
  User user = client.accept("application/json").type("application/json")
    .path("123").get(User.class);

  System.out.println(user);
 }
}

Output is

User [status=Success, id=123, name=kswaughs]

Use Below maven dependency in your pom.xml to use CXF Client

<!-- To use WebClient API -->
<dependency>
 <groupId>org.apache.cxf</groupId>
 <artifactId>cxf-rt-rs-client</artifactId>
 <version>3.1.2</version>
</dependency>
<!-- To parse JSON String to Java objects --> 
<dependency>
 <groupId>org.codehaus.jackson</groupId>
 <artifactId>jackson-jaxrs</artifactId>
 <version>1.9.0</version>
</dependency> 

If you dont provide JacksonJsonProvider to WebClient, You will get below error while parsing the JSON response.

 
org.apache.cxf.jaxrs.utils.JAXRSUtils logMessageHandlerProblem
SEVERE: No message body reader has been found for class com.example.cxfrs.beans.User, ContentType: application/json
Exception in thread "main" javax.ws.rs.client.ResponseProcessingException: No message body reader has been found for class org.apache.camel.example.cxfrs.beans.User, ContentType: application/json
 at org.apache.cxf.jaxrs.impl.ResponseImpl.reportMessageHandlerProblem(ResponseImpl.java:433)
 at org.apache.cxf.jaxrs.impl.ResponseImpl.doReadEntity(ResponseImpl.java:384)
 at org.apache.cxf.jaxrs.client.AbstractClient.readBody(AbstractClient.java:512)
 at org.apache.cxf.jaxrs.client.WebClient.handleResponse(WebClient.java:1173)
 at org.apache.cxf.jaxrs.client.WebClient.doResponse(WebClient.java:1156)
 at org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1092)
 at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:894)
 at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:865)
 at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:428)
 at org.apache.cxf.jaxrs.client.WebClient.get(WebClient.java:611)
 at com.example.cxfrs.CXFRestClient.main(CXFRestClient.java:21)

Recommend this on


By kswaughs | Thursday, November 19, 2015

Create REST service using Apache Camel

This post has the working example of creating a REST service using Apache camel.

1) Add below maven dependencies in your pom.xml

pom.xml
<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <camelspring.version>2.16.0</camelspring.version>
  <spring.version>3.2.10.RELEASE</spring.version>
 </properties>

 <dependencies>
  <!-- Camel Dependencies -->
  <dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-core</artifactId>
   <version>${camelspring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-cxf</artifactId>
   <version>${camelspring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.apache.camel</groupId>
   <artifactId>camel-servlet</artifactId>
   <version>${camelspring.version}</version>
  </dependency>
  <!-- End of Camel Dependencies -->

  <!-- Spring Dependencies -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context-support</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-beans</artifactId>
   <version>${spring.version}</version>
  </dependency>
  <!-- End of Spring dependencies -->

  <!-- Jackson dependencies -->
  <dependency>
   <groupId>org.codehaus.jackson</groupId>
   <artifactId>jackson-jaxrs</artifactId>
   <version>1.9.13</version>
  </dependency>
  <dependency>
   <groupId>org.codehaus.jackson</groupId>
   <artifactId>jackson-core-asl</artifactId>
   <version>1.9.13</version>
  </dependency>
 <dependencies/> 

2) Define CXFServlet and camel-context xml in your web.xml

web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 <display-name>Apache Camel CXF Rest Web Application</display-name>
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:camel-cxfrs-config.xml</param-value>
 </context-param>
  <servlet>
  <servlet-name>CXF Servlet</servlet-name>
  <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>CXF Servlet</servlet-name>
  <url-pattern>/*</url-pattern>
 </servlet-mapping>
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
</web-app> 

3) Define your camel-context xml

camel-cxfrs-config.xml
<?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:cxf="http://camel.apache.org/schema/cxf"
       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://camel.apache.org/schema/cxf
       http://camel.apache.org/schema/cxf/camel-cxf.xsd
       http://cxf.apache.org/jaxrs
       http://cxf.apache.org/schemas/jaxrs.xsd
       http://camel.apache.org/schema/spring
       http://camel.apache.org/schema/spring/camel-spring.xsd
    ">

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

 <bean id="userServiceBean" class="com.poc.rest.UserServiceImpl" />

 <cxf:rsServer id="userSvcServer" address="/"
  loggingFeatureEnabled="true">
  <cxf:serviceBeans>
   <ref bean="userServiceBean" />
  </cxf:serviceBeans>
  <cxf:providers>
   <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
  </cxf:providers>
 </cxf:rsServer>

 <camelContext id="context" xmlns="http://camel.apache.org/schema/spring">
  <route>
   <from uri="cxfrs:bean:userSvcServer" />
   <log message="Processing CXF route....http method ${header.CamelHttpMethod}" />
   <log message="Processing CXF route....path is ${header.CamelHttpPath}" />
   <log message="Processing CXF route....body is ${body}" />
   <choice>
    <when>
     <simple>${header.operationName} == 'details'</simple>
     <to uri="direct:invokeDetails" />
    </when>
    <when>
     <simple>${header.operationName} == 'add'</simple>
     <to uri="direct:invokeAdd" />
    </when>
   </choice>
  </route>

  <route id="invokeDetails">
   <from uri="direct:invokeDetails" />
   <log message="Processing invokeDetails....Start ${body}" />
   <bean ref="userServiceBean" method="details" />
   <log message="Processing invokeDetails....End is ${body}" />
  </route>
  <route id="invokeAdd">
   <from uri="direct:invokeAdd" />
   <log message="Processing invokeAdd....Start is ${body}" />
   <bean ref="userServiceBean" method="add" />
   <log message="Processing invokeAdd....End is ${body}" />
  </route>
 </camelContext>
</beans>

4) Define your REST interface

Rest Interface using Jax-RS
package com.poc.rest;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.poc.rest.beans.AddReq;

@Path("/user")
public interface UserService {

 @GET
 @Path("/details/{id}")
 @Produces(MediaType.APPLICATION_JSON)
 public Response details(@PathParam("id") String id);

 @POST
 @Path("/add")
 @Produces(MediaType.APPLICATION_JSON)
 public Response add(AddReq input);

}

5) Implementation code

UserServiceImpl.java
package com.poc.rest;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import com.poc.rest.beans.AddReq;
import com.poc.rest.beans.AddResp;
import com.poc.rest.beans.DetailsResp;

public class UserServiceImpl implements UserService {

 public Response details(String id) {
  
     System.out.println("UserServiceImpl Java details start");
  
     DetailsResp resp = new DetailsResp();
     resp.setId(id);
     resp.setName("kswaughs");
     resp.setStatus("Success");
  
     return Response.status(Status.OK).
                entity(resp).build();

 }

 public Response add(AddReq req) {
  
     System.out.println("UserServiceImpl Java add start");
  
     AddResp resp = new AddResp();
     resp.setId(req.getId());
     resp.setStatus("Success");
  
     return Response.status(Status.OK).
                entity(resp).build();
 }

}

6) Testing the service. Run the maven build and generated the war with name 'camel-rest' and deployed in Jboss 7 server.

  
 Test 1 : 
 operation : details
 method : GET
 URL : http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/details/123
 Response :
 
  {
   "status": "Success",
   "id": "12345",
   "name": "kswaughs"
  }
Test 2 :
operation : add
method : POST
URL : http://127.0.0.1:8080/camel-rest-0.0.1-SNAPSHOT/user/add
Request
{ "id" : "12345" , "name":"kswaughs" }

Response
{
   "id": "12345",
   "status": "Success"
}

Recommend this on