@RequestMapping,@RequsetBody等注解说明

@RequestMapping,@RequestBody的注解的使用

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

springMVC的工作流程图

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

@RequestMapping,@RequsetBody等注解说明

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

springMvc的时序图如下:

@RequestMapping,@RequsetBody等注解说明

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

@RequestMapping,@RequsetBody等注解说明

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

@ReponseBody注解

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

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

    }

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

    @RequestMapping,@RequsetBody等注解说明

看看@ResponseBody这个注解的源码

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

    }

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

@RequestParm注解

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

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

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

       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
    

测试结果:

@RequestMapping,@RequsetBody等注解说明

测试成功

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

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

测试结果:

@RequestMapping,@RequsetBody等注解说明

报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

测试结果:

@RequestMapping,@RequsetBody等注解说明

测试成功

如果一个实体的字段很多,这样传递参数就很不方便。这时候就要提到另一个注解了,那就是@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数据:
@RequestMapping,@RequsetBody等注解说明

测试结果
@RequestMapping,@RequsetBody等注解说明

@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

测试结果:

@RequestMapping,@RequsetBody等注解说明

测试成功

参考资料:

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

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

@RequestMapping,@RequsetBody等注解说明

上一篇:谈一谈在css中的wrapper


下一篇:第4章 思科IOS