本文主要研究下webflux如何進行參數校驗html
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; //... }
/** * 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()))); }
/** * 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.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public String handleBindException(WebExchangeBindException bindException) { return bindingResult2String(bindException.getBindingResult()); }
/** * 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
/** * 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雖然是方便,可是具體業務場景很是複雜,不是簡單的單個字段校驗就完事的,有的須要關聯校驗,這個時候javax.validation就無能爲力了。這個時候可能就須要手工來寫校驗。java
/** * 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"); } }); }
經過使用javax.validation自動校驗及Mono.error手工校驗,基本能夠處理大多數webflux參數校驗場景。react