
目录1.介绍一下org.springframework.ui.Model1. 本质与实现原理2. 示例代码2.被RequestMapping标注的类的方法参数3.BindingResult / Errors 必须紧跟在被校验的实体参数后面(代码说明)正确代码错误代码1.介绍一下org.springframework.ui.Modelorg.springframework.ui.Model是 Spring MVC 框架中极其核心的接口它的主要作用是在控制器Controller和视图View之间建立数据传递的桥梁。简单来说当你在后端处理完业务逻辑后需要将数据如用户信息、列表送到前端页面如 JSP、Thymeleaf显示Model就是那个用来装数据的“容器”。1. 本质与实现原理本质它是一个增强版的MapString, Object。你可以向其中添加 Key-Value 键值对。实际实现类在 Spring MVC 运行时我们直接使用的Model接口对象的实际实现类通常是BindingAwareModelMap它继承自ModelMap而ModelMap又继承自LinkedHashMap。存储位置当你调用model.addAttribute()时数据最终会被放入HttpServletRequest的attributes属性域中。因此它的作用域是Request 级别一次请求有效。2. 示例代码package com.example.controller; // 假设包名根据实际情况修改 import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; // 自定义的业务类和实体类根据项目实际包路径导入 import com.example.service.UserService; import com.example.entity.User; Controller RequestMapping(/api/user) // 类级别定义基础路径 public class UserController { // 模拟业务服务 private UserService userService new UserService(); // 方式一method RequestMethod.GET —— 查询用户详情 RequestMapping(value /profile, method RequestMethod.GET) public String getUserProfile(RequestParam(id) Long id, Model model) { // 1. 业务数据 User user userService.findById(id); String pageTitle 用户个人中心; // 2. 显式将数据放入 Model推荐视图名清晰 model.addAttribute(userInfo, user); model.addAttribute(title, pageTitle); // 3. 返回视图逻辑名由视图解析器解析如 Thymeleaf 或 JSP return profile; // 对应 /WEB-INF/views/profile.jsp 或 profile.html } // 方式二method RequestMethod.POST —— 新增用户重定向 RequestMapping(value /add, method RequestMethod.POST) public String addUser(ModelAttribute User user, Model model) { // 模拟保存 userService.save(user); // 给 Model 添加提示信息仅在当前请求有效 model.addAttribute(message, 添加成功); // 重定向时Model 中的数据不会带过去需要用 RedirectAttributes return redirect:/api/user/profile?id user.getId(); } }2.被RequestMapping标注的类的方法参数分类参数类型 / 注解作用说明示例代码请求数据提取PathVariable获取 URL 路径中的占位符变量PathVariable Long idRequestParam获取请求参数URL 查询参数或表单参数RequestParam String nameRequestParamrequiredfalse获取非必填参数未传时为 nullRequestParam(requiredfalse) Integer ageRequestParamdefaultValue获取参数未传时使用默认值RequestParam(defaultValue1) int pageRequestBody将请求体JSON/XML绑定到 Java 对象RequestBody User userRequestHeader获取 HTTP 请求头中的值RequestHeader(User-Agent) String uaCookieValue获取 Cookie 中的值CookieValue(JSESSIONID) String jidModelAttribute将请求参数绑定到对象并自动放入 ModelModelAttribute User userMatrixVariable获取矩阵变量/cars;colorredMatrixVariable String color数据输出Model添加键值对数据到 Request 作用域model.addAttribute(key, value)ModelMapModel的实现类用法类似 MapmodelMap.put(key, value)RedirectAttributes重定向时传递数据Flash AttributesredirectAttributes.addFlashAttribute(msg, 成功)验证与错误BindingResult接收Valid校验的结果错误信息Valid RequestBody User user, BindingResult resultErrorsBindingResult的父接口功能相同Errors errorsServlet APIHttpServletRequest获取原生请求对象HttpServletRequest requestHttpServletResponse获取原生响应对象HttpServletResponse responseHttpSession获取当前会话自动创建HttpSession sessionWebRequestSpring 封装的通用请求接口WebRequest webRequestNativeWebRequest更底层的 Web 请求接口NativeWebRequest nativeRequest输入输出流InputStream/Reader获取请求体的原始输入流InputStream inputStreamOutputStream/Writer获取响应的原始输出流OutputStream outputStream安全与上下文Principal获取当前登录用户信息配合 Spring SecurityPrincipal principalLocale获取当前请求的语言区域Locale localeTimeZone获取当前请求的时区TimeZone timeZoneSpring DataPageable分页参数需引入 Spring DataPageable pageable自动解析?page0size10Sort排序参数需引入 Spring DataSort sort自动解析?sortid,desc通用封装HttpEntityT封装整个请求Headers BodyHttpEntityUser entityRequestEntityTHttpEntity的子类带更多请求信息RequestEntityUser requestEntity构建工具UriComponentsBuilder用于构建动态 URLUriComponentsBuilder builder其他可选MultipartFile接收上传的文件需搭配RequestParamRequestParam MultipartFile fileBindingAwareModelMapModel的具体实现类较少直接用BindingAwareModelMap modelMapModelAttributeSessionAttributes配合 Session 使用的属性类上标注SessionAttributes方法参数直接用ModelAttribute取特别提醒BindingResult/Errors必须紧跟在被校验的实体参数后面否则校验异常会直接抛出无法进入方法体。Pageable和Sort需要引入 Spring Data 相关依赖才能使用。以上参数可以任意组合顺序基本自由除了BindingResult必须紧跟被校验对象。3.BindingResult / Errors 必须紧跟在被校验的实体参数后面(代码说明)正确代码RestController RequestMapping(/api/user) public class UserController { PostMapping(/register) public String register( // 1. 被校验的实体 Valid RequestBody User user, // 2. BindingResult 必须紧跟其后中间不能插入任何其他参数 BindingResult result, // 3. 其他参数可以放在 BindingResult 后面 HttpSession session) { // 校验是否有错误 if (result.hasErrors()) { // 获取所有错误信息并返回 String errors result.getAllErrors() .stream() .map(ObjectError::getDefaultMessage) .collect(Collectors.joining(, )); return 校验失败 errors; } // 业务逻辑只有校验通过才会执行到这里 userService.register(user); session.setAttribute(userId, user.getId()); return 注册成功; } }错误代码PostMapping(/register) public String register( Valid RequestBody User user, // 错误中间插入了 HttpSession 参数 HttpSession session, // ← 这里插入了其他参数打断了顺序 BindingResult result) { // ← 没有紧跟被校验对象 // 即使这里有 if(result.hasErrors())也永远不会执行到这里 if (result.hasErrors()) { return 校验失败; } // 业务逻辑... return 注册成功; }