java - 验证失败时 Micronaut Controller 响应错误

标签 java microservices micronaut

我正在尝试编写一个 Micronaut 服务,当数据出现验证错误时,该服务会返回特定响应。


  @Post(value = "/", produces = MediaType.APPLICATION_JSON)
  public Response<Category> save(@Valid @Body Category category) {
    Category savedCategory = categoryService.save(category);
    Response<Category> response = new Response<>("Category Saved Successfully", State.SUCCESS,
        savedCategory);
    return response;
  }

  @Error(exception = ConstraintViolationException.class)
  public Response<Category> onSavedFailed(HttpRequest request, ConstraintViolationException ex) {
    Optional<Category> requestBody = request.getBody(Category.class);
    Response<Category> response = new Response<>("", State.FAILED, requestBody.get());
    response.addErrors(messageSource.violationsMessages(ex.getConstraintViolations()));
    System.out.println(response); // [1] THIS LINE IS EXECUTED
    return response;
  }

这段代码似乎工作正常,因为当我使用以下测试调用代码时,标记为 [1] 的行被正确执行。 但是在捕获 HttpClientResponseException 后的测试中,我无法获取 Controller 返回的响应对象,我做错了什么?

@Test
  public void should_not_save_category_without_name(){
    try (RxHttpClient client = embeddedServer.getApplicationContext()
        .createBean(RxHttpClient.class, embeddedServer.getURL())) {
      Category category =  new Category("");
      Response<Category> retrieve = client.toBlocking()
          .retrieve(HttpRequest.POST("/categories", category),
              Argument.of(Response.class, Category.class));
    }catch (HttpClientResponseException exception){
      System.out.println(exception.getResponse().getStatus());
      System.out.println(exception);
    }
  }

这是测试用例中打印的内容

INTERNAL_SERVER_ERROR
io.micronaut.http.client.exceptions.HttpClientResponseException: Internal Server Error

这是 micronaut 客户端日志

10:11:51.571 [nioEventLoopGroup-1-2] DEBUG i.m.http.client.DefaultHttpClient - Sending HTTP Request: POST /categories
10:11:51.572 [nioEventLoopGroup-1-2] DEBUG i.m.http.client.DefaultHttpClient - Chosen Server: localhost(6140)
10:11:51.574 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - host: localhost:6140
10:11:51.574 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - connection: close
10:11:51.574 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - content-type: application/json
10:11:51.574 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - content-length: 2
10:11:51.574 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - Request Body
10:11:51.574 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - ----
10:11:51.574 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - {}
10:11:51.574 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - ----
Response{message='', errors=[name must not be blank], state=FAILED, data=Category{id=null, name=null}}
10:11:51.831 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - HTTP Client Response Received for Request: POST http://localhost:6140/categories
10:11:51.831 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - Status Code: 500 Internal Server Error
10:11:51.831 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - Date: Wed, 8 Jan 2020 04:41:51 GMT
10:11:51.831 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - content-type: application/json
10:11:51.831 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - content-length: 64
10:11:51.831 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - connection: close
10:11:51.832 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - Response Body
10:11:51.832 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - ----
10:11:51.832 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - {"errors":["name must not be blank"],"state":"FAILED","data":{}}
10:11:51.832 [nioEventLoopGroup-1-2] TRACE i.m.http.client.DefaultHttpClient - ----

最佳答案

要获取错误主体,您需要使用3参数方法,其中第3个参数是错误类型: https://docs.micronaut.io/latest/api/io/micronaut/http/client/DefaultHttpClient.html#exchange-io.micronaut.http.HttpRequest-io.micronaut.core.type.Argument-io.micronaut.core.type.Argument-

所以,你的代码应该是这样的:

HttpRequest request = HttpRequest.POST("/categories", category);
client.toBlocking().exchange(request, Argument.of(Object.class), Argument.of(JsonError));

...

exception.getResponse().getBody(Argument.of(Response.class, Category.class)) // This return an Optional

此外,为了确保一切按预期工作并且您确实收到错误,您可以启用 HttpClient 的跟踪,并将以下内容添加到 logback.xml:

<configuration>
    ...
    ...

    <logger name="io.micronaut.http.client" level="TRACE" />

</configuration>

关于java - 验证失败时 Micronaut Controller 响应错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59623183/

相关文章:

java - 如何在工件名称中设置 Jenkins 内部版本号

Spring Cloud Config Eureka-first 方法不起作用

docker - jHipster无法生成网关Docker镜像

spring-boot - 是否可以在加特林压力测试中模拟数据库调用或 Api 调用?

java - Micronaut 设置 EmbeddedServer 进行 Pact 测试

java - 随机数的分布

java - 设计模式-单个对象只能存在于单个事件中

java - 对使用 java 在电子邮件中显示图像有疑问吗?

rx-java2 - Micronaut 数据 - Pageable 或 Flowable.skip().limit()?

websocket - 使用 Micronaut Websocket 端点从未绑定(bind)的 Flux 发送更新