spring webflux ServerWebInputException异常http status是200的问题

在学习webflux的使用,官方文档中的一个参数校验的例子

@Configuration
public class RoutingConfiguration {

  @Bean
  public RouterFunction<ServerResponse> routes(PersonHandler handler) {
    return RouterFunctions.route().GET("/person/{id}",
        RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::getPerson)
        .GET("/person", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::allPeople)
        .POST("/person", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::savePerson)
        .DELETE("/person/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::deletePerson)
        .PUT("/person/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::updatePerson)
        .build();
  }
}
@Slf4j
@Component
public class PersonHandler {

  @Autowired
  private PersonRepository repository;
  @Autowired
  private PersonValidator validator;


  public Mono<ServerResponse> getPerson(ServerRequest request) {
    int personId = Integer.parseInt(request.pathVariable("id"));
    Mono<Person> personMono = this.repository.getPerson(personId);
    return personMono.flatMap(person -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
        .body(BodyInserters.fromValue(person))).switchIfEmpty(ServerResponse.notFound().build());
  }

  public Mono<ServerResponse> savePerson(ServerRequest request) {
  // 参数校验
    Mono<Person> personMono = request.bodyToMono(Person.class).doOnNext(this::validate);
    return ServerResponse.ok().build(this.repository.savePerson(personMono));
  }
// 校验的方法
  public void validate(Person person) {
    Errors errors = new BeanPropertyBindingResult(person, "person");
    validator.validate(person, errors);
    if (errors.hasErrors()) {
      log.info(errors.toString());
      // 抛出异常
      throw new ServerWebInputException(errors.toString());
    }
  }
    // ....
  }

通过不合法的参数校验
QQ20210804-010106@2x.png

通过查看 ServerWebInputException 的代码,http status 为400。

/**
     * Constructor for a 400 error with a root cause.
     */
    public ServerWebInputException(String reason, @Nullable MethodParameter parameter, @Nullable Throwable cause) {
        super(HttpStatus.BAD_REQUEST, reason, cause);
        this.parameter = parameter;
    }

想得到的一个http status 为400的请求,但是通过接口访问http status 还是200,问一下代码哪里有问题吗?

阅读 3.1k
1 个回答

发现问题了,是在savePerson方法中

public Mono<ServerResponse> savePerson(ServerRequest request) {
  // 参数校验
    Mono<Person> personMono = request.bodyToMono(Person.class).doOnNext(this::validate);
    return ServerResponse.ok().build(this.repository.savePerson(personMono));
  }

中的这段代码

ServerResponse.ok().build(this.repository.savePerson(personMono));

有点问题,修改成

ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(this.repository.savePerson(personMono), Void.class);

这样就可以,另外修改成

ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.bodyValue(this.repository.savePerson(personMono));

也是不行的。具体应该是在 bodybodyValue 的不同,还没有深入的了解 webflux 具体原因还不清楚,另外官方示例地址https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-fn-handler-validation

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题