• Spring MVC的常用注解


    目录

    @RequestMapping

    例子:

    @RequestMapping 支持什么类型的请求

            使 @RequestMapping 只支持特定的类型

    @RestController

    通过 HTTP 请求传递参数给后端

    1.传递单个参数

            注意使⽤基本类型来接收参数的情况

    2.传递多个参数

    3.传递对象

    4.@RequestParam 后端参数重命名(修改映射关系)

    5.传递数组

    6.传递集合

    7.传递JSON数据 @RequestBody

    8.获取URL中参数 @PathVariable

    9.上传⽂件 @RequestPart

    10.获取Cookie/Session @CookieValue @SessionAttribute HttpSession

    11.获取Header @RequestHeader


    @RequestMapping

           在 Spring MVC 中使⽤ @RequestMapping 来实现 URL 路由映射,也就是浏览器连接程序的作⽤ ,后面客户端访问服务器时 URL 中就要包含 @RequestMapping 中的参数

            路由映射:当⽤户访问⼀个 URL 时, 将⽤户的请求对应到程序中某个类的某个⽅法的过程就叫路由映射.

    例子:

    1. @RestController
    2. @RequestMapping("/UserController")
    3. public class UserController {
    4. @RequestMapping("/sayHi")
    5. public String sayHi(){
    6. return "hello,Spring";
    7. }
    8. }

            如上的代码,对于类 UserController,@RequestMapping 注解中的参数为 /UserController ,对于方法 sayHi(),@RequestMapping 注解中的参数为 /sayHi ,这就说明,客户端发送的 HTTP 请求要是想访问到 sayHi()这个方法,URL 中的路径就应该有 /UserController/sayHi,假如在本机上访问 URL 就应该为 127.0.0.1:8080/UserController/sayHi

            我们可以看到如下的效果

    @RequestMapping 支持什么类型的请求

            我们知道 HTTP 请求分为 Get,Post 等类型,那 @RequestMapping 注解支持什么类型的 HTTP 请求呢?

            @RequestMapping 支持所有类型的请求,无论 HTTP 请求是 Get 还是 Post 都能够正确的响应

            使 @RequestMapping 只支持特定的类型

            可能我们在开发时有特殊的要求,需要只支持特定类型的 HTTP 请求

    1. @RequestMapping(value = "/sayHi/post",method = RequestMethod.POST)
    2. public String sayHiPost(){
    3. return "hello,Spring,post";
    4. }

            当我们如上所示在 @RequestMapping 注解中设置 method 属性以后就可以使 sayHiPost 方法只处理 Post 类型的请求

            


    @RestController

            同样也用下面这个代码作为例子

    1. @RestController
    2. @RequestMapping("/UserController")
    3. public class UserController {
    4. @RequestMapping("/sayHi")
    5. public String sayHi(){
    6. return "hello,Spring";
    7. }
    8. }

            当我们把类前面的 @RestController 这个注解删掉,会发送什么样的效果呢?

            当我们把 @RestController 注解删掉以后再次通过之前的 URL 访问就发现报了404(找不到系统资源)错误

            因为在一个 Spring MVC 项目中会有很多的类,Spring 如何知道要根据 URL 到哪些类中去寻找对应的方法呢,就是通过 @RestController 注解,只有类加上了 @RestController 注解,Spring 才会去进行访问,查找类中方法的 @RequestMapping 注解是否符合要求 ,才能找到对应的资源

            上面我们把 UserController 类的 @RestController 注解删掉,Spring 在遍历的时候就不会去访问 UserController 类,也就找不到 sayHi()方法,所以浏览器就显示了 404(找不到系统资源)错误


    通过 HTTP 请求传递参数给后端

            传递不同的参数会需要用到不同的注解

    1.传递单个参数

            接收单个参数,在 Spring MVC 中直接⽤⽅法中的参数就可以,⽐如以下代码:

    1. @RequestMapping("/getName")
    2. public String getName(String name){
    3. return "name:"+name;
    4. }

            我们通过浏览器发送一个携带参数的 HTTP 请求查看获取参数的效果

            如上图,我们在 HTTP 请求的 Query String 中携带了 KEY为 name 的键值对,Spring 会自动获取 HTTP 请求中的键值对,将键值对的 KEY 值和方法中的形参名进行对比,要是相同就将 KEY 对应的 VALUE 赋值给形参

            注意使⽤基本类型来接收参数的情况

    1. @RequestMapping("/getAge")
    2. public String getAge(int age){
    3. return "age:"+age;
    4. }

            如上的代码,我们接收 age 用的是 int 类型,假设我们发送的 HTTP 请求没有给 age 传参就会出现下面的情况

            

            同时,在服务器日志中会有以下的报错信息

            意思就是,int 类型的变量不能被置为 null ,因为要是 HTTP 请求访问对应的方法时,没有给方法传参,Spring 就会自动将方法需要的参数设置为 null ,而基本类型是无法设置为 null 的,所以要是在服务器中用基本类型来接收参数的话,HTTP 请求就必须要传参

            当然这是很麻烦的,所以我们通常不用基本类型来接收 HTTP 请求携带的参数,而是用对应的包装类,比如 int 的包装类 Integer

    2.传递多个参数

    和接收单个参数⼀样,直接使⽤⽅法的参数接收即可.使⽤多个形参.

    1. @RequestMapping("/getNameAge")
    2. public String getNameAge(String name,Integer age){
    3. return "name:"+name+" age:"+age;
    4. }

            Spring 会自动获取 HTTP 请求中 Query String(GET) 或 body (POST)中传递的参数,将参数的 KEY 值与方法的 形参名进行匹配,匹配成功以后就将 Value 赋值给对应的形参

    3.传递对象

            如果参数⽐较多时,⽅法声明就需要有很多形参.并且后续每次新增⼀个参数,也需要修改⽅法声明.我们不妨把这些参数封装为⼀个对象,后面如果传递的参数需要改变的话,直接修改对象就可以了,不用修改方法

            定义一个 Person 对象来接收参数

    1. public class Person {
    2. private int id;
    3. private String username;
    4. private String password;
    5. public int getId() {
    6. return id;
    7. }
    8. public void setId(int id) {
    9. this.id = id;
    10. }
    11. public String getUsername() {
    12. return username;
    13. }
    14. public void setUsername(String username) {
    15. this.username = username;
    16. }
    17. public String getPassword() {
    18. return password;
    19. }
    20. public void setPassword(String password) {
    21. this.password = password;
    22. }
    23. @Override
    24. public String toString() {
    25. return "Person{" +
    26. "id=" + id +
    27. ", username='" + username + '\'' +
    28. ", password='" + password + '\'' +
    29. '}';
    30. }
    31. }

            

    1. @RequestMapping("/getPerson")
    2. public String getPerson(Person person){
    3. return "person:"+person.toString();
    4. }

            如上代码,当 HTTP 请求访问 getPerson 方法时,Spring 就会去获取 HTTP 请求中的键值对,将键值对的 Key 值与 Person 对象的属性值进行匹配,匹配成功后便将 Value 赋值给对应的属性,初始化对象

     得到如下的效果:

    4.@RequestParam 后端参数重命名(修改映射关系

            在某些情况下,前端传递的 Key 值与后端的参数名可能不一致,这样就会导致传参失败,比如前端传递了一个 Key 值为 name 的属性,而后端却用 username 这个形参来接收,那肯定就会导致接收失败

            所以,如果我们想要使用 username 这个形参来接收 Key 值为 name 对应的 Value ,我们就要通过 @RequestParam 注解修改前后端参数之间的映射关系

    1. @RequestMapping("/getUsername")
    2. public String getUsername(@RequestParam("name") String username){
    3. return "username:"+username;
    4. }

    得到的结果如下

            但这也会导致一些问题出现,当我们不给 getUsername()方法传递参数时,会出现下面的情况

            此时我们的 HTTP 请求没有携带参数给 getUsername()方法,所以导致出现了 400(客户端错误),这是因为 @RequestParam 注解有个 required 属性默认为 true ,这就导致使用 @RequestParam 注解修改映射关系以后,方法中的形参就变为了一个必传参数,要是没传就会报错

            解决方法:将 required 属性改为 false 

    1. @RequestMapping("/getUsername")
    2. public String getUsername(@RequestParam(value = "name" ,required = false) String username){
    3. return "username:"+username;
    4. }

    5.传递数组

            HTTP 请求中的参数名和后端方法中数组类型的形参名相同,且参数有多个,Sping 就会自动把所有的 Value 值传递给后端方法的数组中

    1. @RequestMapping("/getArrayName")
    2. public String getArrayName(String[] arrayName){
    3. return arrayName.toString();
    4. }

            得到的结果如下:

    6.传递集合

            传递集合与传递数组类似,都是 HTTP 请求中的一个参数对应多个值

            但 Spring 默认 HTTP 请求中一个参数对应多个值这种情况要将值传递给数组,如果我们要传递给列表的话,就需要使用 @RequestParam 注解绑定参数关系

    1. @RequestMapping("/getListName")
    2. public String getListName(@RequestParam List listName){
    3. return "listName:"+listName;
    4. }

            得到的结果如下

    7.传递JSON数据 @RequestBody

            企业中传递数据最普遍的便是通过 JSON 格式来传递数据,JSON就是⼀种数据格式,有⾃⼰的格式和语法,使⽤⽂本表⽰⼀个对象或数组的信息,因此 JSON本质是字符串.主要负责在不同的语⾔中数据传递和交换.关于 JSON 推荐看应用层自定义协议(组织数据的格式)

            Spring MVC框架也集成了JSON的转换⼯具,我们可以直接使⽤,来完成JSON字符串和Java对象的互转

            接收 JSON 格式的数据,我们需要用到 @RequestBody 这个注解,这个注解翻译过来是请求正文,所以我们传递的数据必须是在正文(body)中,当然传递 JSON 格式的数据通常也是放到 HTTP 请求的 body 中传输的

    1. @RequestMapping("/getJson")
    2. public String getJson(@RequestBody Person person){
    3. return person.toString();
    4. }

            得到的结果如下:

            在 json 格式的数据转换成 java 对象的过程中,Spring 会去获取到 HTTP 请求中的 json 字符串,并获取到 Person 对象中的属性,将 json 字符串中的 Key 值与 Person 对象中的属性名进行对比,要是相同就将 Key 对应的 Value 通过 Person 类中的 set 方法进行赋值

    8.获取URL中参数 @PathVariable

            该注解翻译过来是路径变量,主要作⽤在请求URL路径上的数据绑定,可以获取到 URL 指定位置上的数据

    1. @RequestMapping("/getUrlPath/{id}/{name}")
    2. public String getUrlPath(@PathVariable Integer id,@PathVariable String name){
    3. return "id:"+id+" name:"+name;
    4. }

     得到的结果如下:

    9.上传⽂件 @RequestPart

    代码实现

    1. @RequestMapping("/getFile")
    2. public String getFile(@RequestPart MultipartFile file) throws IOException {
    3. //获取文件名称
    4. String fileName=file.getOriginalFilename();
    5. //文件上传到指定路径
    6. file.transferTo(new File("D:/图片/"+fileName));
    7. return "文件的名称为"+fileName;
    8. }

            通过 postman 构造 HTTP 请求发送文件,效果如下

    10.获取Cookie/Session @CookieValue @SessionAttribute HttpSession

    .获取 Cookie 代码:

    1. @RequestMapping("/getCookie")
    2. public String getCookie(@CookieValue(required = false) String name){
    3. return "cookie:"+name;
    4. }

    获取 Session 代码1:

    1. @RequestMapping("/getSession1")
    2. public String getSession1(@SessionAttribute(required = false) String name){
    3. return "name:"+name;
    4. }

    获取 Session 代码2:

    通过Spring MVC内置对象 HttpSession 来获取 

    1. @RequestMapping("/getSession2")
    2. public String getSession2(HttpSession session){
    3. // Session 的相关数据保存到 session 对象中了
    4. String name=(String) session.getAttribute("name");
    5. return "name:"+name;
    6. }

    使用内置对象 HttpSession 相当于HttpSession session = request.getSession();

    getSession()方法的默认参数是 true ,所以要是没有找到 Session 会创建一个 Session

    11.获取Header @RequestHeader

    获取 Header 代码:

    1. @RequestMapping("/getHeader")
    2. public String getHeader(@RequestHeader("User-Agent") String userAgent){
    3. return "User-Agent"+userAgent;
    4. }

    结果如下:

            在 HTTP 请求的 Header 中 User-Agent 属性对应用户的配置信息和浏览器版本,如上图,成功展示

  • 相关阅读:
    C++ API设计之风格
    服务器被攻击怎么选择更好的方式去防御,IDC说的集防和单机防御都是什么意思
    Motifs与Graphlets
    基于react-markdown组件自定义一个Markdown显示器
    python中强制关闭线程、协程、进程方法
    【C++】运算符重载 ⑥ ( 一元运算符重载 | 后置运算符重载 | 前置运算符重载 与 后置运算符重载 的区别 | 后置运算符重载添加 int 占位参数 )
    【毕业设计】基于Django与深度学习的股票预测系统
    Java代码Demo——Map根据key或value排序
    LinkedList相较于Arravlist的特点/优化(面试笔记总结速记)
    前端-vue基础28-vue常用特性
  • 原文地址:https://blog.csdn.net/q322359/article/details/134069999