SpringMVC常用注解
控制器(Controller)相关注解:
1.@Controller
@Controller
注解用于标识一个类为 Spring MVC 的控制器,它能够处理用户的请求并返回相应的视图或数据。通常与@RequestMapping
注解一起使用,以定义请求的处理方法和映射路径。
2.@RestController
@RestController
是 Spring MVC 中的一个注解,结合了@Controller
和@ResponseBody
的功能,用于定义 RESTful 风格的控制器。它通常用于返回 JSON 或 XML 格式的数据,而不是直接渲染视图。@Controller
负责接收请求并将其分发到相应的处理方法,而@ResponseBody
负责将处理方法的返回值转换为指定格式的响应数据。
1.使用示例
@RestController
public class HelloRestController {
@GetMapping("/hello")
public String hello() {
return "Hello, welcome to RESTful Controller!";
}
}
@RestController
标注了 HelloController
类,使其成为一个 RESTful 风格的控制器。方法返回的字符串会直接作为 HTTP 响应体的内容返回给客户端,而不会被视图解析器处理。
2.响应格式
@ResponseBody
通常用于返回复杂对象或集合,Spring MVC 会自动将其转换为 JSON 或 XML 格式的响应数据。示例:
@RestController
public class UserController {
@GetMapping("/users")
public List<User> getUsers() {
List<User> users = new ArrayList<>();
users.add(new User(1, "Alice"));
users.add(new User(2, "Bob"));
return users;
}
static class User {
private int id;
private String name;
// Constructor, getters and setters
// 省略构造函数、getter和setter方法
}
}
在这个示例中,UserController
返回了一个包含用户信息的列表,Spring MVC 会自动将其转换为 JSON 格式的响应数据。
请求映射相关注解
1.@RequestMapping
@RequestMapping
是 Spring MVC 中用于映射 HTTP 请求到具体处理方法的注解。它可以用在类级别或方法级别,用来指定请求的 URL 路径、HTTP 方法以及其他请求条件。
使用方式:
1.类级别的@RequestMapping:
在类级别使用 @RequestMapping
可以定义处理器类的根请求映射。例如:
@RestController
@RequestMapping("/api")
public class ApiController {
}
上面的例子中,@RestController
声明了这是一个 REST 控制器,而 @RequestMapping("/api")
则指定了这个控制器处理的根路径为 /api
。
2.方法级别的@RequestMapping:
在方法级别使用 @RequestMapping
可以进一步定义具体请求路径和请求方法。例如:
@RestController
@RequestMapping("/api")
public class ApiController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String helloGet() {
return "Hello GET!";
}
@RequestMapping(value = "/hello", method = RequestMethod.POST)
public String helloPost() {
return "Hello POST!";
}
}
上面的例子中,helloGet()
方法处理 /api/hello
的 GET 请求,而 helloPost()
方法处理同样路径的 POST 请求。通过 value
属性指定路径,通过 method
属性指定 HTTP 方法。
2.@GetMapping @PostMapping @PutMapping@DeleteMapping
当使用Spring MVC构建Web应用程序时,可以使用以下注解来处理不同类型的HTTP请求:
@GetMapping
、@PostMapping
、@PutMapping
和@DeleteMapping
。这些注解分别对应HTTP方法GET、POST、PUT和DELETE,并使得编写和阅读控制器方法更加直观和语义化。
在实际开发中,选择合适的HTTP方法注解(如
@GetMapping
、@PostMapping
、@PutMapping
、@DeleteMapping
)取决于你的业务需求和RESTful API设计原则。
GET请求 (
@GetMapping
):
- 用途: 用于从服务器获取资源或数据。
- 示例: 获取资源列表、获取单个资源的详情。
- 特点: GET请求应该是幂等的,即重复调用多次不会造成状态变更或副作用。
POST请求 (
@PostMapping
):
- 用途: 用于在服务器上创建新资源。
- 示例: 创建新的资源、提交表单数据。
- 特点: POST请求可能会引起服务器状态的变更,每次提交可能产生不同的结果。
PUT请求 (
@PutMapping
):
- 用途: 用于更新服务器上的资源。
- 示例: 更新已有资源的信息、全量更新资源。
- 特点: PUT请求应该是幂等的,即多次提交相同的数据不会产生不同的结果,通常用于完全替换资源。
DELETE请求 (
@DeleteMapping
):
- 用途: 用于删除服务器上的资源。
- 示例: 删除指定的资源、清理不需要的数据。
- 特点: DELETE请求应该是幂等的,即多次删除同一个资源应该具有相同的结果。
选择合适的方法注解时,需要考虑以下几点:
- RESTful API设计原则: 遵循RESTful API的设计规范,合理使用GET、POST、PUT、DELETE方法来对资源进行操作。
- 幂等性: GET和DELETE请求本身就是幂等的,而POST和PUT请求需要设计成幂等操作,以确保多次操作不会导致意外的副作用。
- 安全性: 敏感操作如删除资源通常使用DELETE请求,而不是GET请求,以防止意外操作。
- 请求体: POST和PUT请求通常需要请求体(
@RequestBody
),用于传递参数和数据。
@RestController
@RequestMapping("/api/products")
public class ProductController {
// GET请求示例:获取所有产品列表
@GetMapping("/list")
public ResponseEntity<List<Product>> listProducts() {
List<Product> productList = productService.getAllProducts();
return ResponseEntity.ok(productList);
}
// GET请求示例:根据ID获取产品详情
@GetMapping("/{id}")
public ResponseEntity<Product> getProductById(@PathVariable Long id) {
Product product = productService.getProductById(id);
if (product != null) {
return ResponseEntity.ok(product);
} else {
return ResponseEntity.notFound().build();
}
}
// POST请求示例:创建新产品
@PostMapping("/create")
public ResponseEntity<String> createProduct(@RequestBody Product product) {
productService.createProduct(product);
return ResponseEntity.ok("Product created successfully");
}
// PUT请求示例:更新产品信息
@PutMapping("/update/{id}")
public ResponseEntity<String> updateProduct(@PathVariable Long id, @RequestBody Product updatedProduct) {
boolean updated = productService.updateProduct(id, updatedProduct);
if (updated) {
return ResponseEntity.ok("Product updated successfully");
} else {
return ResponseEntity.notFound().build();
}
}
// DELETE请求示例:删除产品
@DeleteMapping("/delete/{id}")
public ResponseEntity<String> deleteProduct(@PathVariable Long id) {
boolean deleted = productService.deleteProduct(id);
if (deleted) {
return ResponseEntity.ok("Product deleted successfully");
} else {
return ResponseEntity.notFound().build();
}
}
// 业务逻辑可以替换为真实的服务方法实现
private ProductService productService;
public ProductController(ProductService productService) {
this.productService = productService;
}
}
参数处理注解:
1.@RequestParam
在Web开发中,
@RequestParam
注解用于从HTTP请求中获取请求参数的值。具体来说,它可以用来获取URL查询参数或表单提交的参数值。
使用方式:
1.基本用法:
@GetMapping("/example")
public ResponseEntity<String> handleRequest(@RequestParam("date") String date) {
// 处理逻辑,使用从请求中获取的 date 参数值
return ResponseEntity.ok("Received date parameter: " + date);
}
> @RequestParam("date")
表示从请求中获取名为 "date" 的参数的值,并将其赋给方法中的 date
参数。
2.可选参数:
@GetMapping("/example")
public ResponseEntity<String> handleRequest(@RequestParam(value = "date", required = false) String date) {
if (date != null) {
// 处理逻辑,使用从请求中获取的 date 参数值
return ResponseEntity.ok("Received date parameter: " + date);
} else {
return ResponseEntity.badRequest().body("Date parameter is required");
}
}
> 在这个例子中,通过设置 required = false
,使得 date
参数变为可选的。如果请求中没有提供 date
参数,方法可以根据需要处理这种情况。
3.默认值:
@GetMapping("/example")
public ResponseEntity<String> handleRequest(@RequestParam(value = "date", defaultValue = "20240101") String date) {
// 处理逻辑,使用从请求中获取的 date 参数值;如果请求中没有提供该参数,则使用默认值 "20240627"
return ResponseEntity.ok("Received date parameter: " + date);
}
> 在这个例子中,通过 defaultValue = "20240627"
设置了一个默认值,如果请求中没有提供 date
参数,将使用默认值。
4.多个参数:
@GetMapping("/example")
public ResponseEntity<String> handleRequest(
@RequestParam("date") String date,
@RequestParam("type") String type) {
// 处理逻辑,使用从请求中获取的 date 和 type 参数值
return ResponseEntity.ok("Received date parameter: " + date + ", type parameter: " + type);
}
> 这个例子展示了如何同时获取多个参数值,每个 @RequestParam
对应请求中的一个参数。
2.@PathVariable
用于从URI模板中提取变量值并将其绑定到处理方法的参数中。
1.用法
@PathVariable 可以用于方法参数,表示方法参数的值来自于请求URI中的某个部分。
可以指定参数名称,也可以省略,默认情况下会自动匹配同名参数。
可以通过
required
属性来指定该参数是否为必需。
2.示例
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable("id") Long userId) {
// 根据用户ID获取用户信息的逻辑
User user = userService.findById(userId);
return ResponseEntity.ok(user);
}
}
在这个例子中,@PathVariable("id")
将URL路径中的id
部分提取出来并赋值给userId
参数,例如,/users/123
会将123
作为userId
的值。
3.默认参数名称
@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping("/{productId}")
public ResponseEntity<Product> getProductById(@PathVariable Long productId) {
// 根据产品ID获取产品信息的逻辑
Product product = productService.findById(productId);
return ResponseEntity.ok(product);
}
}
在这个例子中,@PathVariable
注解中没有指定参数名称,Spring会自动匹配路径变量和方法参数名称,{productId}
会被绑定到 productId
参数上。
4.多个 @PathVariable
@RestController
@RequestMapping("/orders")
public class OrderController {
@GetMapping("/{orderId}/items/{itemId}")
public ResponseEntity<Item> getOrderItem(@PathVariable("orderId") Long orderId,
@PathVariable("itemId") Long itemId) {
// 根据订单ID和项目ID获取项目信息的逻辑
Item item = orderService.findItemByOrderIdAndItemId(orderId, itemId);
return ResponseEntity.ok(item);
}
}
在这个例子中,有两个@PathVariable
注解,它们从URI路径中提取orderId
和itemId
,例如,/orders/123/items/456
会将 123
作为 orderId
的值,将 456
作为 itemId
的值。
5.可选参数
默认情况下,@PathVariable
是必需的。如果路径变量是可选的,可以使用 required
属性:
@RestController
@RequestMapping("/files")
public class FileController {
@GetMapping("/{directory}/{filename}")
public ResponseEntity<String> getFile(
@PathVariable("directory") String directory,
@PathVariable(value = "filename", required = false) String filename) {
// 处理逻辑
if (filename != null) {
return ResponseEntity.ok("Received file: " + directory + "/" + filename);
} else {
return ResponseEntity.ok("Received directory: " + directory);
}
}
}
在这个例子中,filename
是一个可选参数,若未提供filename
路径变量,则该参数值为null
。
3.@RequestBody
@RequestBody 是Spring MVC中的一个注解,用于将HTTP请求体中的内容绑定到方法的参数上。它通常用于处理POST、PUT等请求方法,以便从请求体中获取JSON、XML或其他格式的数据,并将其转换为Java对象。
用法
- @RequestBody 注解用于告诉Spring MVC,将请求体的内容转换为方法参数所需的对象。
- Spring MVC使用
HttpMessageConverter
进行数据转换,例如,使用MappingJackson2HttpMessageConverter
来处理JSON数据。- 适用于POST、PUT、DELETE等请求方法。
1.基本用法:
@RestController
@RequestMapping("/users")
public class UserController {
@PostMapping("/create")
public ResponseEntity<User> createUser(@RequestBody User user) {
// 处理逻辑,保存用户信息
userService.save(user);
return ResponseEntity.ok(user);
}
}
在这个例子中,@RequestBody
注解将请求体中的JSON数据转换为User
对象,并传递给createUser
方法。
2.接受复杂对象:
@RestController
@RequestMapping("/orders")
public class OrderController {
@PostMapping("/submit")
public ResponseEntity<Order> submitOrder(@RequestBody Order order) {
// 处理逻辑,保存订单信息
orderService.save(order);
return ResponseEntity.ok(order);
}
}
在这个例子中,@RequestBody
注解将请求体中的JSON数据转换为Order
对象。请求体可能包含嵌套的对象,如订单项(OrderItem)等,Spring会自动处理这些复杂对象的转换。
3.处理XML数据
如果请求体包含XML数据,可以通过配置HttpMessageConverter
来处理:
@RestController
@RequestMapping("/products")
public class ProductController {
@PostMapping("/add")
public ResponseEntity<Product> addProduct(@RequestBody Product product) {
// 处理逻辑,保存产品信息
productService.save(product);
return ResponseEntity.ok(product);
}
}
在这个例子中,假设配置了适当的HttpMessageConverter
(如MappingJackson2XmlHttpMessageConverter
),Spring会将请求体中的XML数据转换为Product
对象。
4.结合验证注解
import javax.validation.Valid;
@RestController
@RequestMapping("/customers")
public class CustomerController {
@PostMapping("/register")
public ResponseEntity<Customer> registerCustomer(@Valid @RequestBody Customer customer) {
// 处理逻辑,保存客户信息
customerService.save(customer);
return ResponseEntity.ok(customer);
}
}
在这个例子中,@Valid
注解用于验证Customer
对象中的字段。如果验证失败,Spring会抛出验证异常并返回相应的错误信息。
5.处理列表数据
@RestController
@RequestMapping("/items")
public class ItemController {
@PostMapping("/batchAdd")
public ResponseEntity<List<Item>> addItems(@RequestBody List<Item> items) {
// 处理逻辑,保存多个项目信息
itemService.saveAll(items);
return ResponseEntity.ok(items);
}
}
在这个例子中,@RequestBody
注解将请求体中的JSON数组数据转换为List<Item>
对象。
4.@RequestHeader
@RequestHeader 是 Spring MVC 中的一个注解,用于将 HTTP 请求头中的信息绑定到方法的参数上。它允许开发者从请求头中获取特定的信息,如认证信息、内容类型等。
1.基本用法
@RestController
@RequestMapping("/books")
public class BookController {
@GetMapping("/info")
public ResponseEntity<String> getBookInfo(@RequestHeader("User-Agent") String userAgent) {
// 处理逻辑,根据 User-Agent 获取书籍信息
return ResponseEntity.ok("User-Agent header: " + userAgent);
}
}
在这个例子中,@RequestHeader("User-Agent")
将请求头中名为 "User-Agent" 的值绑定到方法参数 userAgent
上。
2.可选的请求头参数
@RestController
@RequestMapping("/orders")
public class OrderController {
@GetMapping("/status")
public ResponseEntity<String> getOrderStatus(@RequestHeader(value = "Authorization", required = false) String authorization) {
if (authorization != null) {
// 处理逻辑,根据 Authorization 获取订单状态
return ResponseEntity.ok("Authorization header: " + authorization);
} else {
return ResponseEntity.badRequest().body("Authorization header is not present");
}
}
}
在这个例子中,@RequestHeader(value = "Authorization", required = false)
允许 authorization
参数是可选的。如果请求中没有提供 "Authorization" 请求头,方法可以根据需要处理这种情况。
3.默认值
@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping("/info")
public ResponseEntity<String> getProductInfo(@RequestHeader(value = "Accept-Language", defaultValue = "en-US") String acceptLanguage) {
// 处理逻辑,根据 Accept-Language 获取产品信息;如果请求中没有提供该请求头,则使用默认值 "en-US"
return ResponseEntity.ok("Accept-Language header: " + acceptLanguage);
}
}
在这个例子中,@RequestHeader(value = "Accept-Language", defaultValue = "en-US")
设置了默认值为 "en-US"。如果请求中没有提供 "Accept-Language" 请求头,将使用默认值。
4.处理多个请求头
@RestController
@RequestMapping("/items")
public class ItemController {
@GetMapping("/details")
public ResponseEntity<String> getItemDetails(@RequestHeader("Accept") String acceptHeader,
@RequestHeader("Cache-Control") String cacheControlHeader) {
// 处理逻辑,根据 Accept 和 Cache-Control 获取商品详细信息
return ResponseEntity.ok("Accept header: " + acceptHeader + ", Cache-Control header: " + cacheControlHeader);
}
}
在这个例子中,@RequestHeader
注解可以多次使用,将不同请求头的值绑定到方法的不同参数上。
其他常用注解
1.@ResponseBody
@ResponseBody
是Spring框架中的一个注解,通常用于控制器方法上,用于指示方法的返回值应该直接作为HTTP响应正文(ResponseBody)返回,而不是通过视图解析器进行渲染。它可以用于RESTful API开发中,特别是返回JSON或XML格式的数据。
1.作用
1.将对象直接作为响应体返回: 当方法使用
@ResponseBody
注解后,Spring框架会将方法的返回值,如Java对象或集合,转换为指定格式(如JSON/XML)的响应数据,并直接写入HTTP响应2.简化开发: 省去了手动设置响应头、编码数据等操作,简化了开发流程。
3.支持多种数据格式: 支持返回JSON、XML等多种数据格式,根据请求头中的Accept属性进行内容协商。
2.示例
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
@ResponseBody
public User getUserById(@PathVariable Long id) {
// 假设这里从数据库或其他地方获取了用户对象
User user = userRepository.findById(id);
return user; // 返回的User对象将自动转换为JSON格式
}
}
当访问 /users/{id}
路径时,控制器会根据id查询用户,并直接将用户对象转换为JSON格式返回给客户端,而不需要额外的视图解析器或模板引擎来处理。
2.@ResponseStatus
@ResponseStatus
是Spring框架中的一个注解,用于将特定的HTTP状态码应用到控制器方法或异常处理器方法上。它允许开发者明确指定当特定条件满足时应该返回的HTTP状态码,从而控制HTTP响应的状态。
1.作用
1.指定成功或失败的HTTP状态码: 可以将成功或失败的情况与相应的HTTP状态码关联起来,使得API的设计更加规范和符合RESTful风格。
2.简化异常处理: 可以将特定异常与适当的HTTP状态码关联,从而简化异常处理过程。
2.示例
@Controller
@RequestMapping("/books")
public class BookController {
@GetMapping("/{id}")
@ResponseStatus(HttpStatus.OK)
public ResponseEntity<Book> getBookById(@PathVariable Long id) {
// 假设根据id查询书籍
Book book = bookService.findById(id);
if (book != null) {
return ResponseEntity.ok(book);
} else {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Book not found");
}
}
}
在这个例子中,@ResponseStatus(HttpStatus.OK)
指示当成功找到书籍时,返回HTTP状态码200(OK)。如果没有找到书籍,则抛出 ResponseStatusException
异常,这将触发Spring默认的异常处理机制,返回HTTP状态码404(NOT FOUND)。
在异常处理器方法中使用 @ResponseStatus
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleValidationException(MethodArgumentNotValidException ex) {
// 处理方法参数验证异常,并返回适当的响应
Map<String, Object> body = new HashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("message", "Validation error");
// 添加其他自定义的错误信息
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(body);
}
}
在这个例子中,@ExceptionHandler(MethodArgumentNotValidException.class)
捕获了 MethodArgumentNotValidException
异常,然后通过 @ResponseStatus(HttpStatus.BAD_REQUEST)
指示当发生这种异常时,应返回HTTP状态码400(BAD REQUEST)。同时,使用 ResponseEntity
构建了一个包含错误信息的响应体。