Spring Boot + Annotations (Web & Stereotype)

Patel Romil
4 min readFeb 15, 2020

--

Spring Boot Annotations

Annotation

Annotation is a piece of information used by java interpreter and the JVM based on element type such as METHOD, PARAMETER, CONSTRUCTOR, etc. You might be familiar with build-in annotations such as @Override, @Deprecated, and @SuppressWarnings

In this series, we will create the simple Spring Boot Application and explore the commonly used annotations and will create a custom annotation. In this article, we will get familiar with Web and Stereotyp annotations. Let’s creates a new project with Spring Initializr. You can get the source code here

@SpringBootApplication

The @SpringBootApplication annotation is equivalent to using @SpringBootConfiguration, @EnableAutoConfiguration, and @ComponentScan with their default attributes.

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication { ... }
  • @EnableAutoConfiguration: enable Spring Boot’s Auto-Configuration
  • @ComponentScan: enable @Component scan on the package where the application is located (best practices)
  • @Configuration: allow registering extra beans in the context or import additional configuration classes

@Component

@Component is a parent annotation of @Controller, @RestController, @Service and @Repositoryannotations. Classes annotated with it are eligible candidates for auto-detection when using annotation-based configuration and classpath scanning.

Can we simply use @Component instead of specifying the specific annotation?

Yes, we can use @Component. But, it’s a good practice to use specific annotation according to layers as described below.

  • @Controller & @RestController represents the presentation layer of components that is responsible for managing the request, response and communicate with the services
  • @Service represents the service layer of components that is responsible to manage the business logic of the application and communicate with repositories and controllers
  • @Repository represents the persistence layer of components and responsible for managing the database operations and communicates with services

@RestControlller

This annotation is a specialized version of @Controller which adds @Controller and @ResponseBody annotation automatically. so we do not have to add @ResponseBody to our mapping methods. That means @ResponseBody is the default action.

@ResponseBody

This indicates a method return value should be serialized to the web response body with the HttpResponse object for the controller.

@Controller
public class UserController {
/** @Controller & @RestController

Removing @ResponseBody from methods findAll will results in
404 Not Found "path": "/users/list"

Is @ResponseBody really mandatory?
-> Use @RestController which is combination of @Controller and @ResponseBody
-> We can use ResponseEntity to resolve 404 Not Found without using @ResponseBody, @RestController

**/
@GetMapping(value = "/list")
public @ResponseBody List<User> findAll() {
List<User> users = userService.findAll();
return users;
}

@GetMapping(value = "/list/error")
public List<User> findAllWithError() {
List<User> users = userService.findAll();
return users;
}
@GetMapping(value = "/response-entity/list")
public ResponseEntity<List<User>> findAllWithResponseEntity() {
List<User> users = userService.findAll();
return new ResponseEntity<>(users, HttpStatus.OK);
}

@RequestMapping

This annotation maps the web requests with the methods specified in the controllers. It can be used at both, class level and method level. @GetMapping, @PostMapping, @PutMapping, @DeleteMapping are the alias or shortcut of the @RequestMapping and used at the method level.

@RequestMapping(value = "/list", method = RequestMethod.GET) is equivalent to @GetMapping(value = "/list". We can also specify the parameters such as headers, consumes, produces as follow.

@PostMapping(value = "/save", 
consumes = "application/json", produces = "application/json")

@RequestParam

This annotation indicates a request parameter is bounded with the web request. This extract query parameter from the web request. We can specify the name, value, default-value and required parameters with it.

  • name & value: Parameters name and value are the alias of each other and functional working is the same for both. When you specify both of them make sure value is same for both name and value parameter else it will result in an error.
  • default-value: We may want to specify the default value for the parameter if the user doesn’t provide the value.
  • required: Whether the parameter is mandatory or optional to be specify
@RequestParam(value = "contact") //Works fine
@RequestParam(name= "contact") //Works fine
@RequestParam(value = "contact", name = "contact") //Works fine
//Error attribute 'name' and its alias 'value' are declared with values of [abc] and [contact]
@RequestParam(value = "contact", name = "abc")

@PathVariable

It extracts the value from the URI. We can specify the name, value and required parameters with it.

@GetMapping(value = "/user/{id}")
public Optional<User> findUserById(@PathVariable Long id) {
Optional<User> user = userService.findById(id);
return user;
}

@CrossOrigin

This annotation is used for the cross-origin HTTP request is a request to a specific resource, which is located at a different origin, namely a domain, protocol, and port, then one of the clients performing the request. This can be used at both the class level and method level. However, I suggest creating a common configuration for the application using CorsConfigurationSource.

  • origins: The list of allowed origins that be specific origins, e.g. "https://domain1.com", or "*" for all origins. By default, all origins are allowed.
  • allowedHeaders: The list of request headers that are permitted in actual requests, possibly "*" to allow all headers.
  • exposedHeaders: The List of response headers that the user-agent will allow the client to access on an actual response, other than “simple” headers, i.e. Cache-Control, Content-Language, Content-Type, Expires, Last-Modified or Pragma.
  • methods: The list of supported HTTP request methods.
  • maxAge: The maximum age (in seconds) of the cache duration for preflight responses.

I have listed the other annotations in the images below. In the next article, we will implement the Soft Delete functionality using @SQLDelete, @Where, @Filter and @FilterDef. You can download the source code from here.

Web Annotations

Web Annotations: org.springframework.web.bind.annotation

Stereotype Annotations

Stereotype Annotations: org.springframework.stereotype

--

--