@RequestMapping,@RequsetBody等注解说明
@RequestMapping,@RequestBody的注解的使用
当下的主流web开发框架当属springMVC,究其原因就是SpringMVC可以很容易的将后台的数据转化为各种类型的数据,,很好的适应了移动互联网的数据多样化变化的要求。比如可以很容易的将数据转化
为我们常使用的json数据集,也可以转化为Excel,PDF,XML等的数据集。随着springboot的发展,注解开发因为其开发速度快,编译期间容易发现错误的出处,注解开发已经成为趋势。这篇博文就基于srpingboot下的
springmvc注解进行梳理,以下的所有代码测试都是以springboot为基础构建的。
springMVC的工作流程图
在了解具体的注解使用之前,了解一下springMVC的工作流程和工作的时序图是很有必要的。
说明:由于现在大部分项目都是前后端分离,大部分情况下,后端只需要传递指定的Json数据集即可,所以这里的springmvc的流程图中的视图是基于json视图的。
springMvc的时序图如下:
@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的请求类型。
- 使用示例
-
编写测试的类
//控制器 @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¬e=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对象来接受这个参数。
注意两点:
- 就是前端传递的对象属性必须和后端对应。比如 后端定义的user属性为 int id ,String name ,前端也必须使用相同的类型和字段来定义。
- 要使用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
测试结果:
测试成功
参考资料:
- 《深入浅出springboot》 杨开振
- springboot的官方文档
在正确的道路上,全力以赴,梦想终究照进现实。来自一个菜鸟程序员的鸡汤。