@RequestMapping注解详解
@RequestMapping是Spring MVC中最基础且使用频率最高的注解,用于将HTTP请求映射到控制器方法。该注解可作用于类级别和方法级别,支持多种属性配置:
@Controller
@RequestMapping("/products")
public class ProductController {
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String getProduct(@PathVariable Long id, Model model) {
Product product = productService.findById(id);
model.addAttribute("product", product);
return "productDetail";
}
@RequestMapping(value = "/create",
method = {RequestMethod.GET, RequestMethod.POST},
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity
Product savedProduct = productService.save(product);
return new ResponseEntity<>(savedProduct, HttpStatus.CREATED);
}
}
核心属性解析:
value/path:定义请求路径映射,支持Ant风格路径模式
method:指定支持的HTTP方法类型(GET/POST等)
params:要求请求必须包含特定参数
headers:限制请求头必须满足特定条件
consumes:指定处理请求的媒体类型(如application/json)
produces:指定响应输出的媒体类型
开发技巧:
类级别定义基础路径,方法级别定义具体端点
使用组合注解(@GetMapping等)简化代码
路径参数使用{}语法配合@PathVariable
媒体类型协商优先使用produces/consumes
参数绑定注解簇
@RequestParam参数绑定
处理查询参数和表单数据的标准方式:
@GetMapping("/search")
public String searchProducts(
@RequestParam(name = "keyword", required = false) String searchTerm,
@RequestParam(defaultValue = "1") int page,
@RequestParam(required = false) String sortBy) {
// 业务逻辑
}
参数选项:
required:是否必须参数(默认true)
defaultValue:参数默认值
name/value:参数别名
@PathVariable路径变量
绑定URI模板变量到方法参数:
@DeleteMapping("/{category}/{id}")
public ResponseEntity deleteItem(
@PathVariable String category,
@PathVariable Long id) {
// 删除操作
}
最佳实践:
保持路径变量名称与方法参数名一致
复杂类型需要自定义Converter
配合正则表达式进行参数验证: @GetMapping("/{id:\\d+}")
@RequestBody请求体处理
处理非表单类型的请求内容(JSON/XML):
@PostMapping
public ResponseEntity
User savedUser = userService.create(user);
return ResponseEntity.created(URI.create("/users/" + savedUser.getId()))
.body(savedUser);
}
注意事项:
需要配置消息转换器(如MappingJackson2HttpMessageConverter)
配合@Valid进行参数验证
不支持multipart/form-data类型
模型处理注解
@ModelAttribute的三种用法
方法参数绑定:
@PostMapping("/order")
public String submitOrder(@ModelAttribute("orderForm") Order order) {
// 处理订单
}
方法级别属性添加:
@ModelAttribute("categories")
public List
return categoryService.getAll();
}
返回值隐式绑定:
@ModelAttribute
public User currentUser() {
return userService.getCurrentUser();
}
@SessionAttributes会话管理
@Controller
@SessionAttributes("shoppingCart")
public class CartController {
@ModelAttribute("shoppingCart")
public ShoppingCart initializeCart() {
return new ShoppingCart();
}
@PostMapping("/cart/add")
public String addItem(@ModelAttribute ShoppingCart cart,
@RequestParam Item item) {
cart.addItem(item);
return "redirect:/cart";
}
}
注意点:
需配合@SessionAttribute注解清除属性
会话超时处理策略
分布式会话存储问题
响应处理注解
@ResponseBody与HttpMessageConverter
@GetMapping(value = "/report", produces = MediaType.APPLICATION_PDF_VALUE)
@ResponseBody
public byte[] generateReport() {
return pdfService.generateReport();
}
转换器配置示例:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.indentOutput(true)
.dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
}
@RestController复合注解
等效于@Controller + @ResponseBody:
@RestController
@RequestMapping("/api/users")
public class UserApiController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
}
验证注解与错误处理
参数验证流程
@PostMapping("/register")
public String registerUser(@Valid @ModelAttribute UserForm form,
BindingResult result) {
if (result.hasErrors()) {
return "registrationForm";
}
userService.register(form);
return "redirect:/welcome";
}
常用验证注解:
@NotNull/@NotEmpty
@Size(min=2, max=30)
@Pattern(regexp="正则表达式")
@Future/@Past
自定义验证器示例
public class PhoneValidator implements ConstraintValidator
private Pattern pattern = Pattern.compile("^1[3-9]\\d{9}$");
public boolean isValid(String value, ConstraintValidatorContext context) {
return value != null && pattern.matcher(value).matches();
}
}
异常处理机制
@ExceptionHandler控制器级异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity
ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity
MethodArgumentNotValidException ex) {
Map
ex.getBindingResult().getAllErrors().forEach(error -> {
String fieldName = ((FieldError) error).getField();
String message = error.getDefaultMessage();
errors.put(fieldName, message);
});
return ResponseEntity.badRequest().body(errors);
}
}
RESTful支持注解
@ResponseStatus状态码控制
@ResponseStatus(code = HttpStatus.CREATED, reason = "Resource created")
public class CreatedException extends RuntimeException {}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteResource(@PathVariable Long id) {
resourceService.delete(id);
}
HATEOAS支持示例
@GetMapping("/{id}")
public EntityModel
User user = userService.findById(id);
return EntityModel.of(user,
linkTo(methodOn(UserController.class).getUser(id)).withSelfRel(),
linkTo(methodOn(UserController.class).getAllUsers()).withRel("users"));
}
跨域处理注解
@CrossOrigin配置示例
@RestController
@CrossOrigin(origins = "https://trusted-domain.com",
maxAge = 3600,
allowedHeaders = {"x-requested-with", "content-type"},
methods = {RequestMethod.GET, RequestMethod.POST})
@RequestMapping("/api")
public class ApiController {
// 控制器方法
}
测试验证代码示例
MockMVC测试用例
@SpringBootTest
@AutoConfigureMockMvc
class ProductControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void testGetProduct() throws Exception {
mockMvc.perform(get("/products/123")
.header("Accept", "application/json"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("Test Product"));
}
@Test
void testCreateProduct() throws Exception {
String jsonBody = "{ \"name\":\"New Product\", \"price\":99.99 }";
mockMvc.perform(post("/products")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonBody))
.andExpect(status().isCreated())
.andExpect(header().exists("Location"));
}
}
性能优化建议
合理使用@RequestMapping的窄化配置
优先使用组合注解提升代码可读性
批量参数绑定使用@ModelAttribute
异步处理使用@Async和Callable
缓存静态资源映射配置
合理设置消息转换器顺序