REST best example with Spring Boot

Posted by Bhamidi Venu

Spring Boot includes a number of additional features to help you monitor and manage your application when it's pushed to production. You can choose to manage and monitor your application using HTTP endpoints, with JMX or even by remote shell (SSH or Telnet). Auditing, health and metrics gathering can be automatically applied to your application..
Spring Boot Actuator is a sub-project of Spring Boot. It adds several production grade services to your application with little effort on your part. In this guide, you'll build an application and then see how to add these services.
Create a representation class
package hello;

public class Greeting {

    private final long id;
    private final String content;
    private final String title;
    
    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
        this.title = "default-title";
    }
    
    public Greeting(long id, String content, String title) {
        this.id = id;
        this.content = content;
        this.title = title;
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }
    
    public String getTitle(){
    	return title;
    }
}
Create a resource controller
In Spring, REST endpoints are just Spring MVC controllers. The following Spring MVC controller handles a GET request for different urls, just follow the comments which provides each method and try to access url as per that after executing Application.java.
package hello;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.atomic.AtomicLong;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    /**
     * Simple method to show how REST works!
     * Sample Request - /greeting?name=John
     * 
     * @param name - parameter name with default value = Robin
     * @return Greeting object - json default.
     */
    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value="name", defaultValue="Robin")String name) {
        return new Greeting(counter.incrementAndGet(),
                            String.format(template, name));
    }
        
    /**
     * Lists the optional vs mandatory parameter 
     *  Sample Request - /foo?second=dog
     * @param first - optional
     * @param second - mandatory
     * @return - concatenated string with both the param values
     *
     */
    @RequestMapping("/foo")
    public String foo(@RequestParam(required=false) final String first, @RequestParam String second)
    {
    	return "second: "+second +" first: "+ (first==null? "null":first);
    }
    
    /**
     * Lets user specify the return type as json...
     * Sample Request - /greeting/1.json
     * Parse the path variable
     * @param id - Path variable
     * @return - response object as json    
     */
    @RequestMapping(value="/greeting/{id}.json", method=RequestMethod.GET, produces="application/json")
    @ResponseBody
    public Greeting getDetailsAsJson(@PathVariable Long id)
    {
        return new Greeting(counter.incrementAndGet(),
                String.format(template, id));
    }
        
    /**
     * Lets user specify the return type as xml
     * Sample  request /greeting/1.xml
     * Parse the path variable
     * @param id - Path variable
     * @return - response object as xml
     * Need to make changes as explained in any one the links.
     *    
     */
    @RequestMapping(value="/greeting/{id}.xml", method=RequestMethod.GET, produces="application/xml")
    @ResponseBody
    public Greeting getDetailsAsXml(@PathVariable Long id)
    {
        return new Greeting(counter.incrementAndGet(),
                String.format(template, id));
    }
     
    /**
    * Responds to the client with partial information as requested and not the complete object.
    * Example, Greeting object has three fields, but client wants to display id and title only, they
    * can pass the request as /greeting/test/1?fields=id,title
    * @param userId
    * @param fields
    * @return
    */
    @RequestMapping(value="greeting/test/{userId}", method=RequestMethod.GET, produces="application/json")
    public String getUser(@PathVariable("userId") Long userId, @RequestParam(defaultValue="id") String fields ){
    	   
    	Greeting greeting = new Greeting(1, "content", "title");
    	StringTokenizer st = new StringTokenizer(fields, ",");
    	Set<String> filterProps = new HashSet<String>();
    	while(st.hasMoreTokens())
    	{
    		filterProps.add(st.nextToken());
    	}
    	
    	ObjectMapper mapper = new ObjectMapper();
    	FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", 
		                      SimpleBeanPropertyFilter.filterOutAllExcept(filterProps));
    	
    	try
    	{
    		String json = mapper.writer(filters).writeValueAsString(greeting);
    		return json;
    	}
    	catch(IOException are)
    	{
    		are.printStackTrace();
    		return are.getMessage();
    	}    	
    }
}
Create an executable main class
You can launch the application from a custom main class, or we can do that directly from one of the configuration classes.

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Switch to a different server port
Spring Boot Actuator defaults to run on port 8080. By adding an application.properties file, you can override that setting.
src/main/resources/application.properties
server.port: 9000
management.port: 9001
management.address: 127.0.0.1
Execute and enjoy the results.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javavillage.common</groupId>
	<artifactId>SpringBoot</artifactId>
	<packaging>war</packaging>
	<version>1.0-SNAPSHOT</version>
	<name>SpringBoot Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.2.3.RELEASE</version>
	</parent>

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

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

</project>


Project workspace Structure

Spring Boot Project workspace Structure

Execute Application.java by Run As-> Java Application in eclipse
console will be

Spring Boot Console

Sample url for execution

Spring Boot execution