Spring MVC 控制器和请求处理模块教程
目录
控制器概述
在Spring MVC中,控制器是处理用户请求的核心组件。它负责接收HTTP请求,处理业务逻辑,并返回适当的响应。
控制器的职责
- 请求路由: 根据请求URL和方法选择合适的处理函数
- 参数绑定: 将HTTP请求参数绑定到Java对象
- 业务调用: 调用相应的服务层方法
- 结果处理: 处理业务逻辑的执行结果
- 响应生成: 生成适当的HTTP响应
控制器类型
1. 传统Controller(推荐用于页面跳转)
@Controller
public class UserController {
@RequestMapping("/user/list")
public String listUsers(Model model) {
List<User> users = userService.getAllUsers();
model.addAttribute("users", users);
return "user/list"; // 返回视图名
}
}
2. RESTful Controller(推荐用于API开发)
@RestController
@RequestMapping("/api/users")
public class UserRestController {
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.getAllUsers();
return ResponseEntity.ok(users);
}
}
@RequestMapping 注解详解
基础使用
@RequestMapping是Spring MVC中最核心的注解,用于将HTTP请求映射到控制器方法。
基本语法
@Controller
public class BookController {
// 基础映射
@RequestMapping("/books")
public String books() {
return "book/list";
}
// 指定HTTP方法
@RequestMapping(value = "/books", method = RequestMethod.GET)
public String getBooks() {
return "book/list";
}
// 指定多个HTTP方法
@RequestMapping(value = "/books", method = {RequestMethod.GET, RequestMethod.POST})
public String handleBooks() {
return "book/list";
}
}
类级别和方法级别
类级别@RequestMapping
@Controller
@RequestMapping("/admin") // 类级别的路径前缀
public class AdminController {
@RequestMapping("/users") // 完整路径: /admin/users
public String manageUsers() {
return "admin/users";
}
@RequestMapping("/dashboard") // 完整路径: /admin/dashboard
public String dashboard() {
return "admin/dashboard";
}
}
路径映射规则
1. 精确匹配
@RequestMapping("/user/profile") // 只匹配 /user/profile
public String profile() {
return "user/profile";
}
2. 路径变量
@RequestMapping("/user/{id}") // 匹配 /user/123, /user/abc等
public String getUserDetail(@PathVariable String id) {
return "user/detail";
}
// 多个路径变量
@RequestMapping("/user/{userId}/post/{postId}")
public String getPost(@PathVariable Long userId, @PathVariable Long postId) {
return "user/post";
}
3. 通配符匹配
@RequestMapping("/files/**") // 匹配 /files/css/style.css
public String handleFiles(HttpServletRequest request) {
return "files/index";
}
@RequestMapping("/user/*/profile") // 匹配 /user/123/profile
public String userProfile() {
return "user/profile";
}
4. 正则表达式
@RequestMapping("/user/{id:\\d+}") // 只匹配数字ID
public String getUserById(@PathVariable Long id) {
return "user/detail";
}
@RequestMapping("/user/{name:[a-zA-Z]+}")
public String getUserByName(@PathVariable String name) {
return "user/detail";
}
属性完整配置
@Controller
public class AdvancedController {
@RequestMapping(
value = "/advanced/{id}", // 路径映射
method = RequestMethod.GET, // HTTP方法
params = {"type=sale", "status"}, // 必须包含的参数
headers = {"Accept=application/json"}, // 必须包含的请求头
consumes = "application/json", // 接受的Content-Type
produces = "application/json" // 产生的Content-Type
)
public String advancedExample() {
return "advanced/example";
}
}
请求方法映射
HTTP方法快捷注解
Spring MVC提供了针对不同HTTP方法的快捷注解:
@Controller
public class UserController {
// GET请求
@GetMapping("/users")
public String getUsers() {
return "user/list";
}
// POST请求
@PostMapping("/users")
public String createUser() {
return "redirect:/users";
}
// PUT请求
@PutMapping("/users/{id}")
public String updateUser(@PathVariable Long id) {
return "user/edit";
}
// DELETE请求
@DeleteMapping("/users/{id}")
public String deleteUser(@PathVariable Long id) {
return "redirect:/users";
}
// PATCH请求
@PatchMapping("/users/{id}")
public String patchUser(@PathVariable Long id) {
return "user/patch";
}
}
表单处理示例
显示表单页面
@GetMapping("/user/create")
public String showCreateForm(Model model) {
model.addAttribute("user", new User());
return "user/create-form";
}
@PostMapping("/user/create")
public String createUser(@ModelAttribute User user) {
userService.save(user);
return "redirect:/users";
}
PUT/DELETE请求处理
// HTML表单不支持PUT和DELETE方法,需要通过POST模拟
@PostMapping(value = "/user/{id}", params = "_method=PUT")
public String updateUser(@PathVariable Long id, @ModelAttribute User user) {
user.setId(id);
userService.update(user);
return "redirect:/users";
}
@PostMapping(value = "/user/{id}", params = "_method=DELETE")
public String deleteUser(@PathVariable Long id) {
userService.delete(id);
return "redirect:/users";
}
自定义HTTP方法
@Controller
public class CustomMethodController {
// 自定义请求头处理DELETE方法
@RequestMapping(value = "/user/{id}",
method = RequestMethod.POST,
headers = "X-HTTP-Method-Override=DELETE")
public String customDelete(@PathVariable Long id) {
userService.delete(id);
return "redirect:/users";
}
}
参数绑定机制
自动参数绑定
Spring MVC提供了强大的参数绑定功能,能够自动将HTTP请求参数绑定到控制器方法的参数上。
基本类型绑定
@GetMapping("/search")
public String search(@RequestParam String keyword) {
// keyword参数自动绑定
return "search/results";
}
@GetMapping("/user")
public String getUser(@RequestParam Long id) {
// id参数自动转换为Long类型
return "user/detail";
}
@RequestParam 注解详解
基础使用
@GetMapping("/categories")
public String getCategories(
@RequestParam String type, // 必需参数
@RequestParam(required = false) String status, // 可选参数
@RequestParam(defaultValue = "1") int page, // 默认值
@RequestParam(defaultValue = "10") int size // 默认值
) {
return "category/list";
}
数组和集合参数
// 处理数组参数
@GetMapping("/users")
public String getUsers(@RequestParam Long[] userIds) {
// 对应URL: /users?userIds=1&userIds=2&userIds=3
return "user/list";
}
// 处理List参数
@GetMapping("/tags")
public String getTags(@RequestParam List<String> tags) {
// 对应URL: /tags?tags=java&tags=spring&tags=mvc
return "tag/list";
}
// 处理Map参数
@GetMapping("/filters")
public String filter(@RequestParam Map<String, String> filters) {
// filters会自动包含所有请求参数
return "filter/results";
}
自定义参数名称
@GetMapping("/search")
public String search(@RequestParam("search-keyword") String keyword) {
// 映射到参数名search-keyword
return "search/results";
}
@PathVariable 注解详解
单个路径变量
@GetMapping("/user/{id}")
공blic String getUser(@PathVariable Long id) {
return "user/detail";
}
@GetMapping("/user/{username}")
public String getUserByUsername(@PathVariable String username) {
return "user/detail";
}
多个路径变量
@GetMapping("/user/{userId}/post/{postId}")
public String getUserPost(
@PathVariable Long userId,
@PathVariable Long postId
) {
return "user/post/detail";
}
指定路径变量名称
@GetMapping("/user/{id}")
public String getUser(@PathVariable("id") Long userId) {
// 明确指定路径变量名称
return "user/detail";
}
限定路径变量格式
@GetMapping("/user/{id:\\d+}") // 只匹配数字
public String getUserById(@PathVariable Long id) {
return "user/detail";
}
@GetMapping("/user/{username:[a-zA-Z0-9_]+}") // 只匹配字母、数字、下划线
public String getUserByUsername(@PathVariable String username) {
return "user/detail";
}
@RequestHeader 注解
请求头绑定
@GetMapping("/api/users")
public String getUsers(@RequestHeader("Accept") String accept,
@RequestHeader(value = "Authorization", required = false) String auth) {
return "user/list";
}
// 绑定所有请求头
@GetMapping("/debug")
public String debug(@RequestHeader Map<String, String> headers) {
return "debug/headers";
}
@CookieValue 注解
Cookie绑定
@GetMapping("/profile")
public String getProfile(@CookieValue("sessionId") String sessionId) {
return "user/profile";
}
// 指定Cookie名称
@GetMapping("/preferences")
public String getPreferences(@CookieValue(value = "theme", defaultValue = "light") String theme) {
return "user/preferences";
}
路径变量处理
路径参数验证
使用约束注解
@GetMapping("/user/{id}")
public String getUser(@PathVariable @Min(1) Long id) {
return "user/detail";
}
@GetMapping("/user/{username}")
public String getUserByUsername(@PathVariable @Size(min = 3, max = 20) String username) {
return "user/detail";
}
自定义验证
@GetMapping("/user/{userId}")
public String getUser(@PathVariable("userId") @ValidUserId Long userId) {
return "user/detail";
}
// 自定义验证注解
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UserIdValidator.class)
public @interface ValidUserId {
String message() default "无效的用户ID";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@Component
public class UserIdValidator implements ConstraintValidator<ValidUserId, Long> {
@Override
public boolean isValid(Long value, ConstraintValidatorContext context) {
return value != null && value > 0 && userRepository.existsById(value);
}
}
路径变量转换
自定义转换器
@Component
public class StringToUserConverter implements Converter<String, User> {
@Autowired
private UserService userService;
@Override
public User convert(String username) {
return userService.findByUsername(username);
}
}
// 使用自定义转换器
@GetMapping("/user/{username}")
public String getUser(@PathVariable User user) {
// username会自动转换为User对象
return "user/detail";
}
请求参数处理
复杂对象绑定
表单对象绑定
@PostMapping("/user/create")
public String createUser(@ModelAttribute User user) {
userService.save(user);
return "redirect:/users";
}
// 指定模型属性名称
@PostMapping("/admin/create")
public String createAdmin(@ModelAttribute("admin") User admin) {
return "admin/create";
}
嵌套对象绑定
public class UserProfile {
private User user;
private Address address;
private List<String> hobbies;
// getters and setters
}
@PostMapping("/profile/save")
public String saveProfile(@ModelAttribute UserProfile profile) {
return "profile/save";
}
JSON请求体处理
RESTful API中的JSON处理
@RestController
@RequestMapping("/api/users")
public class UserRestController {
@PostMapping
public ResponseEntity<User> createUser(@RequestBody @Valid User user) {
User savedUser = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id,
@RequestBody @Valid User user) {
user.setId(id);
User updatedUser = userService.update(user);
return ResponseEntity.ok(updatedUser);
}
}
文件上传处理
单文件上传
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
// 处理上传的文件
String filename = file.getOriginalFilename();
// 保存文件逻辑
}
return "upload/success";
}
多文件上传
@PostMapping("/upload-multiple")
public String uploadFiles(@RequestParam("files") MultipartFile[] files) {
for (MultipartFile file : files) {
if (!file.isEmpty()) {
// 处理每个文件
}
}
return "upload/success";
}
表单+文件上传
@PostMapping("/user/create")
public String createUserWithAvatar(@ModelAttribute User user,
@RequestParam("avatar") MultipartFile avatar) {
// 处理用户创建和头像上传
return "redirect:/users";
}
请求体处理
@RequestBody 注解详解
处理JSON请求
@RestController
public class ApiController {
@PostMapping("/api/login")
public ResponseEntity<LoginResponse> login(@RequestBody LoginRequest request) {
// 处理登录逻辑
return ResponseEntity.ok(new LoginResponse());
}
}
public class LoginRequest {
private String username;
private String password;
// getters and setters
}
使用HttpMessageConverter
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override:
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.indentOutput(true)
.dateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
}
XML请求处理
配置XML支持
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-xml</artifactId>
<version>2.13.3</version>
</dependency>
@PostMapping(value = "/user", consumes = "application/xml")
public ResponseEntity<User> createUserFromXML(@RequestBody User user) {
return ResponseEntity.ok(userService.save(user));
}
请求体验证
使用JSR-303验证
public class UserCreateRequest {
@NotBlank(message = "用户名不能为空")
@Size(min = 3, max = 20, message = "用户名长度必须在3-20个字符")
private String username;
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
@NotBlank(message = "密码不能为空")
@Size(min = 6, message = "密码长度至少6位")
private String password;
// getters and setters
}
@PostMapping("/user/create")
public ResponseEntity<?> createUser(@RequestBody @Valid UserCreateRequest request,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
// 返回验证错误信息
return ResponseEntity.badRequest().body(bindingResult.getAllErrors());
}
// 创建用户逻辑
return ResponseEntity.ok("用户创建成功");
}
返回值处理
视图名返回
基础视图返回
@GetMapping("/home")
public String home() {
return "home"; // 返回逻辑视图名
}
@GetMapping("/user/{id}")
public String userDetail(@PathVariable Long id) {
return "user/detail"; // 路径: /WEB-INF/views/user/detail.jsp
}
重定向
@PostMapping("/user/create")
public String createUser(@ModelAttribute User user) {
userService.save(user);
return "redirect:/users"; // 重定向到用户列表
}
// 带参数的重定向
@PostMapping("/user/create")
public String createUser(@ModelAttribute User user) {
User savedUser = userService.save(user);
return "redirect:/user/" + savedUser.getId();
}
转发
@GetMapping("/internal")
public String internalRedirect() {
return "forward:/internal-target";
}
ModelAndView 返回
基础ModelAndView
@GetMapping("/dashboard")
public ModelAndView dashboard() {
ModelAndView mav = new ModelAndView();
mav.setViewName("dashboard");
mav.addObject("userCount", userService.getTotalCount());
mav.addObject("onlineUsers", userService.getOnlineUserCount());
return mav;
}
构造函数方式
@GetMapping("/profile/{id}")
public ModelAndView getUserProfile(@PathVariable Long id) {
User user = userService.findById(id);
return new ModelAndView("user/profile", "user", user);
// 等同于 setViewName("user/profile") 和 addObject("user", user)
}
@ResponseBody 注解
返回JSON数据
@GetMapping("/api/user/{id}")
@ResponseBody
public User getUserJson(@PathVariable Long id) {
return userService.findById(id);
}
@RestController // @RestController = @Controller + @ResponseBody
@RequestMapping("/api")
public class ApiController {
@GetMapping("/users")
public List<User> getAllUsers() {
return userService.getAllUsers();
}
}
ResponseEntity 返回
完整HTTP响应
@RestController
public class ApiController {
@GetMapping("/api/user/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
try {
User user = userService.findById(id);
return ResponseEntity.ok(user);
} catch (UserNotFoundException e) {
return ResponseEntity.notFound().build();
}
}
@PostMapping("/api/user")
public ResponseEntity<User> createUser(@RequestBody @Valid User user) {
User savedUser = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED)
.body(savedUser);
}
}
自定义响应头
@GetMapping("/api/download/{id}")
public ResponseEntity<Resource> downloadFile(@PathVariable Long id) {
Resource file = fileService.getFile(id);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + id + ".pdf\""
.contentType(MediaType.APPLICATION_PDF)
.body(file);
}
RESTful API 设计
REST 设计原则
资源识别
@RestController
@RequestMapping("/api/users") // 资源集合
public class UserRestController {
@GetMapping // GET /api/users
public List<User> getUsers() {
return userService.getAllUsers();
}
@PostMapping // POST /api/users
public ResponseEntity<User> createUser(@RequestBody @Valid User user) {
User savedUser = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
}
@GetMapping("/{id}") // GET /api/users/{id}
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
@PutMapping("/{id}") // PUT /api/users/{id}
public ResponseEntity<User> updateUser(@PathVariable Long id,
@RequestBody @Valid User user) {
user.setId(id);
User updatedUser = userService.update(user);
return ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/{id}") // DELETE /api/users/{id}
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
}
分页和排序
分页参数处理
@GetMapping
public ResponseEntity<Page<User>> getUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sortBy,
@RequestParam(defaultValue = "asc") String sortDir) {
Pageable pageable = PageRequest.of(page, size,
Sort.Direction.fromString(sortDir), sortBy);
Page<User> users = userService.findAll(pageable);
return ResponseEntity.ok(users);
}
搜索和过滤
搜索功能
@GetMapping("/search")
public ResponseEntity<List<User>> searchUsers(
@RequestParam(required = false) String keyword,
@RequestParam(required = false) String department,
@RequestParam(required = false) String status) {
List<User> users = userService.search(keyword, department, status);
return ResponseEntity.ok(users);
}
API版本控制
URL版本控制
@RestController
@RequestMapping("/api/v1/users")
public class UserV1Controller {
// v1版本的实现
}
@RestController
@RequestMapping("/api/v2/users")
public class UserV2Controller {
// v2版本的实现
}
请求头版本控制
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping(produces = "application/vnd.api.v1+json")
public ResponseEntity<List<UserV1>> getUsersV1() {
// v1版本实现
}
@GetMapping(produces = "application/vnd.api.v2+json")
public ResponseEntity<List<UserV2>> getUsersV2() {
// v2版本实现
}
}
控制器最佳实践
控制器的职责分离
1. 保持控制器的轻薄
@Controller
public class UserController {
@Autowired
private UserService userService; // 只注入服务层
@GetMapping("/user/{id}")
public String getUserDetail(@PathVariable Long id, Model model) {
User user = userService.findById(id); // 只负责调用服务
model.addAttribute("user", user);
return "user/detail"; // 只负责返回视图
}
// 不要在控制器中写业务逻辑
}
2. 使用DTO进行数据传输
// 专门的DTO类用于API传输
public class UserApiDto {
private Long id;
private String username;
private String email;
// 不包含敏感信息如密码
// getters and setters
}
@RestController
@RequestMapping("/api/users")
public class UserApiController {
@GetMapping("/{id}")
public ResponseEntity<UserApiDto> getUser(@PathVariable Long id) {
User user = userService.findById(id);
UserApiDto dto = convertToDto(user);
return ResponseEntity.ok(dto);
}
private UserApiDto convertToDto(User user) {
// 转换逻辑
}
}
异常处理策略
1. 使用@ControllerAdvice
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
ErrorResponse error = new ErrorResponse("USER_NOT_FOUND", ex.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
@ExceptionHandler(ValidationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<ErrorResponse> handleValidation(ValidationException ex) {
ErrorResponse error = new ErrorResponse("VALIDATION_ERROR", ex.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}
}
2. 业务异常自定义
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(Long id) {
super("User not found with id: " + id);
}
}
public class ValidationException extends RuntimeException {
public ValidationException(String message) {
super(message);
}
}
参数验证最佳实践
1. 使用Spring验证注解
@PostMapping("/user/create")
public ResponseEntity<?> createUser(@RequestBody @Valid UserCreateRequest request,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
Map<String, String> errors = new HashMap<>();
bindingResult.getFieldErrors().forEach(error -> {
errors.put(error.getField(), error.getDefaultMessage());
});
return ResponseEntity.badRequest().body(errors);
}
// 处理逻辑
return ResponseEntity.ok("用户创建成功");
}
2. 自定义验证注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueUsernameValidator.class)
public @interface UniqueUsername {
String message() default "用户名已存在";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
性能优化建议
1. 异步处理
@RestController
public class AsyncController {
@GetMapping("/async/task/{id}")
public ResponseEntity<CompletableFuture<String>> asyncTask(@PathVariable Long id) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 执行耗时任务
return processTask(id);
});
return ResponseEntity.ok(future);
}
}
2. 缓存处理
@RestController
public class ApiController {
@GetMapping("/api/user/{id}")
@Cacheable(value = "users", key = "#id")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
}
常见问题解决
1. 参数绑定失败
问题描述: @RequestParam绑定失败
// 错误示例
@GetMapping("/search")
public String search(@RequestParam String keyword) { // keyword为null时会抛出异常
return "search/results";
}
// 正确解决方案
@GetMapping("/search")
public String search(@RequestParam(required = false) String keyword,
Model model) {
if (keyword != null && !keyword.trim().isEmpty()) {
// 处理搜索逻辑
}
return "search/results";
}
2. 路径冲突问题
问题描述: 多个路径映射冲突
// 冲突的路径
@RequestMapping("/user/*")
public String userWildcard() {
return "user/wildcard";
}
@RequestMapping("/user/{id}") // 两者可能冲突
public String userDetail(@PathVariable Long id) {
return "user/detail";
}
// 解决方案: 调整映射顺序或使用更精确的模式
@RequestMapping("/user/{id:\\d+}") // 明确数字ID
public String userDetail(@PathVariable Long id) {
return "user/detail";
}
3. JSON反序列化问题
问题描述: JSON请求体无法正确绑定到对象
// 确保JSON字段名与Java属性名匹配
public class UserCreateRequest {
private String username; // 对应JSON中的"username"
private String email; // 对应JSON中的"email"
// 可以使用@JsonProperty指定字段名
@JsonProperty("user_name")
private String userName;
// getters and setters
}
4! @PathVariable类型转换问题
问题描述: String无法转换为Long
// 错误处理方式
@GetMapping("/user/{id}")
public String getUser(@PathVariable Long id) {
// 如果路径是/user/abc,会转换失败
}
// 解决方案1: 使用String接收然后手动转换
@GetMapping("/user/{id}")
public String getUser(@PathVariable String id) {
try {
Long userId = Long.parseLong(id);
// 处理逻辑
} catch (NumberFormatException e) {
return "error/400"; // 无效ID
}
}
// 解决方案2: 使用正则表达式约束
@GetMapping("/user/{id:\\d+}")
public String getUser(@PathVariable Long id) {
// 只能匹配数字ID
}
5. CORS跨域问题
常见问题: API接口跨域访问失败
// 解决方案: 配置CORS
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true);
}
}
// 或者使用注解
@CrossOrigin(origins = "http://localhost:3000")
@RestController
@RequestMapping("/api/users")
public class UserRestController {
// 控制器方法
}
总结
Spring MVC控制器和请求处理模块是框架的核心部分,本教程全面介绍了:
核心技术要点
1. @RequestMapping注解
- 灵活的路由映射配置
- 支持多种路径模式
- HTTP方法限定和属性配置
2. 参数绑定机制
- @RequestParam、@PathVariable等注解使用
- 复杂对象的自动绑定
- 自定义转换器和验证
3. 请求处理流程
- HTTP请求到控制器方法的映射
- 参数提取和类型转换
- 业务逻辑调用和响应生成
4. RESTful API设计
- REST架构风格遵循
- 资源URL设计规范
- HTTP状态码正确使用
5. 高级特性
- 文件上传处理
- JSON/XML请求体处理
- 异步处理和性能优化
最佳实践建议
- 职责分离: 控制器只负责请求处理和响应生成
- 异常处理: 统一全局异常处理机制
- 参数验证: 完善的输入参数验证
- DTO使用: 专门的传输对象避免敏感数据暴露
- 版本控制: API版本管理策略
- 性能优化: 异步处理和缓存机制
掌握了控制器和请求处理模块后,建议继续学习其他Spring MVC模块:
- 视图技术和数据处理模块
- 表单处理和验证模块
- 高级特性模块(拦截器、异常处理等)
- 测试和集成模块
这些模块的知识将使您能够构建更加健壮和生产级的Spring MVC应用程序。

被折叠的 条评论
为什么被折叠?



