目录
重要注解及其作用
controller层是负责承接前端传来请求,mvc自带的fastjson架构包会帮我们【解析请求里面的参数】,如果有与传过来的参数对应的实体类,那么传过来的数据就可以被封装成对应的实体类对象,前提是我们要在controller方法中使用对应的实体类作为参数来接受这些前端传过来的数据,如果没有使用相关的注解来绑定前端传过来的数据,那么接受数据的实体类的属性名【必须】要与前段的字段名相对应;当然我们也可以使用map来接收前端传过来的任何数据,后面会讲怎么使用map接收前端传过来的数据。
@RequestMapping
该注解不仅仅是一个方法级的注解,还是一个类级注解;如果放在类上,相当于给每个方法默认都加上一个前缀url。
@RequestParam
该注解是从请求地址中取值,但是要求前端发的请求参数必须是使用key-value的形式来传递参数的 。 比如xxxxxx/delete?id=2&name=ljm
@GetMapping("/tset")
public String setupForm(@RequestParam("petId") int petIdxx, Model model) {
// @RequestParam("petId") int petId
//表示前端传过来的petId数据赋值给 petIdxx 属性
}
默认情况下,使用此注解的方法参数是必需要提供的,但我们可以通过将@RequestParam注解的【required标志设置】为 false来指定方法参数是可选的,就是我使用注解标记了这个属性,但是前端没有传这个数据过来,所以把这个设置为false就不会报错,如果不设置required为false,那么就会报400异常,不过还有一个要注意,就是基本数据类型尽量使用包装类,这样帮我们设置默认值为null的时候就不会报空指针异常了。
请注意,使用@RequestParam是可选的。默认情况下,任何属于简单值类型且未被任何其他参数解析器解析的参数都被视为使用【@RequestParam】。
@PathVariable
这个注解的作用是【从请求路径中】直接获取参数的注解;
如果前端:xxxxxx/delete/29 这种路径的方式传递参数,那么我们要怎么接收这个数据?
@requestmapping("/delete/{id}")
public result delete(@PathVariable("id") Integer id){}
使用场景:通过 @PathVariable 可以将 URL 中【占位符】参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable("xxx") 绑定到操作方法的入参中。
案例:前端通过post发的请求地址:http://localhost:8080/dish/status/1?ids=1516568538387079169
@PostMapping("/status/{status}")
public R<String> status(@PathVariable("status") Integer status,Long ids){
log.info("status:{}",status);
log.info("ids:{}",ids);
return null;
}
@ResponseBody
这个注解的作用是 将【返回的结果(一般是指实体类或者是map类型的数据)】【以json格式直接写入响应体】,【不走视图解析器】,写入响应体后的json数据前端就可以直接获取,并且可以对数据进行渲染了;
返回json数据的过程是一个数据序列化的过程;比如前端需要一个user的集合,我们不能直接把Java的集合传给前端,所以我们需要把这些数据通过序列化转化成一种前端可以识别的序列字符;
浏览器生成的响应体是以报文的形式返回的,是一种序列,如果你不做处理的话,js中是没办法直接使用的;
这种做法其实很简单,大致步骤如下:
- 将我们的对象转化为json字符串。
- 将返回的内容直接写入响应体,不走视图解析器。
- 然后将Content-Type设置为application/json即可。(这个知识在后面会经常使用,特别是你要让用户下载东西时)
有两个框架(fastjson,jackson)已经帮我们完成了这个功能,我们只需要导入相关的架构包,然后把bean注入到容器就行;
@RequestBody
作用是直接获取请求体的数据,可以把前端传过来的json数据反序列化成我们需要的数据,【比如把请求体的数据转换成我们需要的实体类或者是map类型的数据,注意map是什么数据都可以封装(唯一需要注意的就是,map的key要和前端需要的属性的属性名相同,比如前端需要一个name的数据,那么我们map对象封装的数据就为 map.put("name",value); 然后在controller把map对象返回就行),然后把map对象(封装的数据)返回给前端】(这个是数据转换器帮我们完成的,我们只需要把相关的转换器对象注入到容器中就行),前端的json数据是存储在requestbody里面的;
RESTful风格的编程习惯
什么是 rest :REST(Representational State Transfer)表现形式状态转换
-
传统风格资源描述形式 http://localhost/user/getById?id=1 (得到id为1的用户) http://localhost/user/saveUser (保存用户)
-
REST风格描述形式 http://localhost/user/1 (得到id为1的用户) http://localhost/user (保存用户,通过前端请求的方法来进行区分)
优点:
-
隐藏资源的访问行为, 无法通过地址得知对资源是何种操作;只有使用了对应的请求方法才能访问相关的数据;
-
书写简化
按照REST风格访问资源时使用行为动作区分对资源进行了何种操作:(这四个动作必须要熟练,现在企业开发几乎已经把这个风格作为开发规范了)
-
http://localhost/users 查询【全部】用户信息 GET (查询)
-
http://localhost/users/1 查询指定用户信息 GET (查询)
-
http://localhost/users 添加用户信息 POST (新增/保存)
-
http://localhost/users 修改用户信息 PUT (修改/更新)
-
http://localhost/users/1 删除用户信息 DELETE (删除)
注意:
上述行为是约定方式,约定不是规范,可以打破,所以称REST风格,而不是REST规范; 描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如: users、 books、 accounts…
restful 风格:这些请求是表现在controller层的方法注解上:
查询数据用get请求
新增数据用post请求
修改数据用put请求
删除数据用delete请求
使用 @RestController
注解开发 RESTful 风格:
注解名称:@RestController
类型:类注解
位置:基于springMVC的restful开发控制器类定义上方
作用:设置当前控制器为restful风格,等同于@controller与@ResponseBody两个注解组合的功能
@RestController
@RequestMapping("/books")
public class BookControleler{
@GetMapping
public List<Book> getAll(){
return bookService.list();
}
@PostMapping
public Boolean save(@RequestBody Book book){
return bookService.save(book);
}
@PutMapping
public Boolean update(@RequestBody Book book){
return bookService.modify(book);
}
@DeleteMapping("{id}")
public Boolean delete(@PathVariable Integer id){
return bookService.delete(id);
}
}
使用 @GetMapping @PostMapping @PutMapping @DeleteMapping 简化 @RequestMapping
注解的开发;
注意:使用restful风格开发,前端的请求要和controller中的方法相对应才能访问成功,才能获取到相关的资源,否则前后端都会报错的!