Spring Boot - Web Application

Let’s learn basic web application using Spring Boot.

Maven

You need to add spring-boot-starter-web dependencies in order to develop web application.

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-devtools module provides automatic restart and live reload. It will help reduce a lot of development time.

1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>

Rest Controller Annotations

Annotations used for Spring MVC are used in Spring Boot too. Here are the common annotations:

  • @RestController - @Controller + @ResponseBody
  • @ResponseBody - indicates that the result type should be written straight in the response body in whatever format you specify like JSON or XML.
  • @RequestMapping - This annotation is used at both the class and method level. The @RequestMapping annotation is used to map web requests onto specific handler classes and handler methods.
  • @PostMapping - shortcut for @RequestMapping(method = RequestMethod.POST). There is also @GetMapping, @PutMapping, @DeleteMapping
  • @RequestParam - get the parameters in the request URL
  • @RequestBody - method parameter should be bound to the value of the HTTP request body.
  • @PathVariable - used to handle dynamic changes in the URI where a certain URI value acts as a parameter.

The sample application demos most of the commonly used annotations in a Spring Boot web application

Greeting.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Data
public class Greeting {
private static final AtomicLong counter = new AtomicLong(0);
private long id;
private final String content;

public Greeting() {
super();
this.id = counter.incrementAndGet();
content = StringUtils.EMPTY;
}

public Greeting(String content) {
super();
this.id = counter.incrementAndGet();
this.content = content;
}
}

MyController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
@RestController
@RequestMapping("/greeting")
public class MyController {
// simple GET
// GET localhost:8080/greeting/hello
@RequestMapping(value = "/hello",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)

public ResponseEntity<Greeting> hello() {
return ResponseEntity.status(HttpStatus.OK).body(new Greeting("Hello"));
}


// GET with query parameter
// GET localhost:8080/greeting/sayHello?firstname=world
@RequestMapping(value = "/sayHello",
params = "firstName",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Greeting> sayHello(
@RequestParam(value = "firstName") String firstName) {
return ResponseEntity.status(HttpStatus.OK).body(new Greeting(firstName));
}

// GET with path parameter
// GET localhost:8080/greeting/sayHelloPath/{name}
@RequestMapping(value = "/sayHelloPath/{name}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Greeting> sayHelloPath(@PathVariable(value = "name") String name) {
return ResponseEntity.status(HttpStatus.OK).body(new Greeting(name));
}

// GET with query parameters as Map
// GET localhost:8080/greeting/sayHelloToAll?test1=1&test2&test3
@RequestMapping(value = "/sayHelloToAll",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Greeting>> sayHelloToAll(@RequestParam Map<String, String> names) {
List<Greeting> greetings = new ArrayList<Greeting>();
names.keySet().forEach(key -> {
greetings.add(new Greeting(key));
});
return ResponseEntity.status(HttpStatus.OK).body(greetings);
}

// POST localhost:8080/greeting/postGreeting
// @RequestMapping(value = "/postGreeting", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@PostMapping(value = "/postGreeting",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Greeting> postGreeting(@RequestBody Greeting greeting) {
if( StringUtils.isBlank(greeting.getContent())) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); // use build() to create responseEntity without body
}
return ResponseEntity.status(HttpStatus.OK).body(greeting);
}

// return empty body(response entity is void
// http://localhost:8080/greeting/returnvoid
@RequestMapping(value = "/returnempty",
method = RequestMethod.GET)
public ResponseEntity<Void> returnempty() {
return ResponseEntity.status(HttpStatus.OK).build();
}
}

To see a complete Spring Boot Crud Web application, see https://howtodoinjava.com/spring-boot2/spring-boot-crud-hibernate/

Set Port Number

You can set port number using properties configuration

1
server.port=8000

or pass port number setting as command line argument

1
java -jar app.jar --server.port=8000

Set Context Path

You can set context path using properties configuration

1
server.servlet.context-path=/myapp

Jetty and Undertow Embedded Server

To use Jetty embedded server, you need to exclude tomcat dependency and add jetty

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

For undertow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

For performance comparison between embedded servlet containers Tomcat, Jetty and Undertow, see https://examples.javacodegeeks.com/enterprise-java/spring/tomcat-vs-jetty-vs-undertow-comparison-of-spring-boot-embedded-servlet-containers/

Reference

Sourcecode - SpringBootExamples - web-application