• SpringMVC入门宝典(四)SpringMVC注解(上)


    目录

    一.@Controller

    二.@RequestMapping

    三.@RequestParam

    四.@RequestHeader、@CookieValue

    五.@SessionAttributes

    六.@ModelAttribute

    七.RESTful风格支持

    1.RESTful风格介绍

    2.Postman使用

    3.@PathVariable 

    4.@PostMapping、@GetMapping、@PutMapping、 @DeleteMapping

    5.HiddentHttpMethodFilter


    SpringMVC 通过注解来实现控制器的功能,接下来我们详细学习SpringMVC 的常用注解。

    一.@Controller

    作用:标记控制器,将控制器交给 Spring 容器管理。
    位置:类上方
    即在控制类上方标记之后,会将此控制类的一个对象在Spring容器中创建,Spring章节已经学过,不再多说。

    二.@RequestMapping

    作用:给控制器方法设置请求路径
    位置:方法或类上方。用于类上,表示类中的所有控制器方法都是以该地址作为父路径(父路路径和子路径组合就是一个完整路径)。
    属性:
    • value/path:请求路径 (当不写其他属性时,可以不写value或path,如上篇文章那样)
    • method:指定请求方式
    • params:规定必须发送的请求参数
    • headers:规定请求必须包含的请求头

    在contrller包下创建MyController3控制类

    父路径是/c3,子路径是/annotation1,所以函数annotation1的路径是/c3/annotation1

    1. package com.first.controller;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.web.bind.annotation.RequestMapping;
    4. import org.springframework.web.bind.annotation.RequestMethod;
    5. @Controller
    6. @RequestMapping("/c3")
    7. public class MyController3 {
    8. /*
    9. 访问路径为 /c3/annotation1
    10. 支持post和get请求
    11. 请求时必须带有age参数
    12. 请求时必须带有User-agent请求头
    13. */
    14. @RequestMapping(value = "/annotation1",
    15. //get和post都写进来表示get或post都行
    16. method = {RequestMethod.GET,RequestMethod.POST},
    17. //规定必须发送的请求参数
    18. params = {"username"},
    19. //规定请求必须包含的请求头
    20. headers = {"User-agent"})
    21. public String annotation1(String username){
    22. System.out.println(username);
    23. //会跳转到http://localhost:8080/first.jsp
    24. return "first";
    25. }
    26. }

    输出:访问http://localhost:8080/c3/annotation1?username=kd

    且控制台输出kd

    三.@RequestParam

    作用:在控制器方法中获取请求参数
    位置:方法参数前
    属性:
    • name:指定请求参数名称
    • defaultValue: 为参数设置默认值
    • required:设置是否是必须要传入的参数

    在前面咱们已经知道如果方法的参数和请求参数名称一致的话,那么SpringMVC可以自动进行对应封装,就像上面那个函数一样,如果不一致的情况下还想封装的话就得用RequestParam。

    1. /*
    2. 定义请求的参数名为username,默认值为"默认名",不是必须的参数(即url不传参也不会报错)
    3. */
    4. @RequestMapping("/annotation2")
    5. public String annotation2(@RequestParam(name = "username",defaultValue = "默认名",required = false) String name){
    6. System.out.println(name);
    7. //跳转到first.jsp
    8. return "first";
    9. }

    访问http://localhost:8080/c3/annotation2,输出:

    控制台输出:

    默认名

    访问http://localhost:8080/c3/annotation2?username=kd

    控制台输出:kd

    四.@RequestHeader、@CookieValue

    @RequestHeader
    作用:在控制器方法中获取请求头数据
    位置:方法参数前
    @CookieValue
    作用:在控制器方法中获取 Cookie 数据
    位置:方法参数前
    1. /*
    2. 获取User-Agent请求头
    3. 获取JSESSIONID的Cookie值
    4. */
    5. @RequestMapping("/annotation3")
    6. public String annotation3(@RequestHeader("User-Agent") String userAgent, @CookieValue("JSESSIONID") String jSessionId){
    7. System.out.println(userAgent);
    8. System.out.println(jSessionId);
    9. return "first";
    10. }

    控制台输出:

    1. Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0
    2. 247A4659A05334A8CF1C68B77AABF6D1

    五.@SessionAttributes

    作用:将Model模型中的数据存到session域中
    位置:类上方
    创建一个新的控制类MyController4
    1. package com.first.controller;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.ui.Model;
    4. import org.springframework.web.bind.annotation.RequestMapping;
    5. import org.springframework.web.bind.annotation.SessionAttributes;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpSession;
    8. @Controller
    9. @RequestMapping("/c4")
    10. // 将模型中的name数据保存到session中
    11. @SessionAttributes("name")
    12. public class MyController4 {
    13. @RequestMapping("/t1")
    14. public String t1(Model model){
    15. //model中保存name数据
    16. model.addAttribute("name","英语");
    17. return "first";
    18. }
    19. @RequestMapping("/t2")
    20. public String t2(HttpServletRequest request){
    21. System.out.println(request.getAttribute("name"));
    22. return "first";
    23. }
    24. @RequestMapping("/t3")
    25. public String t3(HttpSession session){
    26. System.out.println(session.getAttribute("name"));
    27. return "first";
    28. }
    29. }

    访问http://localhost:8080/c4/t2,控制台输出:

    因为存放在Model中只有同一个request中才能共享数据,所以t2拿不到name

    null

    访问http://localhost:8080/c4/t3,控制台输出:

    英语

    六.@ModelAttribute

    作用1:设置指定方法在控制器其他方法前执行
    位置:方法上方
    创建一个新的控制类MyController5
    1. package com.first.controller;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.web.bind.annotation.ModelAttribute;
    4. import org.springframework.web.bind.annotation.RequestMapping;
    5. @Controller
    6. @RequestMapping("/c5")
    7. public class MyController5 {
    8. @ModelAttribute
    9. public void before(){
    10. System.out.println("前置方法");
    11. }
    12. @RequestMapping("/t1")
    13. public String t1(){
    14. System.out.println("t1");
    15. return "first";
    16. }
    17. }
    控制台输出:
    1. 前置方法
    2. t1
    作用2:从Model模型中获取数据给参数赋值
    位置:方法参数前
    创建一个新的控制类MyController6
    1. package com.first.controller;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.ui.Model;
    4. import org.springframework.web.bind.annotation.ModelAttribute;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. @Controller
    7. @RequestMapping("/c6")
    8. public class MyController6 {
    9. // 前置方法向Model中设置数据
    10. @ModelAttribute
    11. public void before(Model model){
    12. model.addAttribute("name","梦露");
    13. }
    14. // 该参数不是从请求中获取,而是从Model中获取
    15. @RequestMapping("/t1")
    16. public String t1(@ModelAttribute("name") String name){
    17. System.out.println(name);
    18. return "first";
    19. }
    20. }

    输出

     

    梦露

    七.RESTful风格支持

    1.RESTful风格介绍

    RESTful 风格是一种 URL 路径的设计风格。在 RESTful 风格的 URL 路径中,网络上的任意数据都可以看成一个资源,它可以是一段文 本、一张图片,也可以是一个 Java 对象。而每个资源都会占据一个 网络路径,无论对该资源进行增删改查,访问的路径是一致的。

    传统URL

    • 查找id1的学生: http://localhost:8080/student/findById?id=30
    • 删除id1的学生: http://localhost:8080/student/deleteById?id=30

    RESTful风格URL

    • 查找id30的学生: http://localhost:8080/student/30
    • 删除id30的学生: http://localhost:8080/student/30
    那么如何区分对该资源是哪一种操作?通过请求方式不同,判断进行的是什么操作。
    之前我们学过两种请求方式, GET 请求和 POST 请求,而访问RESTful 风格的 URL 一共有四种请求方式:
    • GET请求:查询操作
    • POST请求:新增操作
    • DELETE请求:删除操作
    • PUT请求:修改操作

     RESTful风格URL

    • 查找id30的学生: http://localhost:8080/student/30 GET方式请求
    • 删除id30的学生: http://localhost:8080/student/30 DELETE方式请求
    RESTful 风格的优点 :
    结构清晰、符合标准、易于理解、扩展方便。

    2.Postman使用

    默认情况下浏览器是无法发送 DELETE 请求和 PUT 请求的,我们可以
    使用 Postman 工具发送这些请求。
    1
    1. 双击安装包安装Postman(记的在前端的文章中演示过)
    2. 点击new-collection创建请求集合

    点击New

    选择Collection,可以将常用的访问链接放到此集合下,以后访问直接在此集合下访问就行,方便了很多,不用每次都手动输入url

     为集合起个名

     

     点击加号新增请求

     

    3.@PathVariable 

    作用:在 RESTful 风格的 URL 中获取占位符的值
    位置:方法参数前
    属性:
    • value:获取哪个占位符的值作为参数值,如果占位符和参数名相同,可以省略该属性。
    1. package com.first.controller;
    2. import com.first.domain.Student;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.web.bind.annotation.PathVariable;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. import org.springframework.web.bind.annotation.RequestMethod;
    7. @Controller
    8. @RequestMapping("/student")
    9. // 模拟学生的增删改查控制器
    10. public class StudentController {
    11. // 路径中的{id}表示占位符,最后会封装到方法的参数中使用
    12. // 删除学生
    13. @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
    14. public String deleteStudent(@PathVariable(value = "id") int id){
    15. System.out.println("删除id为"+id+"的学生");
    16. return "first";
    17. }
    18. // 如果占位符和参数名相同,可以省略@PathVariable的value属性
    19. // 根据id查询学生
    20. @RequestMapping(value = "/{id}",method = RequestMethod.GET)
    21. public String findStudentById(@PathVariable int id){
    22. System.out.println(id);
    23. System.out.println("根据id查询学生");
    24. return "first";
    25. }
    26. // 新增学生
    27. @RequestMapping(value = "/{id}",method = RequestMethod.POST)
    28. public String addStudent(@PathVariable int id, Student student){
    29. System.out.println(id);
    30. System.out.println(student);
    31. System.out.println("新增学生");
    32. return "first";
    33. }
    34. // 修改学生
    35. @RequestMapping(value = "/{id}",method = RequestMethod.PUT)
    36. public String updateStudent(@PathVariable int id, Student student){
    37. System.out.println(id);
    38. System.out.println(student);
    39. System.out.println("修改学生");
    40. return "first";
    41. }
    42. }
    访问方式:
    • 新增学生:POST http://localhost:8080/student/1?name=小明&sex=
    • 修改学生:PUT http://localhost:8080/student/1?name=小白&sex=
    • 删除学生:DELETE http://localhost:8080/student/1
    • 查询学生:GET http://localhost:8080/student/1

    使用postman进行测试,点击加号新建一个测试,查询学生为例

     选择请求方式,并输入URL,并Ctrl+S,然后为这个测试命名并选择一个集合,然后保存

     其他三个操作也与此差不多,需要传入参数时就在key和value处添加即可,如新增学生,不过如果写入的地址中有?后面的内容,那么会自动解析到key和value中,如果只写了http://localhost:8080/,那么在key和value中添加值后也会自动添加到url中。

     四个都完成后,看左边会发现集合下有四个测试

     启动服务器,在postman中执行四个测试,idea控制台输出如下:

    1. 1
    2. 根据id查询学生
    3. 删除id1的学生
    4. 1
    5. Student{id=1, name='小明', sex='男', address=null}
    6. 新增学生
    7. 1
    8. Student{id=1, name='小白', sex='男 ', address=null}
    9. 修改学生

    4.@PostMapping、@GetMapping、@PutMapping、 @DeleteMapping

    作用:简化设置请求方式的 @RequestMapping 写法
    位置:方法上方。
    比如上面的方法改造如下:
    1. package com.first.controller;
    2. import com.first.domain.Student;
    3. import org.springframework.stereotype.Controller;
    4. import org.springframework.web.bind.annotation.*;
    5. @Controller
    6. @RequestMapping("/student")
    7. // 模拟学生的增删改查控制器
    8. public class StudentController {
    9. // 路径中的{id}表示占位符,最后会封装到方法的参数中使用
    10. // 删除学生
    11. //@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
    12. @DeleteMapping("/{id}")
    13. public String deleteStudent(@PathVariable(value = "id") int id){
    14. System.out.println("删除id为"+id+"的学生");
    15. return "first";
    16. }
    17. // 如果占位符和参数名相同,可以省略@PathVariable的value属性
    18. // 根据id查询学生
    19. //@RequestMapping(value = "/{id}",method = RequestMethod.GET)
    20. @GetMapping("/{id}")
    21. public String findStudentById(@PathVariable int id){
    22. System.out.println(id);
    23. System.out.println("根据id查询学生");
    24. return "first";
    25. }
    26. // 新增学生
    27. //@RequestMapping(value = "/{id}",method = RequestMethod.POST)
    28. @PostMapping("/{id}")
    29. public String addStudent(@PathVariable int id, Student student){
    30. System.out.println(id);
    31. System.out.println(student);
    32. System.out.println("新增学生");
    33. return "first";
    34. }
    35. // 修改学生
    36. //@RequestMapping(value = "/{id}",method = RequestMethod.PUT)
    37. @PutMapping("/{id}")
    38. public String updateStudent(@PathVariable int id, Student student){
    39. System.out.println(id);
    40. System.out.println(student);
    41. System.out.println("修改学生");
    42. return "first";
    43. }
    44. }

    用postman测试,和上节一样,成功!

    5.HiddentHttpMethodFilter

    由于浏览器 form 表单只支持 GET POST 请求,而 DELETE PUT 请求并不支持, SpringMVC 有一个过滤器,可以将浏览器的 POST 请求 改为指定的请求方式,发送给的控制器方法。
    用法如下:
    1
    (1)在 web.xml 中配置过滤器
    1. <!-- 请求方式过滤器 -->
    2. <filter>
    3. <filter-name>httpMethodFilter</filter-name>
    4. <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    5. </filter>
    6. <filter-mapping>
    7. <filter-name>httpMethodFilter</filter-name>
    8. <!--所有路径都过滤-->
    9. <url-pattern>/*</url-pattern>
    10. </filter-mapping>
    (2)编写控制器方法
    新建一个控制类MyController7
    1. package com.first.controller;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.web.bind.annotation.DeleteMapping;
    4. import org.springframework.web.bind.annotation.PutMapping;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. @Controller
    7. @RequestMapping("/c7")
    8. public class MyController7 {
    9. @DeleteMapping("/delete")
    10. public String testDelete(){
    11. System.out.println("删除方法");
    12. return "first";
    13. }
    14. @PutMapping("/put")
    15. public String testPut(){
    16. System.out.println("修改方法");
    17. return "first";
    18. }
    19. }
    (3)在 jsp 中编写表单
    在webapp下新建一个first2.jsp
    1. <%--
    2. Created by IntelliJ IDEA.
    3. User: ASUS
    4. Date: 2022/6/23
    5. Time: 21:03
    6. To change this template use File | Settings | File Templates.
    7. --%>
    8. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    9. <html>
    10. <head>
    11. <title>DELETE、PUT提交</title>
    12. </head>
    13. <body>
    14. <!-- 删除 -->
    15. <%-- 提交DELETE、PUT请求,表单必须提交方式为post --%>
    16. <%-- 表单中有一个隐藏域,name值为_method,value值为提交方式 --%>
    17. <form action="/c7/delete" method="post">
    18. <input type="hidden" name="_method" value="DELETE">
    19. <input type="submit" value="删除">
    20. </form>
    21. <hr/>
    22. <!-- 修改 -->
    23. <form action="/c7/put" method="post">
    24. <input type="hidden" name="_method" value="PUT">
    25. <input type="submit" value="修改">
    26. </form>
    27. </body>
    28. </html>

    测试,访问 http://localhost:8080/first2.jsp

     点击两个按钮分别输出

    1. 删除方法
    2. 修改方法

    说明post被过滤而成了delete和put。

  • 相关阅读:
    BERT源码实现与解读(Pytorch)
    Linux高并发服务器开发第四章:Linux网络编程
    HTTPS(对称加密+非对称加密+证书)
    三个数之和
    【NodeJs-5天学习】第二天篇④ ——项目模块化
    网络传输方式
    -星号菱形-
    【面试题】js 判断数组中是否有某个值
    HCIP-Datacom OSPF进阶(二)最常用的路由协议 OSPF各种LSA作用详解
    单值二叉树
  • 原文地址:https://blog.csdn.net/weixin_44593822/article/details/125414557