Restful是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。Restful适用于移动互联网厂商作为业务使能接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源。
Restful 特点
- 每一个URI代表1种资源;
- 客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;
- 通过操作资源的表现形式来操作资源;
- 资源的表现形式是XML或者HTML;
- 客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。
Restful 常用URL
操作 | URL | RequestMethod | Restful URL | Restful RequestMethod |
---|---|---|---|---|
查询 | /user/query?name=tom | GET | /user?name=tom | GET |
详情 | /user/getInfo?id=1 | GET | /user/1 | GET |
创建 | /user/create?name=tom | POST | /user | POST |
修改 | /user/update?id=1&name=jerry | POST | /user/1 | PUT |
删除 | /user/delete?id=1 | GET | /user/1 | DELETE |
Spring相关常用注解
@RestController
标明Controller提供的是 Restful API
1 | // UserController.java |
@RequestMapping 及其变体
映射http请求的url到Java方法中
- value: 指定request的地址
- method: 指定请求的method类型, GET、POST、PUT、DELETE等
- params: 指定request中包含的某些参数值,作为方法的输入,如:
@RequestParam(value = "disable", required = false)
- value: 为传入的参数
- required: 设置为 false,若传入的 value 为空值,则报错;设置为 true,若传入的 value 为空值,则返回 null.
- consumes: 指定处理请求的提交内容类型,例如 application/json, text/html;
- produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
- headers: 指定request中包含某些指定的header值,让该方法处理请求
1 | // UserController.java |
随着Spring的发展,可以采用如下注解,简化@RequestMapping。
@GetMapping
1 | // UserController.java |
@PostMapping
1 | // UserController.java |
@PutMapping
1 | // UserController.java |
@DeleteMapping
1 | // UserController.java |
@PatchMapping
Patch方式是对Put方式的一种补充。put方式是可以更新,但是更新的是整体。patch是对局部更新。
@RequestParam
映射请求参数到Java方法的参数中
@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)
- value:参数名
- required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。
- defaultValue:默认参数值,如果设置了该值,required=true将失效,自动为false,如果没有传该参数,就使用默认值
1 | // UserController.java |
@RequestBody
映射请求参数到Java的实体类中
该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded
编码的内容,例如application/json
, application/xml
等;
它是通过使用HandlerAdapter 配置的HttpMessageConverters来解析post data body,然后绑定到相应的bean上的。
因为配置有FormHttpMessageConverter,所以也可以用来处理application/x-www-form-urlencoded
的内容,处理完的结果放在一个MultiValueMap<String, String>
里,这种情况在某些特殊需求下使用,详情查看FormHttpMessageConverter api;
1 | "/something", method = RequestMethod.PUT) (value = |
@PathVariable ^7
@PageableDefault
指定分页参数默认值
- page: 第几页,从0开始,默认为第0页
- size: 每一页的大小,默认为20
- sort: 排序相关的信息,以property,property(,ASC|DESC)的方式组织,例如sort=firstname&sort=lastname,desc表示在按firstname正序排列基础上按lastname倒序排列。
1 | // UserController.java |
@Valid
Hibernate Validation注解
注解 | 说明 |
---|---|
@NotNull | 值不能为空 |
@Null | 值必须为空 |
@Pattern(regex=) | 字符串必须匹配正则表达式 |
@Size(min=,max=) | 集合的元素数量必须在min和max之间 |
@CreditCardNumber(ignoreNoneDigitCharacters=) | 字符串必须是信用卡号(美国标准) |
字符串必须是Email地址 | |
@Length(min=,max=) | 检查字符串的长度 |
@NotBlank | 字符串必须有字符 |
@NotEmpty | 字符串不能为null,集合内须有元素 |
@Range(min=,max=) | 值数字必须大于等于min,小于等于max |
@SafeHtml | 字符串是安全的html |
@URL(protocol=,host=,port=,regexp=,flags=) | 字符串是合法的url |
@AssertFalse | 值必须是False |
@AssertTrue | 值必须是True |
@DecimalMax(value=,inclusive=) | 值必须小于等于(inclusive=true)/小于(inclusive=false)value属性指定的值。可以注释在字符串类型的属性上。 |
@DecimalMin(value=,inclusive=) | 值必须大于等于(inclusive=true)/大于(inclusive=false)value属性指定的值。可以注释在字符串类型的属性上。 |
@Digits(integer=,fraction=) | 数字格式检查。integer指定整数部分额最大长度,fraction指定小数部分的最大长度 |
@Future | 值必须是未来的日期 |
@Past | 值必须是过去的日期 |
@Max(value=) | 值必须小于等于value指定的值。不能注释在字符串类型的属性上。 |
@Min(value=) | 值必须大于等于value指定的值。不能注释在字符串类型的属性上。 |
BindingResult
@Valid 和 BindingResult 是一一对应的,如果有多个@Valid,那么每个@Valid后面跟着的BindingResult就是这个@Valid的验证结果,顺序不能乱。1
2
3
4
5
6
7public Object doSomething(@Validated @RequestBody OneDto oneDto,
BindingResult result) {
// 参数通不过校验也会进入方法执行,校验结果会通过result参数传递进来
if (result.hasErrors()){
// 没通过校验
}
}
@Validated和@Valid的区别
- @Valid是使用Hibernate validation的时候使用
- @Validated是只用Spring Validator校验机制使用
说明:java的JSR303声明了@Valid这类接口,而Hibernate-validator对其进行了实现。@Validation对@Valid进行了二次封装,在使用上并没有区别,但在分组、注解位置、嵌套验证等功能上有所不同,这里主要就这几种情况进行说明。
注解位置
- @Validated:用在类型、方法和方法参数上。但不能用于成员属性(field),如果@Validated注解在成员属性上,则会报 不适用于field错误
- @Valid:可以用在方法、构造函数、方法参数和成员属性(field)上
分组校验
- @Validated:提供分组功能,可以在参数验证时,根据不同的分组采用不同的验证机制
- @Valid:没有分组功能
组序列
默认情况下 不同级别的约束验证是无序的,但是在一些情况下,顺序验证却是很重要。
一个组可以定义为其他组的序列,使用它进行验证的时候必须符合该序列规定的顺序。在使用组序列验证的时候,如果序列前边的组验证失败,则后面的组将不再给予验证。
嵌套校验
一个待验证的pojo类,其中还包含了待验证的对象,需要在待验证对象上注解@Valid,才能验证待验证对象中的成员属性,这里不能使用@Validated。
HTTP状态码
GET
- 安全且幂等
- 获取表示
- 变更时获取表示(缓存)
- 200(OK) - 表示已在响应中发出
- 204(无内容) - 资源有空表示
- 301(Moved Permanently) - 资源的URI已被更新
- 303(See Other) - 其他(如,负载均衡)
- 304(not modified)- 资源未更改(缓存)
- 400 (bad request)- 指代坏请求(如,参数错误)
- 404 (not found)- 资源不存在
- 406 (not acceptable)- 服务端不支持所需表示
- 500 (internal server error)- 通用错误响应
- 503 (Service Unavailable)- 服务端当前无法处理请求
POST
- 不安全且不幂等
- 使用服务端管理的(自动产生)的实例号创建资源
- 创建子资源
- 部分更新资源
- 如果没有被修改,则不过更新资源(乐观锁)
- 200(OK)- 如果现有资源已被更改
- 201(created)- 如果新资源被创建
- 202(accepted)- 已接受处理请求但尚未完成(异步处理)
- 301(Moved Permanently)- 资源的URI被更新
- 303(See Other)- 其他(如,负载均衡)
- 400(bad request)- 指代坏请求
- 404 (not found)- 资源不存在
- 406 (not acceptable)- 服务端不支持所需表示
- 409 (conflict)- 通用冲突
- 412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突)
- 415 (unsupported media type)- 接受到的表示不受支持
- 500 (internal server error)- 通用错误响应
- 503 (Service Unavailable)- 服务当前无法处理请求
PUT
- 不安全但幂等
- 用客户端管理的实例号创建一个资源
- 通过替换的方式更新资源
- 如果未被修改,则更新资源(乐观锁)
- 200 (OK)- 如果已存在资源被更改
- 201 (created)- 如果新资源被创建
- 301(Moved Permanently)- 资源的URI已更改
- 303 (See Other)- 其他(如,负载均衡)
- 400 (bad request)- 指代坏请求
- 404 (not found)- 资源不存在
- 406 (not acceptable)- 服务端不支持所需表示
- 409 (conflict)- 通用冲突
- 412 (Precondition Failed)- 前置条件失败(如执行条件更新时的冲突)
- 415 (unsupported media type)- 接受到的表示不受支持
- 500 (internal server error)- 通用错误响应
- 503 (Service Unavailable)- 服务当前无法处理请求
DELETE
- 不安全但幂等
- 删除资源
- 200 (OK)- 资源已被删除
- 301 (Moved Permanently)- 资源的URI已更改
- 303 (See Other)- 其他,如负载均衡
- 400 (bad request)- 指代坏请求
- 404 (not found)- 资源不存在
- 409 (conflict)- 通用冲突
- 500 (internal server error)- 通用错误响应
- 503 (Service Unavailable)- 服务端当前无法处理请求
总结
- Restful是一种用URL描述资源的方式
- 使用HTTP方法描述行为,使用HTTP状态码来表示不同的结果
- 使用json交互数据
- Restful只是一种风格,并不是强制的标准