Java 验证失败时,Micronaut控制器响应错误

Java 验证失败时,Micronaut控制器响应错误,java,microservices,micronaut,Java,Microservices,Micronaut,我正在尝试编写一个Micronaut服务,当数据有验证错误时,它会返回一个特定的响应 @Post(value=“/”,products=MediaType.APPLICATION\u JSON) 公共响应保存(@Valid@Body Category){ Category savedCategory=categoryService.save(类别); Response Response=新响应(“成功保存类别”),State.SUCCESS, 保存类别); 返回响应; } @错误(except

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


@Post(value=“/”,products=MediaType.APPLICATION\u JSON)
公共响应保存(@Valid@Body Category){
Category savedCategory=categoryService.save(类别);
Response Response=新响应(“成功保存类别”),State.SUCCESS,
保存类别);
返回响应;
}
@错误(exception=ConstraintViolationException.class)
保存的公共响应失败(HttpRequest请求,ConstraintViolationException ex){
可选requestBody=request.getBody(Category.class);
Response Response=新响应(“”,State.FAILED,requestBody.get());
addErrors(messageSource.violationsMessages(例如getConstraintViolations());
System.out.println(响应);//[1]执行此行
返回响应;
}
这段代码似乎工作正常,因为当我使用下面的测试调用代码时,标记为[1]的行被正确执行。 但是在捕获HttpClientResponseException后的测试中,我无法获取控制器返回的响应对象,我做错了什么

@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);
    }
  }
以下是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个参数是错误类型:

因此,您的代码应该类似于:

HttpRequest请求=HttpRequest.POST(“/categories”,category);
exchange(请求、参数.of(Object.class)、参数.of(JsonError));
...
exception.getResponse().getBody(Argument.of(Response.class,Category.class))//返回一个可选的
另外,为了确保一切都按预期进行,并且您实际收到了错误,您可以为
HttpClient
启用跟踪,将以下内容添加到
logback.xml


...
...

要获取错误主体,需要使用3参数方法,其中第3个参数是错误类型:

因此,您的代码应该类似于:

HttpRequest请求=HttpRequest.POST(“/categories”,category);
exchange(请求、参数.of(Object.class)、参数.of(JsonError));
...
exception.getResponse().getBody(Argument.of(Response.class,Category.class))//返回一个可选的
另外,为了确保一切都按预期进行,并且您实际收到了错误,您可以为
HttpClient
启用跟踪,将以下内容添加到
logback.xml


...
...

你好,伊万,非常感谢您的回复。这几乎成功了,现在如果我打印异常,那么我会看到响应对象。但是当我执行
exception.getResponse().getBody(Response.class)
时,我会得到
java.util.NoSuchElementException:No value present
如果没有能够运行的代码,那么帮助就很复杂。您是否尝试过使用
exchange
而不是
retrieve
方法?您是否已启用日志以查看实际的错误响应是否正在被发回?我在问题中添加了日志,代码也在中可用。行为与exchange方法相同。我更改getbody参数后,它立即工作,如下所示exception.getResponse().getbody(Argument.of(response.class,Category.class))嗨,伊万,非常感谢你的回复。这几乎成功了,现在如果我打印异常,那么我会看到响应对象。但是当我执行
exception.getResponse().getBody(Response.class)
时,我会得到
java.util.NoSuchElementException:No value present
如果没有能够运行的代码,那么帮助就很复杂。您是否尝试过使用
exchange
而不是
retrieve
方法?您是否已启用日志以查看实际的错误响应是否正在被发回?我在问题中添加了日志,代码也在中可用。行为与exchange方法相同。我更改getbody参数后,它立即工作,如下所示exception.getResponse().getbody(Argument.of(response.class,Category.class))
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 - ----