网站 购买小企业网站建设哪找
👋 大家好,我是 阿问学长
!专注于分享优质开源项目
解析、毕业设计项目指导
支持、幼小初高
的教辅资料
推荐等,欢迎关注交流!🚀
SpringMVC请求处理与控制器
📖 本文概述
本文是SSM框架系列SpringMVC基础篇的第二篇,将深入探讨SpringMVC的请求处理机制和控制器的使用方法。通过详细的代码示例和最佳实践,帮助读者掌握Controller的各种用法和请求处理技巧。
🎯 学习目标
- 深入理解SpringMVC的请求处理流程
- 掌握Controller的各种注解和用法
- 学会处理不同类型的HTTP请求
- 了解参数绑定和数据传递机制
- 掌握RESTful风格的URL设计
1. 请求处理流程详解
1.1 完整的请求处理流程
/*** SpringMVC请求处理流程演示*/
public class RequestProcessingFlow {/*** 详细的请求处理步骤*/public void demonstrateFlow() {/** 1. 客户端发送请求* GET /user/profile/123?tab=basic*//** 2. DispatcherServlet接收请求* - 解析请求URL: /user/profile/123* - 解析请求方法: GET* - 解析请求参数: tab=basic*//** 3. HandlerMapping查找处理器* - 根据URL模式匹配: /user/profile/{id}* - 找到对应的Controller方法: UserController.getProfile()* - 创建HandlerExecutionChain(包含拦截器)*//** 4. HandlerAdapter调用处理器* - 参数解析: 将{id}绑定为123,将tab绑定为"basic"* - 调用Controller方法: getProfile(123, "basic")* - 处理返回值: 转换为ModelAndView*//** 5. ViewResolver解析视图* - 根据视图名称查找视图: "user/profile"* - 创建View对象: JstlView*//** 6. View渲染响应* - 将Model数据填充到视图中* - 生成HTML响应* - 返回给客户端*/}
}
1.2 请求映射机制
/*** 请求映射演示*/
@Controller
@RequestMapping("/user")
public class UserController {/*** 基本的请求映射*/@RequestMapping("/list")public String list() {return "user/list";}/*** 指定HTTP方法*/@RequestMapping(value = "/create", method = RequestMethod.GET)public String showCreateForm() {return "user/create";}@RequestMapping(value = "/create", method = RequestMethod.POST)public String create() {return "redirect:/user/list";}/*** 使用组合注解(推荐)*/@GetMapping("/edit/{id}")public String showEditForm(@PathVariable Long id) {return "user/edit";}@PostMapping("/edit")public String edit() {return "redirect:/user/list";}@PutMapping("/{id}")public String update(@PathVariable Long id) {return "redirect:/user/list";}@DeleteMapping("/{id}")public String delete(@PathVariable Long id) {return "redirect:/user/list";}/*** 多个URL映射*/@GetMapping({"/profile", "/info", "/detail"})public String profile() {return "user/profile";}/*** 带参数的映射*/@GetMapping(value = "/search", params = "type=advanced")public String advancedSearch() {return "user/advanced-search";}@GetMapping(value = "/search", params = "!type")public String basicSearch() {return "user/basic-search";}/*** 带请求头的映射*/@GetMapping(value = "/api/users", headers = "Accept=application/json")@ResponseBodypublic List<User> getUsersJson() {return userService.findAll();}@GetMapping(value = "/api/users", headers = "Accept=application/xml")@ResponseBodypublic List<User> getUsersXml() {return userService.findAll();}/*** 内容类型映射*/@PostMapping(value = "/api/users", consumes = "application/json")@ResponseBodypublic User createUserFromJson(@RequestBody User user) {return userService.save(user);}@PostMapping(value = "/api/users", consumes = "application/xml")@ResponseBodypublic User createUserFromXml(@RequestBody User user) {return userService.save(user);}
}
2. 参数绑定详解
2.1 各种参数绑定方式
/*** 参数绑定演示*/
@Controller
@RequestMapping("/demo")
public class ParameterBindingController {/*** 1. 基本类型参数绑定*/@GetMapping("/basic")public String basicParams(String name, // 自动绑定name参数int age, // 自动类型转换boolean active, // 布尔类型转换Date birthday, // 日期类型转换(需要配置)Model model) {model.addAttribute("name", name);model.addAttribute("age", age);model.addAttribute("active", active);model.addAttribute("birthday", birthday);return "demo/basic";}/*** 2. @RequestParam注解*/@GetMapping("/request-param")public String requestParam(@RequestParam("username") String name, // 指定参数名@RequestParam(value = "age", defaultValue = "18") int age, // 默认值@RequestParam(required = false) String email, // 可选参数@RequestParam List<String> hobbies, // 数组/集合参数Model model) {model.addAttribute("name", name);model.addAttribute("age", age);model.addAttribute("email", email);model.addAttribute("hobbies", hobbies);return "demo/request-param";}/*** 3. @PathVariable路径变量*/@GetMapping("/user/{id}/posts/{postId}")public String pathVariable(@PathVariable Long id, // 路径变量@PathVariable("postId") Long pid, // 指定变量名@PathVariable Map<String, String> pathVars, // 所有路径变量Model model) {model.addAttribute("userId", id);model.addAttribute("postId", pid);model.addAttribute("allPathVars", pathVars);return "demo/path-variable";}/*** 4. @RequestHeader请求头*/@GetMapping("/headers")public String requestHeader(@RequestHeader("User-Agent") String userAgent, // 指定请求头@RequestHeader(value = "Accept", required = false) String accept, // 可选请求头@RequestHeader Map<String, String> headers, // 所有请求头Model model) {model.addAttribute("userAgent", userAgent);model.addAttribute("accept", accept);model.addAttribute("headers", headers);return "demo/headers";}/*** 5. @CookieValue Cookie值*/@GetMapping("/cookies")public String cookieValue(@CookieValue(value = "JSESSIONID", required = false) String sessionId,@CookieValue(value = "theme", defaultValue = "default") String theme,Model model) {model.addAttribute("sessionId", sessionId);model.addAttribute("theme", theme);return "demo/cookies";}/*** 6. @ModelAttribute对象绑定*/@PostMapping("/user")public String modelAttribute(@ModelAttribute User user, Model model) {// Spring自动将请求参数绑定到User对象model.addAttribute("user", user);return "demo/model-attribute";}/*** 7. @RequestBody JSON/XML绑定*/@PostMapping("/api/user")@ResponseBodypublic User requestBody(@RequestBody User user) {// 将请求体中的JSON/XML转换为User对象return userService.save(user);}/*** 8. HttpServletRequest和HttpServletResponse*/@GetMapping("/servlet")public String servletApi(HttpServletRequest request,HttpServletResponse response,HttpSession session,Model model) {String remoteAddr = request.getRemoteAddr();String sessionId = session.getId();model.addAttribute("remoteAddr", remoteAddr);model.addAttribute("sessionId", sessionId);return "demo/servlet";}
}
2.2 复杂对象绑定
/*** 复杂对象绑定演示*/
@Controller
@RequestMapping("/complex")
public class ComplexBindingController {/*** 嵌套对象绑定*/@PostMapping("/nested")public String nestedObject(@ModelAttribute UserForm userForm, Model model) {/** 请求参数示例:* username=john* email=john@example.com* profile.realName=John Doe* profile.phone=1234567890* profile.address.city=Beijing* profile.address.street=Chaoyang Road*/model.addAttribute("userForm", userForm);return "complex/nested";}/*** 集合对象绑定*/@PostMapping("/collection")public String collectionBinding(@ModelAttribute UserListForm form, Model model) {/** 请求参数示例:* users[0].username=user1* users[0].email=user1@example.com* users[1].username=user2* users[1].email=user2@example.com*/model.addAttribute("form", form);return "complex/collection";}/*** Map对象绑定*/@PostMapping("/map")public String mapBinding(@RequestParam Map<String, String> params, Model model) {model.addAttribute("params", params);return "complex/map";}
}/*** 表单对象定义*/
public class UserForm {private String username;private String email;private UserProfile profile;// getter/setter...
}public class UserProfile {private String realName;private String phone;private Address address;// getter/setter...
}public class Address {private String city;private String street;// getter/setter...
}public class UserListForm {private List<User> users;// getter/setter...
}
3. 数据传递机制
3.1 Model数据传递
/*** Model数据传递演示*/
@Controller
@RequestMapping("/data")
public class DataTransferController {/*** 使用Model传递数据*/@GetMapping("/model")public String useModel(Model model) {model.addAttribute("message", "Hello from Model");model.addAttribute("user", new User("John", "john@example.com"));model.addAttribute("users", userService.findAll());return "data/model";}/*** 使用ModelMap传递数据*/@GetMapping("/model-map")public String useModelMap(ModelMap modelMap) {modelMap.addAttribute("message", "Hello from ModelMap");modelMap.put("timestamp", new Date());return "data/model-map";}/*** 使用ModelAndView传递数据*/@GetMapping("/model-and-view")public ModelAndView useModelAndView() {ModelAndView mav = new ModelAndView("data/model-and-view");mav.addObject("message", "Hello from ModelAndView");mav.addObject("data", getData());return mav;}/*** 使用@ModelAttribute预处理数据*/@ModelAttribute("commonData")public Map<String, Object> commonData() {Map<String, Object> data = new HashMap<>();data.put("appName", "SSM Demo");data.put("version", "1.0.0");data.put("currentTime", new Date());return data;}@GetMapping("/common")public String useCommonData(Model model) {// commonData会自动添加到所有请求的Model中model.addAttribute("pageTitle", "Common Data Demo");return "data/common";}/*** 使用Session存储数据*/@GetMapping("/session")public String useSession(HttpSession session, Model model) {session.setAttribute("sessionData", "Data stored in session");Object data = session.getAttribute("sessionData");model.addAttribute("sessionData", data);return "data/session";}/*** 使用@SessionAttributes*/@Controller@SessionAttributes({"user", "preferences"})public static class SessionAttributesController {@GetMapping("/session-attrs")public String sessionAttributes(Model model) {model.addAttribute("user", new User("Session User", "session@example.com"));model.addAttribute("preferences", getPreferences());return "data/session-attrs";}@GetMapping("/use-session-attrs")public String useSessionAttributes(@ModelAttribute("user") User user, Model model) {// user对象从Session中获取model.addAttribute("message", "Hello " + user.getUsername());return "data/use-session-attrs";}}
}
3.2 重定向和转发
/*** 重定向和转发演示*/
@Controller
@RequestMapping("/redirect")
public class RedirectController {/*** 重定向*/@PostMapping("/save")public String save(@ModelAttribute User user, RedirectAttributes redirectAttributes) {try {userService.save(user);// 重定向时传递成功消息redirectAttributes.addFlashAttribute("message", "用户保存成功");redirectAttributes.addFlashAttribute("messageType", "success");// 重定向到列表页面return "redirect:/user/list";} catch (Exception e) {redirectAttributes.addFlashAttribute("message", "保存失败:" + e.getMessage());redirectAttributes.addFlashAttribute("messageType", "error");// 重定向回表单页面return "redirect:/user/create";}}/*** 带参数的重定向*/@GetMapping("/with-params")public String redirectWithParams(RedirectAttributes redirectAttributes) {// 添加URL参数redirectAttributes.addAttribute("id", 123);redirectAttributes.addAttribute("tab", "profile");// 添加Flash属性(不会出现在URL中)redirectAttributes.addFlashAttribute("message", "重定向成功");// 重定向到: /user/detail?id=123&tab=profilereturn "redirect:/user/detail";}/*** 转发*/@GetMapping("/forward")public String forward(Model model) {model.addAttribute("message", "这是转发的数据");// 转发到另一个Controller方法return "forward:/data/model";}/*** 条件重定向*/@PostMapping("/conditional")public String conditionalRedirect(@RequestParam String action, @ModelAttribute User user,RedirectAttributes redirectAttributes) {switch (action) {case "save":userService.save(user);redirectAttributes.addFlashAttribute("message", "保存成功");return "redirect:/user/list";case "saveAndContinue":User savedUser = userService.save(user);redirectAttributes.addFlashAttribute("message", "保存成功,继续编辑");return "redirect:/user/edit/" + savedUser.getId();case "cancel":return "redirect:/user/list";default:return "redirect:/user/create";}}
}
4. RESTful风格设计
4.1 RESTful Controller设计
/*** RESTful风格的用户管理Controller*/
@RestController
@RequestMapping("/api/users")
public class UserRestController {@Autowiredprivate UserService userService;/*** GET /api/users - 获取用户列表*/@GetMappingpublic ResponseEntity<List<User>> getUsers(@RequestParam(defaultValue = "0") int page,@RequestParam(defaultValue = "10") int size,@RequestParam(required = false) String keyword) {List<User> users = userService.findUsers(page, size, keyword);return ResponseEntity.ok(users);}/*** GET /api/users/{id} - 获取指定用户*/@GetMapping("/{id}")public ResponseEntity<User> getUser(@PathVariable Long id) {User user = userService.findById(id);if (user == null) {return ResponseEntity.notFound().build();}return ResponseEntity.ok(user);}/*** POST /api/users - 创建用户*/@PostMappingpublic ResponseEntity<User> createUser(@Valid @RequestBody User user) {User createdUser = userService.save(user);URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(createdUser.getId()).toUri();return ResponseEntity.created(location).body(createdUser);}/*** PUT /api/users/{id} - 更新用户*/@PutMapping("/{id}")public ResponseEntity<User> updateUser(@PathVariable Long id, @Valid @RequestBody User user) {if (!userService.exists(id)) {return ResponseEntity.notFound().build();}user.setId(id);User updatedUser = userService.update(user);return ResponseEntity.ok(updatedUser);}/*** PATCH /api/users/{id} - 部分更新用户*/@PatchMapping("/{id}")public ResponseEntity<User> patchUser(@PathVariable Long id, @RequestBody Map<String, Object> updates) {if (!userService.exists(id)) {return ResponseEntity.notFound().build();}User updatedUser = userService.partialUpdate(id, updates);return ResponseEntity.ok(updatedUser);}/*** DELETE /api/users/{id} - 删除用户*/@DeleteMapping("/{id}")public ResponseEntity<Void> deleteUser(@PathVariable Long id) {if (!userService.exists(id)) {return ResponseEntity.notFound().build();}userService.deleteById(id);return ResponseEntity.noContent().build();}/*** GET /api/users/{id}/roles - 获取用户角色*/@GetMapping("/{id}/roles")public ResponseEntity<List<Role>> getUserRoles(@PathVariable Long id) {if (!userService.exists(id)) {return ResponseEntity.notFound().build();}List<Role> roles = userService.getUserRoles(id);return ResponseEntity.ok(roles);}/*** POST /api/users/{id}/roles - 为用户添加角色*/@PostMapping("/{id}/roles")public ResponseEntity<Void> addUserRole(@PathVariable Long id, @RequestBody Role role) {if (!userService.exists(id)) {return ResponseEntity.notFound().build();}userService.addRole(id, role.getId());return ResponseEntity.ok().build();}
}
4.2 统一响应格式
/*** 统一响应格式*/
public class ApiResponse<T> {private int code;private String message;private T data;private long timestamp;public static <T> ApiResponse<T> success(T data) {ApiResponse<T> response = new ApiResponse<>();response.setCode(200);response.setMessage("success");response.setData(data);response.setTimestamp(System.currentTimeMillis());return response;}public static <T> ApiResponse<T> error(int code, String message) {ApiResponse<T> response = new ApiResponse<>();response.setCode(code);response.setMessage(message);response.setTimestamp(System.currentTimeMillis());return response;}// getter/setter...
}/*** 使用统一响应格式的Controller*/
@RestController
@RequestMapping("/api/v2/users")
public class UserApiController {@GetMappingpublic ApiResponse<List<User>> getUsers() {List<User> users = userService.findAll();return ApiResponse.success(users);}@GetMapping("/{id}")public ApiResponse<User> getUser(@PathVariable Long id) {User user = userService.findById(id);if (user == null) {return ApiResponse.error(404, "用户不存在");}return ApiResponse.success(user);}@PostMappingpublic ApiResponse<User> createUser(@Valid @RequestBody User user) {try {User createdUser = userService.save(user);return ApiResponse.success(createdUser);} catch (Exception e) {return ApiResponse.error(500, "创建用户失败:" + e.getMessage());}}
}
5. 小结
本文深入介绍了SpringMVC的请求处理和控制器使用:
- 请求处理流程:从请求接收到响应返回的完整过程
- 请求映射:@RequestMapping及其组合注解的使用
- 参数绑定:各种参数绑定方式和复杂对象绑定
- 数据传递:Model、Session、重定向等数据传递机制
- RESTful设计:符合REST规范的API设计
掌握SpringMVC请求处理的关键点:
- 理解请求映射的各种配置方式
- 熟练使用各种参数绑定注解
- 正确选择数据传递方式
- 设计符合RESTful规范的API
- 处理好重定向和转发的使用场景
🔗 下一篇预告
下一篇文章将介绍SpringMVC数据绑定与验证,学习如何进行数据验证和类型转换。
相关文章:
- 上一篇:SpringMVC框架概述与工作原理
- 下一篇:SpringMVC数据绑定与验证
- 返回目录