Spring Boot + Annotations (Web & Stereotype)
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 @Repository
annotations. 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
orPragma.
- 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.