我們在系統(tǒng)中經(jīng)常會遇到需要對輸入的數(shù)據(jù)進行驗證寞钥。
這里我們使用Spring Boot 結合Bean Validation API來進行數(shù)據(jù)驗證声怔。
Bean Validation API是Java定義的一個驗證參數(shù)的規(guī)范呵扛。
具體可以參考:http://beanvalidation.org/specification/
依賴
在pom文件中加入spring-boot-starter-validation
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
定義請求
例子中我們定義如下的請求消息宛篇。它包含id就轧,username,password 三個屬性腋妙。
package com.github.alex.validate.model;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* Created by ChenChang on 2017/4/8.
*/
public class UserRequest {
private Long id;
private String username;
private String password;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
編寫Controller
我們使用Spring 提供的@RestController
注解。
做一個簡單的CURD的Controller讯榕,如下
package com.github.alex.validate.web;
import com.github.alex.validate.model.User;
import com.github.alex.validate.model.UserRequest;
import com.github.alex.validate.util.HeaderUtil;
import com.github.alex.validate.util.IdWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import io.swagger.annotations.ApiOperation;
/**
* Created by ChenChang on 2017/4/8.
*/
@RestController
@RequestMapping(value = "/userResource")
public class UserResource {
private final Logger log = LoggerFactory.getLogger(UserResource.class);
static Map<Long, User> users = Collections.synchronizedMap(new HashMap<Long, User>());
IdWorker idWorker = new IdWorker(2);
@PostMapping
@ApiOperation(value = "新增用戶", notes = "新增用戶")
public ResponseEntity<User> createUser(@RequestBody UserRequest request) throws URISyntaxException {
log.debug("REST request to create User: {}", request);
User user = new User();
BeanUtils.copyProperties(request, user);
user.setId(idWorker.nextId());
users.put(user.getId(), user);
return ResponseEntity.created(new URI("/userResource/" + user.getId()))
.headers(HeaderUtil.createEntityCreationAlert(User.class.getSimpleName(), user.getId().toString()))
.body(user);
}
@GetMapping("/{id}")
@ApiOperation(value = "獲取用戶", notes = "獲取用戶")
public ResponseEntity<User> getUser(@PathVariable Long id) {
log.debug("REST request to get User : {}", id);
User user = users.get(id);
return Optional.ofNullable(user)
.map(result -> new ResponseEntity<>(
result,
HttpStatus.OK))
.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
@PutMapping
@ApiOperation(value = "更新用戶", notes = "更新用戶")
public ResponseEntity<User> updateUser(@RequestBody UserRequest request)
throws URISyntaxException {
log.debug("REST request to update User : {}", request);
if (request.getId() == null) {
return ResponseEntity.badRequest().body(null);
}
User user = users.get(request.getId());
BeanUtils.copyProperties(request, user);
return ResponseEntity.ok()
.headers(HeaderUtil.createEntityUpdateAlert(User.class.getSimpleName(), user.getId().toString()))
.body(user);
}
}
進行測試看看是我們獲得了什么
發(fā)送請求
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \
"password": "1", \
"username": "string" \
}' 'http://localhost:8080/userResource'
獲得了結果
Response Body
{
"id": 2128081075062784,
"username": "string",
"password": "1"
}
Response Code
201
可以看到我們的操作是成功的骤素,但是沒有對我們的數(shù)據(jù)進行校驗。
現(xiàn)在我們有兩個需求:
- username不能為空愚屁,并且長度大于三個字母
- password不能為空济竹,并且長度大于6小于30
定義驗證
修改UserRequest,在username和password屬性上添加注解
@NotNull
@Size(min = 3)
private String username;
@NotNull
@Size(min = 6, max = 30)
private String password;
修改UserResource,在@RequestBody
前面添加注解@Validated
public ResponseEntity<User> createUser(@Validated @RequestBody UserRequest request)
就這么簡單 我們再看看會發(fā)生什么
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \
"password": "1", \
"username": "1" \
}' 'http://localhost:8080/userResource'
結果
Response Body
{
"timestamp": 1491642036689,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.web.bind.MethodArgumentNotValidException",
"errors": [
{
"codes": [
"Size.userRequest.username",
"Size.username",
"Size.java.lang.String",
"Size"
],
"arguments": [
{
"codes": [
"userRequest.username",
"username"
],
"arguments": null,
"defaultMessage": "username",
"code": "username"
},
2147483647,
3
],
"defaultMessage": "個數(shù)必須在3和2147483647之間",
"objectName": "userRequest",
"field": "username",
"rejectedValue": "1",
"bindingFailure": false,
"code": "Size"
},
{
"codes": [
"Size.userRequest.password",
"Size.password",
"Size.java.lang.String",
"Size"
],
"arguments": [
{
"codes": [
"userRequest.password",
"password"
],
"arguments": null,
"defaultMessage": "password",
"code": "password"
},
30,
6
],
"defaultMessage": "個數(shù)必須在6和30之間",
"objectName": "userRequest",
"field": "password",
"rejectedValue": "1",
"bindingFailure": false,
"code": "Size"
}
],
"message": "Validation failed for object='userRequest'. Error count: 2",
"path": "/userResource"
}
Response Code
400
其他驗證
hibernate-validator也對Bean Validation做了支持,增加了更多種類的驗證
我們在UserRequest中加入新的字段email,它是一個必填項霎槐,而且要符合email的規(guī)則
@Email
@NotNull
private String email;
再來試試
Response Body
{
"timestamp": 1491642643358,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.web.bind.MethodArgumentNotValidException",
"errors": [
{
"codes": [
"Email.userRequest.email",
"Email.email",
"Email.java.lang.String",
"Email"
],
"arguments": [
{
"codes": [
"userRequest.email",
"email"
],
"arguments": null,
"defaultMessage": "email",
"code": "email"
},
[],
{
"codes": [
".*"
],
"arguments": null,
"defaultMessage": ".*"
}
],
"defaultMessage": "不是一個合法的電子郵件地址",
"objectName": "userRequest",
"field": "email",
"rejectedValue": "string",
"bindingFailure": false,
"code": "Email"
}
],
"message": "Validation failed for object='userRequest'. Error count: 1",
"path": "/userResource"
}
Response Code
400
如此簡單-,- 給你的Rest接口也加上輸入數(shù)據(jù)驗證吧~
以上的代碼例子 https://github.com/chc123456/ValidatingInputRestRequestSpringBoot/