序
本文主要研究下webflux如何進行參數(shù)校驗
使用javax.validation
domain
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
public class User {
@Min(1)
private long id;
@NotEmpty
private String name;
@Min(20)
private int age;
//...
}
通過onErrorResume處理異常
- form表單提交
/**
* curl -i -X POST -d 'id=-1&name=a&age=10' http://localhost:8080/user/validate-mono
*
* curl -i -X POST -d 'id=2&name=a&age=10' http://localhost:8080/user/validate-mono
*
* curl -i -X POST -d 'id=2&name=a&age=30' http://localhost:8080/user/validate-mono
* @param user
* @return
*/
@PostMapping("/validate-mono")
public Mono<String> formValidate(@Validated Mono<User> user) {
return user
.map(u -> "Hello " + u.getName())
.onErrorResume(WebExchangeBindException.class, e -> Mono.just(bindingResult2String(e.getBindingResult())));
}
- post json
/**
* curl -i -H "Content-Type: application/json" -X POST -d '{"id":-11,"name":"a"}' http://localhost:8080/user/validate-mono-json-body
*
* curl -i -H "Content-Type: application/json" -X POST -d '{"id":12,"name":"a","age":30}' http://localhost:8080/user/validate-mono-json-body
* @param user
* @return
*/
@PostMapping(value = "/validate-mono-json-body",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public Mono<String> requestBodyValidate(@Validated @RequestBody Mono<User> user) {
return user
.map(u -> "Hello " + u.getName())
.onErrorResume(WebExchangeBindException.class, e -> Mono.just(bindingResult2String(e.getBindingResult())));
}
注意這里catch住WebExchangeBindException
通過ExceptionHandler處理WebExchangeBindException
- ExceptionHandler
@ExceptionHandler(WebExchangeBindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public String handleBindException(WebExchangeBindException bindException) {
return bindingResult2String(bindException.getBindingResult());
}
- from表單提交
/**
* curl -i -X POST -d 'id=-1&name=a&age=10' http://localhost:8080/user/validate-mono
*
* curl -i -X POST -d 'id=2&name=a&age=10' http://localhost:8080/user/validate-mono
*
* curl -i -X POST -d 'id=2&name=a&age=30' http://localhost:8080/user/validate-mono
* @param user
* @return
*/
@PostMapping(value = "/validate-mono",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Mono<String> formValidate(@Validated Mono<User> user) {
return user
.map(u -> "Hello " + u.getName());
}
注意這里要標注produces = MediaType.APPLICATION_JSON_UTF8_VALUE,否則報406 Not Acceptable
- post json
/**
* curl -i -H "Content-Type: application/json" -X POST -d '{"id":-11,"name":"a"}' http://localhost:8080/user/validate-mono-json-body
*
* curl -i -H "Content-Type: application/json" -X POST -d '{"id":12,"name":"a","age":30}' http://localhost:8080/user/validate-mono-json-body
* @param user
* @return
*/
@PostMapping(value = "/validate-mono-json-body",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public Mono<String> requestBodyValidate(@Validated @RequestBody Mono<User> user) {
return user
.map(u -> "Hello " + u.getName());
}
注意這里沒有使用onErrorResume來處理WebExchangeBindException,而是交給ExceptionHandler處理
手工校驗
javax.validation雖然是方便邢笙,但是具體業(yè)務(wù)場景非常復雜化撕,不是簡單的單個字段校驗就完事的,有的需要關(guān)聯(lián)校驗质和,這個時候javax.validation就無能為力了振峻。這個時候可能就需要手工來寫校驗糕伐。
/**
* curl -i -X POST -d 'id=-1&name=a&age=10' http://localhost:8080/user/manual-validate
*
* curl -i -X POST -d 'id=2&name=a&age=-1' http://localhost:8080/user/manual-validate
* @param user
* @return
*/
@PostMapping(value = "/manual-validate",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Mono<String> manualValidate(Mono<User> user){
return user.flatMap(u -> {
if(u.getAge() < 0){
return Mono.error(new RuntimeException("age < 0"));
}else{
return Mono.just("success");
}
});
}
小結(jié)
通過使用javax.validation自動校驗及Mono.error手工校驗,基本可以處理大多數(shù)webflux參數(shù)校驗場景仰坦。