• @RequestMapping,@RequsetBody等注解说明


    @RequestMapping,@RequestBody的注解的使用

    当下的主流web开发框架当属springMVC,究其原因就是SpringMVC可以很容易的将后台的数据转化为各种类型的数据,,很好的适应了移动互联网的数据多样化变化的要求。比如可以很容易的将数据转化
    为我们常使用的json数据集,也可以转化为Excel,PDF,XML等的数据集。随着springboot的发展,注解开发因为其开发速度快,编译期间容易发现错误的出处,注解开发已经成为趋势。这篇博文就基于srpingboot下的
    springmvc注解进行梳理,以下的所有代码测试都是以springboot为基础构建的。

    springMVC的工作流程图

    在了解具体的注解使用之前,了解一下springMVC的工作流程和工作的时序图是很有必要的。

    说明:由于现在大部分项目都是前后端分离,大部分情况下,后端只需要传递指定的Json数据集即可,所以这里的springmvc的流程图中的视图是基于json视图的。

    springMvc的时序图如下:

    srpingmvc处理一个web请求的时序图

    @RequestMapping注解的使用

    • 作用: 使用灵活的方法将web的请求路径映射在一个类上或者一个方法上。一般映射在类上,在方法上主要使用他的变体的四个注解,@GetMapping @PostMapping @PutMapping,@DeleteMapping 以遍更好的区别不同的请求类型。

    • 主要属性:通过源码了解到的属性如下:

       @Target({ElementType.TYPE, ElementType.METHOD})
       @Retention(RetentionPolicy.RUNTIME)
       @Documented
       @Mapping
       public @interface RequestMapping {
      
      // 配置请求映射名称
      String name() default "";
      
          // 通过路径映射
      @AliasFor("path")
      String[] value() default {};
      
          // 通过路径映射回path的配置项
      @AliasFor("value")
      String[] path() default {};
      
          // 限定响应HTTP请求的类型,GET,POST,HEAD,OPPTIONS,PUT,TRACE等
          // 默认响应所有的请求
      RequestMethod[] method() default {};
      
         // 当存在http参数时,才响应的请求
       String[] params() default {};
      
       // 限定请求头存在对应的参数才响应
        String[] headers() default {};
      
       // 限定HTTP的请求体提交类型,如"application/json","text/html"
       String[] consumes() default {};
      
           // 限定返回的内容类型,仅当HTTP的请求头中的(Accept)类型中包含指定的该类型才返回
       String[] produces() default {};
      
           }
      

    比较常用的属性还是value和path这两个属性,这两个属性来配置路径的,当然也可以使用method属性来配置HTTP的请求类型。

    • 使用示例
    1. 编写测试的类

       //控制器
       @Controller
       @RequestMapping("/my")
       public class UserController {
      
         /**
         * 获取用户
         * @return 以json格式返回数据
          */
       @RequestMapping("/getuser")
       @ResponseBody
       public User getUser(){
         User user = new User();
         user.setId(1);
         user.setName("chenw1024");
         return user;
        }
      

      }

    2.测试

       浏览器 输入 http://localhost:8080/my/getuser
    

    可以看到浏览器展示出了用户的信息。这是因为这里还使用了一个注解 @ReponseBody这个注解。主要返回服务端的响应结果。

    @ReponseBody注解

    • 主要作用: 就是将服务器响应的结果以json数据集的格式返回给客户端。也就是将方法的返回值绑定到web的响应体中。
      上述的例子,将用户的信息返回给客户端,现在我们注释掉这个@ResponseBody会如何呢

       @RequestMapping("/getuser")
       //  @ResponseBody
      public User getUser(){
        User user = new User();
        user.setId(1);
        user.setName("chenw1024");
        return user;
      

      }

      再次测试可以发现 请求找不到:

    看看@ResponseBody这个注解的源码

         @Target({ElementType.TYPE, ElementType.METHOD})
         @Retention(RetentionPolicy.RUNTIME)
         @Documented
        public @interface ResponseBody {
    
        }
    

    从源码可以了解到这个注解并没有属性,但是使用它还是很经常的。一般应用在方法上。

    @RequestParm注解

    • 作用: 确定前后端参数名称的映射关系,也就是将前端和后端的参数对应起来。

      比一个简单的例子,一个人在家里的小名是狗蛋,在公司里的名字是李四。有一天,李四的朋友去公司找李四,知呼李四的小名狗蛋,而公司并不知道狗蛋是谁,这时刚好和李四是同事的小何,他知道李四就是狗蛋,狗蛋就是李四,就帮忙找到了李四。这里的小何就是@RequestParm。

    • 属性 通过源码进行说明:

         public @interface RequestParam {
      
      // 指定映射的名称
      @AliasFor("name")
      String value() default "";
      
      // 指定参数名称,一般指定的是前端的参数名称
      @AliasFor("value")
      String name() default "";
      
          // 是否允许参数为空,默认为true 也就是前端参数个数必须和后端对应,
      boolean required() default true;
      
         // 就是允许参数为空的情况下,提供的一个默认值
         String defaultValue() default ValueConstants.DEFAULT_NONE;
      
          }
      

    常用的属性就是 value属性和required 这来两个属性。

    • 使用用例

        /*
          * @param id
          * @param name
          * @return
          */
          @RequestMapping("/annotation")
          @ResponseBody
          public Map<String,Object> getParmm(@RequestParam("user_id") int id,
          @RequestParam("user_name") String name,@RequestParam(value = "note",required = false)String note){
      
          Map<String,Object> map = new HashMap<>();
          map.put("id",id);
          map.put("name",name);
          map.put("note",note);
          return map;
          }
      

    user_id,user_name ,note 这是前端的参数 通过@RequestParm 就映射到相应的方法上的参数。

    • 测试

       浏览器输入   http://localhost:8080/my/annotation?user_id=3&user_name=chen&note=hello
      

    测试结果:

    测试成功

    有时候,可能我们并不需要传递全部的参数,在这里如果我们只传递两个参数,会怎么样,

        浏览器输入: http://localhost:8080/my/annotation?user_id=3&user_name=chen
    

    测试结果:

    报400的错误,说明是客户端传递的参数个数和服务端参数个数的不相等。解决这个问题,只要将对应属性required的值设置为false ,这里由于我们不传递note的值,所以将@RequestParam(value = "note")String note改为 @RequestParam(value = "note",required = false)String note
    再测试一遍:

      浏览器输入: 浏览器输入: http://localhost:8080/my/annotation?user_id=3&user_name=chen
    

    测试结果:

    测试成功

    如果一个实体的字段很多,这样传递参数就很不方便。这时候就要提到另一个注解了,那就是@RequsetBody这个注解。

    @RequestBody注解

    • 作用:

      就是将前端的对象映射成后端的一个对象。比如:前端传递一个User对象,使用这个注解,后端的相应的方法就可以使用user对象来接受这个参数。

    注意两点:

    1. 就是前端传递的对象属性必须和后端对应。比如 后端定义的user属性为 int id ,String name ,前端也必须使用相同的类型和字段来定义。
    2. 要使用Json数据集进行传递,也就是设置为 contentType: "application/json"
    • 使用用例

       /**
       * 使用@RequestBody这个注解接受json的数据集
       * 就是请求的Json数据集的属性必须和实体类的属性一致,并且类型也要一致
       * localhost:8080/my/insert    {"id":1,"name":"chen"} 这个是请求体的json
       * @param user
       * @return
       */
       @PostMapping("/insert")
       @ResponseBody
       public Map<String,Object> insert(@RequestBody User user){
         Map<String,Object> map = new HashMap<>();
         map.put("user",user);
         return map;
       }
      

    使用postman进行测试:

    设置json数据:

    测试结果

    @PathVariable注解

    • 作用

      通过url来向后端传递参数。主要用于rest风格,比如要获取一个用户编号为1,姓名为chen的用户,就可输入/get/1/chen 来查询,@PathVariable注解就是将URL中的相应参数映射到方法中的参数中去。

    • 使用用例

      假设要通过编号和姓名来查询用户,就可以使用@PathVariable这个注解。

      /**
      * 通过uRL 传递参数 使用注解 @PathVariable
      * 访问:localhost:8080/my/get/1/chen
      * 注意传入的参数名尽量和方法的参数名一致,也可以在@PathVariable 中指定,不管如 何,必须保证@PathVariable的请求参数和路径中的相同
      * @param id
      * @param name
      * @return
      */
      @GetMapping("/get/{id}/{name}")
      @ResponseBody
      public User getUser(@PathVariable int id,@PathVariable String name){
        Map<String,Object> map = new HashMap<>();
        User user = new User();
        user.setId(id);
        user.setName(name);
        return user;
      }
      

    测试如下:

         浏览器输入: localhost:8080/my/get/1/chen
    

    测试结果:

    测试成功

    参考资料:

    1. 《深入浅出springboot》 杨开振
    2. springboot的官方文档

    在正确的道路上,全力以赴,梦想终究照进现实。来自一个菜鸟程序员的鸡汤。

  • 相关阅读:
    字符串,format格式化及列表的相关进阶操作---day07
    利用wiile双层循环打印各种星星---day06
    双层循环练习,pass_break_continue,和for循环---day06
    类型判断,代码块,流程控制及循环---day05
    频繁项集算法
    Unity 物体移动的理解
    Game1---游戏设计
    精读Hadamard Response论文
    java 创建线程
    Unity游戏开发面试基础知识
  • 原文地址:https://www.cnblogs.com/chentang/p/12589844.html
Copyright © 2020-2023  润新知