聊聊webflux參數校驗

本文主要研究下webflux如何進行參數校驗html

使用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雖然是方便,可是具體業務場景很是複雜,不是簡單的單個字段校驗就完事的,有的須要關聯校驗,這個時候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

doc

相關文章
相關標籤/搜索