爱彩365彩票官方app下载

Spring MVC核心注解与实践指南

Spring MVC核心注解与实践指南

@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 createProduct(@RequestBody Product product) {

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 createUser(@Valid @RequestBody User user) {

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 loadCategories() {

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> converters) {

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)

@Email

@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 handleNotFound(ResourceNotFoundException ex) {

ErrorResponse error = new ErrorResponse("NOT_FOUND", ex.getMessage());

return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);

}

@ExceptionHandler(MethodArgumentNotValidException.class)

public ResponseEntity> handleValidationExceptions(

MethodArgumentNotValidException ex) {

Map errors = new HashMap<>();

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 getUser(@PathVariable Long id) {

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

缓存静态资源映射配置

合理设置消息转换器顺序

相关推荐

beat365官方app下载手机版 dnf传说勋章打哪个
beat365官方app下载手机版 孙兴慜世界杯进球最多的伟大记录(揭秘孙兴慜如何成为世界杯进球王)
爱彩365彩票官方app下载 小米手机5寿命一般几年