docs
Annotations for declaring web controllers and mapping HTTP requests to handler methods in Spring MVC.
Marks a class as a Spring MVC controller capable of handling web requests.
/**
* Indicates that an annotated class is a "Controller" (e.g. a web controller).
*
* This annotation serves as a specialization of @Component, allowing for
* implementation classes to be autodetected through classpath scanning.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
*/
@AliasFor(annotation = Component.class)
String value() default "";
}Usage Example:
@Controller
public class HomeController {
@GetMapping("/")
public String home(Model model) {
model.addAttribute("message", "Welcome");
return "home"; // Returns view name
}
}Convenience annotation that combines @Controller and @ResponseBody, indicating that all handler methods return response bodies rather than view names.
/**
* A convenience annotation that is itself annotated with @Controller and @ResponseBody.
*
* Types that carry this annotation are treated as controllers where @RequestMapping
* methods assume @ResponseBody semantics by default.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
/**
* The value may indicate a suggestion for a logical component name.
*/
@AliasFor(annotation = Controller.class)
String value() default "";
}Usage Example:
@RestController
@RequestMapping("/api/products")
public class ProductController {
@GetMapping
public List<Product> getProducts() {
return productService.findAll(); // Automatically serialized to JSON
}
@GetMapping("/{id}")
public Product getProduct(@PathVariable Long id) {
return productService.findById(id);
}
}Maps HTTP requests to handler classes and methods with flexible configuration of URL patterns, HTTP methods, request parameters, headers, and content types.
/**
* Annotation for mapping web requests onto methods in request-handling classes
* with flexible method signature.
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
/**
* Alias for {@link #path}.
*/
@AliasFor("path")
String[] value() default {};
/**
* The path mapping URIs (e.g. {@code "/profile"}).
* Ant-style path patterns are also supported (e.g. {@code "/profile/**"}).
* At the method level, relative paths (e.g. {@code "edit"}) are supported
* within the primary mapping expressed at the type level.
*/
@AliasFor("value")
String[] path() default {};
/**
* The HTTP request methods to map to, narrowing the primary mapping:
* GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE.
*/
RequestMethod[] method() default {};
/**
* The parameters of the mapped request, narrowing the primary mapping.
* Same format for any environment: a sequence of "myParam=myValue" style
* expressions, with a request only mapped if each such parameter is found
* to have the given value. Expressions can be negated by using the "!=" operator.
*/
String[] params() default {};
/**
* The headers of the mapped request, narrowing the primary mapping.
* Same format for any environment: a sequence of "My-Header=myValue" style
* expressions, with a request only mapped if each such header is found
* to have the given value. Expressions can be negated by using the "!=" operator.
*/
String[] headers() default {};
/**
* Narrows the primary mapping by media types that can be consumed by the
* mapped handler. Consists of one or more media types one of which must
* match to the request Content-Type header.
* Examples: "text/plain", "!text/plain" (negation), "application/json"
*/
String[] consumes() default {};
/**
* Narrows the primary mapping by media types that can be produced by the
* mapped handler. Consists of one or more media types one of which must
* be acceptable according to the request "Accept" header.
* Examples: "text/plain", "application/json"
*/
String[] produces() default {};
/**
* Assign a name to this mapping.
*/
String name() default "";
}Usage Examples:
// Class-level mapping
@Controller
@RequestMapping("/api/orders")
public class OrderController {
// GET /api/orders
@RequestMapping(method = RequestMethod.GET)
public List<Order> getOrders() {
return orderService.findAll();
}
// POST /api/orders with JSON content type
@RequestMapping(
method = RequestMethod.POST,
consumes = "application/json",
produces = "application/json"
)
public Order createOrder(@RequestBody Order order) {
return orderService.save(order);
}
// GET /api/orders/search?status=PENDING
@RequestMapping(
path = "/search",
method = RequestMethod.GET,
params = "status"
)
public List<Order> searchOrders(@RequestParam String status) {
return orderService.findByStatus(status);
}
// Only handles requests with specific header
@RequestMapping(
path = "/admin",
method = RequestMethod.GET,
headers = "X-Admin-Token"
)
public List<Order> adminOrders(@RequestHeader("X-Admin-Token") String token) {
return orderService.findAll();
}
}Specialized @RequestMapping for HTTP GET requests.
/**
* Annotation for mapping HTTP GET requests onto specific handler methods.
* Specifically, @GetMapping is a composed annotation that acts as a
* shortcut for @RequestMapping(method = RequestMethod.GET).
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping {
@AliasFor(annotation = RequestMapping.class)
String[] value() default {};
@AliasFor(annotation = RequestMapping.class)
String[] path() default {};
@AliasFor(annotation = RequestMapping.class)
String[] params() default {};
@AliasFor(annotation = RequestMapping.class)
String[] headers() default {};
@AliasFor(annotation = RequestMapping.class)
String[] consumes() default {};
@AliasFor(annotation = RequestMapping.class)
String[] produces() default {};
@AliasFor(annotation = RequestMapping.class)
String name() default "";
}Usage Example:
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping
public List<User> getAllUsers() {
return userService.findAll();
}
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
@GetMapping(path = "/search", params = "email")
public User findByEmail(@RequestParam String email) {
return userService.findByEmail(email);
}
}Specialized @RequestMapping for HTTP POST requests.
/**
* Annotation for mapping HTTP POST requests onto specific handler methods.
* Specifically, @PostMapping is a composed annotation that acts as a
* shortcut for @RequestMapping(method = RequestMethod.POST).
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.POST)
public @interface PostMapping {
@AliasFor(annotation = RequestMapping.class)
String[] value() default {};
@AliasFor(annotation = RequestMapping.class)
String[] path() default {};
@AliasFor(annotation = RequestMapping.class)
String[] params() default {};
@AliasFor(annotation = RequestMapping.class)
String[] headers() default {};
@AliasFor(annotation = RequestMapping.class)
String[] consumes() default {};
@AliasFor(annotation = RequestMapping.class)
String[] produces() default {};
@AliasFor(annotation = RequestMapping.class)
String name() default "";
}Usage Example:
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public ResponseEntity<User> createUser(@RequestBody @Valid User user) {
User created = userService.save(user);
URI location = ServletUriComponentsBuilder
.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(created.getId())
.toUri();
return ResponseEntity.created(location).body(created);
}
@PostMapping(path = "/batch", consumes = "application/json")
public List<User> createUsers(@RequestBody List<User> users) {
return userService.saveAll(users);
}
}Specialized @RequestMapping for HTTP PUT requests.
/**
* Annotation for mapping HTTP PUT requests onto specific handler methods.
* Specifically, @PutMapping is a composed annotation that acts as a
* shortcut for @RequestMapping(method = RequestMethod.PUT).
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.PUT)
public @interface PutMapping {
@AliasFor(annotation = RequestMapping.class)
String[] value() default {};
@AliasFor(annotation = RequestMapping.class)
String[] path() default {};
@AliasFor(annotation = RequestMapping.class)
String[] params() default {};
@AliasFor(annotation = RequestMapping.class)
String[] headers() default {};
@AliasFor(annotation = RequestMapping.class)
String[] consumes() default {};
@AliasFor(annotation = RequestMapping.class)
String[] produces() default {};
@AliasFor(annotation = RequestMapping.class)
String name() default "";
}Usage Example:
@RestController
@RequestMapping("/api/users")
public class UserController {
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(
@PathVariable Long id,
@RequestBody @Valid User user) {
User updated = userService.update(id, user);
return ResponseEntity.ok(updated);
}
}Specialized @RequestMapping for HTTP PATCH requests.
/**
* Annotation for mapping HTTP PATCH requests onto specific handler methods.
* Specifically, @PatchMapping is a composed annotation that acts as a
* shortcut for @RequestMapping(method = RequestMethod.PATCH).
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.PATCH)
public @interface PatchMapping {
@AliasFor(annotation = RequestMapping.class)
String[] value() default {};
@AliasFor(annotation = RequestMapping.class)
String[] path() default {};
@AliasFor(annotation = RequestMapping.class)
String[] params() default {};
@AliasFor(annotation = RequestMapping.class)
String[] headers() default {};
@AliasFor(annotation = RequestMapping.class)
String[] consumes() default {};
@AliasFor(annotation = RequestMapping.class)
String[] produces() default {};
@AliasFor(annotation = RequestMapping.class)
String name() default "";
}Usage Example:
@RestController
@RequestMapping("/api/users")
public class UserController {
@PatchMapping("/{id}")
public ResponseEntity<User> partialUpdateUser(
@PathVariable Long id,
@RequestBody Map<String, Object> updates) {
User updated = userService.partialUpdate(id, updates);
return ResponseEntity.ok(updated);
}
@PatchMapping("/{id}/status")
public ResponseEntity<Void> updateStatus(
@PathVariable Long id,
@RequestParam String status) {
userService.updateStatus(id, status);
return ResponseEntity.noContent().build();
}
}Specialized @RequestMapping for HTTP DELETE requests.
/**
* Annotation for mapping HTTP DELETE requests onto specific handler methods.
* Specifically, @DeleteMapping is a composed annotation that acts as a
* shortcut for @RequestMapping(method = RequestMethod.DELETE).
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.DELETE)
public @interface DeleteMapping {
@AliasFor(annotation = RequestMapping.class)
String[] value() default {};
@AliasFor(annotation = RequestMapping.class)
String[] path() default {};
@AliasFor(annotation = RequestMapping.class)
String[] params() default {};
@AliasFor(annotation = RequestMapping.class)
String[] headers() default {};
@AliasFor(annotation = RequestMapping.class)
String[] consumes() default {};
@AliasFor(annotation = RequestMapping.class)
String[] produces() default {};
@AliasFor(annotation = RequestMapping.class)
String name() default "";
}Usage Example:
@RestController
@RequestMapping("/api/users")
public class UserController {
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
// Soft delete with query parameter
@DeleteMapping(path = "/{id}", params = "soft=true")
public ResponseEntity<Void> softDeleteUser(@PathVariable Long id) {
userService.softDelete(id);
return ResponseEntity.noContent().build();
}
}Indicates that the return value of a method should be bound to the response body, serialized using message converters.
/**
* Annotation that indicates a method return value should be bound to the
* web response body. Supported for annotated handler methods.
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}Usage Example:
@Controller
@RequestMapping("/api/data")
public class DataController {
// Returns JSON instead of view name
@GetMapping("/json")
@ResponseBody
public Map<String, Object> getJsonData() {
Map<String, Object> data = new HashMap<>();
data.put("status", "success");
data.put("timestamp", System.currentTimeMillis());
return data;
}
// Returns view name (no @ResponseBody)
@GetMapping("/page")
public String getPage(Model model) {
model.addAttribute("data", "some data");
return "dataPage";
}
}Marks a method or exception class with a status code and reason that should be returned.
/**
* Marks a method or exception class with the status code and reason that
* should be returned. The status code is applied to the HTTP response when
* the handler method is invoked and overrides status information set by
* other means, like ResponseEntity or "redirect:".
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseStatus {
/**
* Alias for {@link #code}.
*/
@AliasFor("code")
HttpStatus value() default HttpStatus.INTERNAL_SERVER_ERROR;
/**
* The status code to use for the response.
*/
@AliasFor("value")
HttpStatus code() default HttpStatus.INTERNAL_SERVER_ERROR;
/**
* The reason to be used for the response.
*/
String reason() default "";
}Usage Examples:
@RestController
@RequestMapping("/api/resources")
public class ResourceController {
// Returns 201 Created
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Resource createResource(@RequestBody Resource resource) {
return resourceService.save(resource);
}
// Returns 204 No Content
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteResource(@PathVariable Long id) {
resourceService.delete(id);
}
}
// Exception with status code
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Resource not found")
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}Enumeration of HTTP request methods.
public enum RequestMethod {
GET,
HEAD,
POST,
PUT,
PATCH,
DELETE,
OPTIONS,
TRACE
}Enumeration of HTTP status codes (from Spring Framework's http module).
public enum HttpStatus {
// 2xx Success
OK(200, "OK"),
CREATED(201, "Created"),
ACCEPTED(202, "Accepted"),
NO_CONTENT(204, "No Content"),
// 3xx Redirection
MOVED_PERMANENTLY(301, "Moved Permanently"),
FOUND(302, "Found"),
SEE_OTHER(303, "See Other"),
NOT_MODIFIED(304, "Not Modified"),
TEMPORARY_REDIRECT(307, "Temporary Redirect"),
PERMANENT_REDIRECT(308, "Permanent Redirect"),
// 4xx Client Error
BAD_REQUEST(400, "Bad Request"),
UNAUTHORIZED(401, "Unauthorized"),
FORBIDDEN(403, "Forbidden"),
NOT_FOUND(404, "Not Found"),
METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
CONFLICT(409, "Conflict"),
UNPROCESSABLE_ENTITY(422, "Unprocessable Entity"),
// 5xx Server Error
INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
NOT_IMPLEMENTED(501, "Not Implemented"),
BAD_GATEWAY(502, "Bad Gateway"),
SERVICE_UNAVAILABLE(503, "Service Unavailable"),
GATEWAY_TIMEOUT(504, "Gateway Timeout");
public int value();
public String getReasonPhrase();
public boolean is1xxInformational();
public boolean is2xxSuccessful();
public boolean is3xxRedirection();
public boolean is4xxClientError();
public boolean is5xxServerError();
}