# MySpringMVC-Learning **Repository Path**: han-cheese/my-spring-mvc-learning ## Basic Information - **Project Name**: MySpringMVC-Learning - **Description**: SpringMVC学习代码及笔记,学习课程:动力节点SpringMVC - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2024-07-27 - **Last Updated**: 2025-06-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Spring MVC框架:课堂笔记(只记重点) @Weiney ## 1. 第一个Spring MVC程序的开发流程 ### 1.1 创建Maven模块 * 第一步:创建一个空的工程springmvc * 第二步:设置JDK版本 * 第三步:设置Maven * 第四步:创建Maven模块(我这里创建的是一个普通的Maven模块) * 第五步:在pom文件中设置打包方式:war * 第六步:引入依赖: * springmvc依赖 * logback依赖 * thymeleaf和spring6整合依赖 * servlet依赖(scope设置为provided,表示这个依赖最终由第三方容器来提供。) ### 1.2 给Maven模块添加web支持 * 在模块下的src\main目录下新建 webapp目录(默认是带有小蓝点的,没有小蓝点,自己添加Web支持就有小蓝点了。) 另外,在添加web支持的时候,需要添加web.xml文件,注意添加的路径。 ### 1.3 在Web.xml文件中配置前端控制器 * 前端控制器:SpringMVC框架中内置的一个类(DispatcherServlet),所有的请求都应该经过这个DispatcherServlet的处理。 * 重点:/ * 这里的 / 表示:除xx.jsp结尾的请求路径之外的所有请求路径。 * 也就是说,只要不是JSP请求路径,那么一定会走DispatcherServlet。 ### 1.4 编写FirstController * 在类上标注 @Controller 注解,纳入IoC容器的管理。 * 当然,也可以采用 @Component注解进行标注。 @Controller 只是 @Component 注解的别名。 ### 1.5 配置/编写 SpringMVC框架自己的配置文件 * 这个配置文件有默认的名字:-servlet.xml * 这个配置文件有默认的存放位置:WEB-INF 目录下。 * 两个配置: * 第一个:配置组件扫描 * 第二个:配置视图解析器 ### 1.6 提供视图 * 在/WEB-INF/templates目录下新建 first.thymeleaf 文件 * 在该文件中编写符合 Thymeleaf 语法格式的字符串(编写Thymeleaf的模板语句) ### 1.7 提供请求映射 ```java @Controller public class FirstController { // 请求映射 @RequestMapping("/test") public String test(){ // 逻辑视图名称,DispatcherServlet根据视图解析器会为其加上前缀、后缀形成物理视图名称:/WEB-INF/templates/first.thymeleaf return "first"; } } ``` * 最终会将逻辑视图名称转换为物理视图名称: * 逻辑视图名称:first * 物理视图名称:前缀 + first + 后缀 * 最终路径是:/WEB-INF/templates/first.thymeleaf * 使用Thymeleaf模板引擎,将/WEB-INF/templates/first.thymeleaf转换成html代码,最终响应给浏览器。 ### 1.8 测试 * 配置Tomcat10服务器 * 启动Tomcat服务器,在浏览器地址栏上直接发送请求:http://localhost:8888/springmvc/test ## 2. Spring MVC中的配置文件,名字是可以指定的,位置也是可以指定的,怎么指定? * 设置DispatcherServlet的初始化参数: ``` xml contextConfigLocation classpath:springmvc.xml ``` * 建议,在web服务器启动的时候,初始化DispatcherServlet,这样用户第一次发送请求时,效率较高。体验好。 * 1 ## 3. @RequestMapping注解可以出现在类上,也可以出现在方法上,例如: ``` java @Controller @RequestMapping("/a") public class UserController{ @RequestMapping("/b") public String index(){ return "index"; } } ``` * 前端浏览器发送的请求路径是 /a/b 的时候,则执行UserController#index()方法。 ## 4. 关于 @RequestMapping 注解的value属性 * value属性本身是一个 String[] 字符串数组,说明多个请求路径可以映射同一个处理器方法。 * 如果注解的属性是数组,并且在使用注解的时候,该数组中只有一个元素,大括号可以省略。 * 如果使用某个注解的时候,如果只使用了一个value属性,那么value也是可以省略的。 * value属性的别名是path。 * path属性的别名是value。 ## 5. RequestMapping的value属性支持Ant风格的,支持模糊匹配的路径 * ?表示任意一个字符,除"/","?"等特殊字符,注意:一定是一个字符哦。不能空着。 * *表示0到N个任意字符,除"/","?"等特殊字符。 * **表示0到N个任意字符。并且路径中可以出现 / * 但是 ** 在使用的时候需要注意,** 左边只能是 /。 * 注意: * 如果使用Spring5以及之前的版本,这样写是没问题的:@RequestMapping(value = "/**/testAntValue") * 如果使用Spring6以及之后的版本,这样写是报错的:@RequestMapping(value = "/**/testAntValue") * 在Spring6当中,** 通配符只能作为路径的末尾出现。 ## 6. 关于@RequestMapping注解的value属性上的占位符(重点) * 传统的URL: * /springmvc/login?username=admin&password=123 * 现在的开发比较流行使用RESTFul风格的URL: * /springmvc/login/admin/123 * 在SpringMVC当中,如果请求的URL使用的是RESTFul风格的,那么这个数据应该在java程序中如何获取呢?使用占位符方式。 ```java @Controller public class IndexController{ @RequestMapping(value = "/login/{a}/{b}") public String testRESTFulURL( @PathVariable("a") String username, @PathVariable("b") String password){ System.out.println("用户名:" + username + ",密码:" + password); return "ok"; } } ``` ## 7. 关于@RequestMapping注解的method属性,通过该属性可以限制前端发送的请求方式。如果前端发送的请求方式与后端的处理方式不同,则出现405错误 ```java @Controller public class UserController{ @RequestMapping(value="/user/login", method=RequestMethod.POST) public String userLogin(){ return "ok"; } } ``` * 表示:当前端发送的请求路径是 /user/login,并且请求方式是POST的时候,才能映射到 UserController#userLogin()方法上。 * 只要有一个不满足,则无法映射。例如:请求路径对应不上,或者请求方式对应不上,都是无法映射的。 ## 8.衍生Mapping * @PostMapping 注解代替的是:@RequestMapping(value="", method=RequestMethod.POST) * @GetMapping 注解代替的是:@RequestMapping(value="", method=RequestMethod.GET) * .... * @PutMapping * @DeleteMapping * @PatchMapping ## 9.web的请求方式 * 比较常用的: * GET POST PUT DELETE HEAD * GET:适合查询 * POST:适合新增 * PUT:适合修改 * DELETE:适合删除 * HEAD:适合获取响应头信息。 * 注意:使用form表单提交时,如果method设置为 put delete head,对不起,发送的请求还是get请求。 * 如果要发送put delete head请求,请发送ajax请求才可以。 ## 10. 关于 RequestMapping注解的 params 属性 ```java @RequestMapping(value="/testParams", params={"username", "password"}) public String testParams(){ return "ok"; } ``` * 当RequestMapping注解中添加了params,则表示又添加了新的约束条件。 * 当请求路径是 /testParams,并且请求携带的参数有 username 和 password的时候,才能映射成功! * 关于thymeleaf中怎么发送请求的时候携带数据: ```html ``` ## 11. 关于RequestMapping注解的headers属性: * 也是一个数组。用来设置请求头的映射。 ```java public class IndexController{ @RequestMapping(value="/login", headers={"Referer", "Host"}) public String testHeaders(){ return "ok"; } } ``` * 当请求路径是 /login,并且请求头中包含 Referer,也包含Host的时候,映射成功。 ## 12. 获取请求提交的数据 ### 12.1 第一种方式使用原生的Servlet API * 在处理器的方法参数上提供:HttpServletRequest * SpringMVC框架会自动将Tomcat服务器创建request对象传递给处理器方法。 * 我们直接在处理器方法中使用request对象即可。 * 当然,HttpServletResponse,HttpSession有需要的话,也可以采用这种方式注入。 ### 12.2 第二种方式:使用SpringMVC框架提供的一个注解: @RequestParam(请求参数) * @RequestParam注解中的属性: * value属性:value属性可以使用name属性代替 * name属性:name属性可以已使用value属性代替 * required属性:用来设置该参数是否为必须的。默认值是true。默认情况下这个参数是必须要传递过来的。如果前端没有提交这个参数,报错:400错误。 * 这个属性有点类似于 @RequestMapping 注解中的 params 属性的作用。 ``` java @RequestMapping(value="/testParams", params={"username", "password"}) public String testParams(){ return "ok"; } ``` * required属性可以设置为false,这样这个参数就不是必须的了。如果前端没有提供,则不会报400错误。但是由于前端没有提供这个数据,因此程序中的变量值为null * defaultValue属性:通过defaultValue属性可以给参数赋默认值。如果前端没有提供这样的参数,参数的默认值就起作用了。 ### 12.3 第三种方式:依靠控制器方法上的形参名来接收 * 如果 请求参数名 和 控制器方法上的形参名 保持一致,那么 @RequestParam注解可以省略。 * 如果你使用的是Spring6+版本,则需要在pom.xml文件中添加如下编译配置:(Spring5以及之前的版本不需要。) ``` xml org.apache.maven.plugins maven-compiler-plugin 3.12.1 21 21 -parameters ``` * 注意:如果 控制器方法上的形参名 和 请求参数名 没有对应上,那么控制器方法中的形参默认值是null。 ### 12.4 第四种方式:使用POJO类/JavaBean接收请求参数(这是最常用的) * 底层实现原理:反射机制。 * 不过,使用这种方式的前提是:POJO类的属性名必须和请求参数的参数名保持一致 * 实现原理是什么? * 假设提交了一个请求,参数名是 username,那么要求POJO类当中必须有一个属性名也叫做:username ``` java Class clazz = Class.forName("com.powernode.springmvc.pojo.User"); User user = (User)clazz.newInstance(); String fieldName = "username"; String setMethodName = "setUsername"; Method setMethod = clazz.getDeclaredMethod(setMethodName, ....); setMethod.invoke(user, "zhaoliu"); ``` * 重点:底层通过反射机制调用set方法给属性赋值的。所以set方法的方法名非常重要。 * 如果前端提交了参数是: username=zhangsan * 那么必须保证POJO类当中有一个方法名叫做:setUsername * 如果前端提交了参数是: email=zhangsan@powernode.com * 那么必须保证POJO类当中有一个方法名叫做:setEmail * 如果没有对应的set方法,将无法给对应的属性赋值。 ## 13. 获取请求头信息? * 使用 @RequestHeader 注解,它用来标注 形参。作用是:将 请求头信息 映射到 控制器方法的形参 上。 ``` java @PostMapping("/user/reg") public String register(User user, @RequestHeader(value = "Referer", required = false, defaultValue = "") String referer){ System.out.println(user); System.out.println(referer); return "ok"; } ``` ## 14. 获取客户端提交的Cookie? * 使用 @CookieValue 注解标注控制器方法上的形参。 ``` java @RequestMapping("/user/reg") public String register(User user, @CookieValue(value = "id", required = false, defaultValue = "") String id){ System.out.println("客户端提交过来的cookie,它的值是:" + id); return "ok"; } ``` ## 15. 关于javaweb项目中,get请求的乱码问题? * get请求,提交的数据是在浏览器的地址栏上回显。在请求行上提交数据,例如:/springmvc/login?username=张三&password=123 * 怎么解决get请求乱码问题呢? * 对URI进行编码设置,在哪儿可以设置URI的编码方式呢?在Tomcat服务器的配置CATALINA_HOME/conf/server.xml文件中: ``` xml ``` * 对于Tomcat10和Tomcat9来说:get请求没有乱码。也就是说Tomcat10或者Tomcat9已经自动对URI进行编码,并且默认的编码方式就是UTF-8 * 但是对于Tomcat8来说,URIEncoding的默认值是ISO-8859-1编码方式,所以在Tomcat8中,get请求是存在中文乱码问题的,怎么解决?如上所描述。 ## 16. 关于javaweb项目中,post请求的乱码问题? * post请求乱码如何解决? * request.setCharacterEncoding("UTF-8"); * 但是有一个前提: request.setCharacterEncoding("UTF-8"); 这一行代码必须在 String username = request.getParameter("username"); 方法执行之前执行,才有效。 *在Tomcat10当中,我们是不需要考虑post请求乱码问题,因为Tomcat10,已经自动帮助我们执行了: request.setCharacterEncoding("UTF-8"); *在哪里可以看到呢? * 在CATALINA_HOME/conf/web.xml文件中有这样的配置: * UTF-8 * UTF-8 * 这个配置信息表示:请求体采用UTF-8的方式,另外响应的时候也采用UTF-8的方式,所以POST请求无乱码,响应也没有乱码。 * 注意了:对于Tomcat9以及之前的版本来说,没有以上的配置。POST请求乱码问题,响应的乱码问题都需要自行解决。 * 那么如果遇到Tomcat9- 版本,那么POST请求乱码应该怎么解决呢?对于SpringMVC来说,有什么好的办法吗? * 在 request.getParameter() 方法执行之前,执行: request.setCharacterEncoding("UTF-8"); ,这样问题就能解决。 * 第一种方案:自己编写一个过滤器!!!!过滤器Filter在Servlet执行之前执行。 * 第二种方案:使用SpringMVC框架内置的字符编码过滤器即可:CharacterEncodingFilter。 ## 17. request域: * 第一种方式:在SpringMVC中使用原生的Servlet API可以完成request域数据共享: * 在处理器方法上添加 HttpServletRequest参数即可。 * 第二种方式:在SpringMVC的处理器方法的参数上添加一个接口类型:Model ``` java @RequestMapping("/testModel") public String testModel(Model model){ // 向request域当中存储数据 model.addAttribute("name", value); // 转发 return "ok"; } ``` * MVC架构模式: * M: Model(模型,本质就是数据) * V: View * C: Controller * 第三种方式:在SpringMVC的处理器方法的参数上添加一个接口类型:Map ``` java @RequestMapping("/testMap") public String testMap(Map map){ // 向request域当中存储数据 map.put("testRequestScope", "在SpringMVC当中使用Map接口完成request域数据共享"); // 转发 return "ok"; } ``` * 第四种方式:在SpringMVC的处理器方法的参数上添加一个类型:ModelMap ``` java @RequestMapping("/testModelMap") public String testModelMap(ModelMap modelMap){ // 向request域当中存储数据 modelMap.addAttribute("testRequestScope", "在SpringMVC当中使用ModelMap类完成request域数据共享"); // 转发 return "ok"; } ``` * 研究一下:Model接口、Map接口、ModelMap类,三者之间的关系? * 表面上使用的是不同的接口和不同的类。实际上底层都使用了同一个对象:org.springframework.validation.support.BindingAwareModelMap * BindingAwareModelMap继承了ExtendedModelMap类 * ExtendedModelMap继承了ModelMap类 * ExtendedModelMap实现了Model接口 * ModelMap类继承了LinkedHashMap继承了HashMap实现了Map接口 * 第五种方式:使用Spring MVC框架提供的ModelAndView类完成request域数据共享。 ``` java @RequestMapping("/testModelAndView") public ModelAndView testModelAndView(){ // 创建 模型视图 对象 ModelAndView mav = new ModelAndView(); // 给 模型视图对象 绑定数据 mav.addObject("testRequestScope", "在SpringMVC当中使用ModelAndView类完成request域数据共享"); // 给 模型视图对象 绑定视图(绑定逻辑视图名称) mav.setViewName("ok"); // 返回 模型视图对象 return mav; } ``` * 我们聊一个真相: * 对于处理器方法来说,不管你使用的参数是Model接口,还是Map接口,还是ModelMap类,还是ModelAndView类,最终处理器方法执行结束之后, * 返回的都是ModelAndView对象。这个返回的ModelAndView对象给DispatcherServlet类了。 * 当请求路径不是JSP的时候,都会走前端控制器DispatcherServlet。 * DispatcherServlet中有一个核心方法 doDispatch(),这个方法用来通过请求路径找到对应的 处理器方法 * 然后调用 处理器方法,处理器方法返回一个逻辑视图名称(可能也会直接返回一个ModelAndView对象) * 底层会将逻辑视图名称转换为View对象,然后将View对象结合Model对象,封装一个ModelAndView对象,然后将该对象返回给DispatcherServlet类了。 ## 18. session域 * 第一种方式:使用原生的Servlet API实现。(在处理器方法的参数上添加一个 HttpSession 参数,SpringMVC会自动将session对象传递给这个参数。) * 第二种方式:使用@SessionAttributes注解标注Controller ## 19. application域 * 这个域使用较少,如果使用的话,一般是采用ServletAPI的方式使用。 ``` java @RequestMapping("/testApplicationScope") public String testApplicationScope(HttpServletRequest request){ ServletContext application = request.getServletContext(); application.setAttribute("testApplicationScope", "在SpringMVC中使用ServletAPI实现application域共享"); return "ok"; } ``` ## 20. SpringMVC中常用的视图: * InternalResourceView:内部资源视图(是SpringMVC内置的,专门负责解析JSP模板语法的,另外也负责 转发forward 功能的实现) * RedirectView:重定向视图(是SpringMVC内置的,专门负责 重定向redirect 功能的实现) * ThymeleafView:Thymeleaf视图(是第三方的,专门负责解析Thymeleaf模板语法的) * ...... ## 21. 实现视图机制的核心类与核心接口 * 1. DispatcherServlet:前端控制器 * 负责接收前端的请求 (/login) * 根据请求路径找到对应的处理器方法 (UserController#login()) * 执行处理器方法 (执行 UserController#login()) * 并且最终返回ModelAndView对象。 * 再往下就是处理视图。 * 2. ViewResolver接口:视图解析器接口 (ThymeleafViewResolver实现了ViewResolver接口、InternalResourceViewResolver也是实现了ViewResolver接口....) * 这个接口做什么事儿? * 这个接口作用是将 逻辑视图名称 转换为 物理视图名称。 * 并且最终返回一个View接口对象。 * 核心方法是什么? * View resolveViewName(String viewName, Locale locale) throws Exception; * 3. View接口:视图接口 (ThymeleafView实现了View接口、InternalResourceView也实现了View接口.....) * 这个接口做什么事儿? * 这个接口负责将模板语法的字符串转换成html代码,并且将html代码响应给浏览器。(渲染。) * 核心方法是什么? * void render(@Nullable Map model, HttpServletRequest request, HttpServletResponse response) throws Exception; ## 22. 在SpringMVC中是怎么通过代码完成转发的?怎么完成重定向的? * 代码 ``` java @Controller public class ForwardController{ @RequestMapping("/a") public String toA(){ // 返回的是一个逻辑视图名称 return "a"; } } ``` * 注意:当 return "a"; 的时候,返回了一个逻辑视图名称。这种方式跳转到视图,默认采用的就是 forward 方式跳转过去的。只不过这个底层创建的视图对象:ThymeleafView * 怎么转发?语法格式是什么呢? * return "forward:/b"; 转发到 /b,这是一次请求,底层创建的视图对象是:InternalResourceView对象。 * "forward:/b" 这个已经不是逻辑视图名称了。是以转发的方式跳转,是一个资源的路径。不能随便写,以 forward: 开始。 * 怎么重定向?语法格式是什么呢? * return "redirect:/b"; 转发到 /b,这是两次请求,底层创建的视图对象是:RedirectView对象。 * 注意语法:必须以 redirect: 开始。 * 总结: * 转发: return "forward:/b" 底层创建的是InternalResourceView对象 * 重定向: return "redirect:/b" 底层创建的是RedirectView对象 ## 23. * 这个配置信息,可以在springmvc.xml文件中进行配置,作用是什么? * 如果一个Controller上的方法只是为了完成视图跳转,没有任何业务代码,那么这个Controller可以不写。 * 直接在 springmvc.xml 文件中添加标签mvc:view-controller即可。 * * 表示发送的请求路径是 /test,跳转的视图页面是: 前缀+test+后缀 ## 24. * 这个配置信息叫做开启注解驱动。在springmvc.xml文件中配置。 * 当你使用了 配置,会让你整个项目中所有的注解全部失效,你需要使用以上的配置来再次开启注解。 * ## 25. 关于静态资源处理: * 假设我们在webapp目录下有static目录,static目录下有image01.png图片。 * 我们可以在浏览器地址栏上直接访问:http://localhost:8080/springmvc/static/img/image01.png 吗?不行。 * 因为会走DispatcherServlet,导致发生404错误。 * 怎么办?两种解决方案: * 第一种解决方案:开启默认的Servlet处理 * 在Tomcat服务器中提供了一个默认的Servlet,叫做:org.apache.catalina.servlets.DefaultServlet * 在CATALINA_HOME/conf/web.xml文件中,有这个默认的Servlet的相关配置。 * 不过,这个默认的Servlet默认情况下是不开启的。 * 你需要在springmvc.xml文件中使用以下配置进行开启: * * * 开启之后的作用是,当你访问 http://localhost:8080/springmvc/static/img/image01.png的时候, * 默认先走 DispatcherServlet,如果发生404错误的话,会自动走DefaultServlet,然后DefaultServlet * 帮你定位静态资源。 * 第二种解决方案:配置静态资源处理,在springmvc.xml文件中添加如下配置: * * * 当请求路径符合 /static/** 的时候,去 /static/ 位置找资源。 ## 26. 什么是RESTFul? * RESTful是对WEB服务接口的一种设计风格,提供了一套约束,可以让WEB服务接口更加简洁、易于理解。 * REST对请求方式的约束是这样的: * 查询get * 新增POST * 删除delete * 修改put * REST对URL的约束是这样的: * GET /user/1 查一个 * GET /user 查所有 * POST /user 新增 * PUT /user 修改 * DELETE /user/1 删除 * RESTful:是表述性状态转移。 * 本质上:通过 URL + 请求方式 来控制服务器端数据的变化。 ## 27. RESTful编程风格中要求,修改的时候,必须提交PUT请求,怎么提交PUT请求呢? * 第一步:要想发送PUT请求,首先你必须是一个POST请求。(POST请求是大前提) * 第二步:在POST请求的表单中添加隐藏域: ``` html ``` * 强调:name必须是 _method,value必须是put/PUT。 * 如果你要发送delete请求的话,value写delete即可。 * 第三步:添加一个过滤器 ``` xml hiddenHttpMethodFilter org.springframework.web.filter.HiddenHttpMethodFilter hiddenHttpMethodFilter /* ``` ## 28. 在SpringMVC中如何使用原生ServletAPI完成AJAX请求的响应? ``` java @GetMapping("/ajax") public void ajax(HttpServletResponse response) throws IOException { PrintWriter out = response.getWriter(); out.print("hello ajax, my name is Spring MVC2!"); } @GetMapping("/ajax") public String ajax(HttpServletResponse response) throws IOException { PrintWriter out = response.getWriter(); out.print("hello ajax, my name is Spring MVC!"); return null; } ``` ## 29. @ResponseBody 注解(非常重要,使用非常多,因为以后大部分的请求都是AJAX请求) ``` java @GetMapping("/ajax") @ResponseBody public String ajax(){ return "hello ajax, my name is Spring MVC!"; } ``` * 重点:一旦处理器方法上添加了 @ResponseBody 注解,那么 return 返回语句,返回的将不是一个 “逻辑视图名称” 了。而是直接将返回结果采用字符串的形式响应给浏览器。 * 底层实现原理实际上代替的就是: * PrintWriter out = response.getWriter(); * out.print("hello ajax, my name is Spring MVC!"); * 以上程序使用的HTTP消息转换器是:StringHttpMessageConverter。 ``` java @GetMapping("/ajax") @ResponseBody public User ajax() { User user = new User(111222L, "zhangsan", "123"); return user; } ``` * 当一个处理器方法上面有 @ResponseBody注解,并且返回的是一个java对象,例如user,那么springmvc框架,会自动将user对象转换成json格式的字符串,响应给浏览器。 * 当然,你必须要在pom.xml文件中引入一个可以处理json的依赖,例如jackson: ``` xml com.fasterxml.jackson.core jackson-databind 2.17.0 ``` * 以上程序中使用的消息转换器是:MappingJackson2HttpMessageConverter ## 30. 非常好用的注解:@RestController * 它出现在类上。等于 @Controller + @ResponseBody * @RestController 它是一个复合注解。 * 当一个类上添加 @RestController 注解之后,表示该类上自动添加了 @Controller注解,并且该类中所有的方法上都会自动添加 @ResponseBody 注解。 ## 31. 关于 @RequestBody 注解 * 该注解只能使用在处理器方法的形参上。 * 这个注解的作用是直接将请求体传递给Java程序,在Java程序中可以直接使用一个String类型的变量接收这个请求体的内容。 * 底层使用的HTTP消息转换器是:FormHttpMessageConverter * 关于@RequestBody 注解的重要用法:如果前端请求体当中提交的数据是JSON格式,那么 @RequestBody 可以将提交的JSON格式的字符串转换成java对象。 * 注意:同样需要使用jackson的依赖。 ``` xml com.fasterxml.jackson.core jackson-databind 2.17.0 ``` * 然后,要注意@RequestBody标注在处理器方法的形参上,也就是说形参只要准备一个user对象就行了,前端提交一个json字符串,直接将其转换成java对象user * 以上前端请求体提交JSON格式的字符串,那么后端直接将json格式字符串转换成java对象,这里使用的消息转换器是:MappingJackson2HttpMessageConverter ## 32. RequestEntity * 这个类的实例封装了整个请求协议。 * SpringMVC自动创建好,传递给处理器方法的参数上。 * 你只需要在处理器方法的参数上加上: (RequestEntity requestEntity)即可,SpringMVC自动创建好该对象,传递到处理器方法的参数上。 * 通过它可以获取请求协议中任何信息,包括:请求方法、请求头、请求体。 ## 33. ResponseEntity * ResponseEntity不是注解,是一个类。用该类的实例可以封装响应协议,包括:状态行、响应头、响应体。也就是说:如果你想定制属于自己的响应协议,可以使用该类。 * 注意:如果你要定制属于自己的响应协议,那么处理器方法的返回值类型必须是:ResponseEntity,泛型为什么是User,因为响应体中的内容是user信息。 ## 34. 文件上传 * 文件上传必须是post请求。 * 文件上传的form标签中必须使用 enctype="multipart/form-data" * enctype是用来设置请求头的内容类型的。默认值是:enctype="application/x-www-form-urlencoded" * 文件上传的组件是:`` *注意:如果你用的是spring6,那么需要在web.xml文件的DispatcherServlet中进入如下的配置: ``` xml 102400 102400 0 ``` * 文件上传:浏览器端向服务器端发送文件,最终服务器将文件保存到服务器上。(本质上还是IO流,读文件和写文件。) * SpringMVC专门为文件上传准备了一个类:MultipartFile multipartFile. * 这个类怎么理解?这个类就代表你从客户端传过来的那个文件。 * multipartFile.getName(); 获取请求参数的name * multipartFile.getOriginalFilename(); 获取文件的真实名字 ## 35. 文件下载,代码非常固定 ``` java @GetMapping("/download") public ResponseEntity downloadFile(HttpServletRequest request) throws IOException { File file = new File(request.getServletContext().getRealPath("/upload") + "/touxiang.jpeg"); // 创建响应头对象 HttpHeaders headers = new HttpHeaders(); // 设置响应内容类型 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); // 设置下载文件的名称 headers.setContentDispositionFormData("attachment", file.getName()); // 下载文件 return new ResponseEntity(Files.readAllBytes(file.toPath()), headers, HttpStatus.OK); } ```