我想将异常从我的“数据库” REST API重新引发到我的“后端” REST API,但是我松开了原始异常的消息。
这是我通过邮递员从我的“数据库” REST API获得的内容:
{
"timestamp": "2020-03-18T15:19:14.273+0000",
"status": 400,
"error": "Bad Request",
"message": "I'm DatabaseException (0)",
"path": "/database/api/vehicle/test/0"
}
这部分还可以。
这是我通过邮递员从我的“后端” REST API获得的内容:
{
"timestamp": "2020-03-18T15:22:12.801+0000",
"status": 400,
"error": "Bad Request",
"message": "400 BAD_REQUEST \"\"; nested exception is org.springframework.web.reactive.function.client.WebClientResponseException$BadRequest: 400 Bad Request from GET http://localhost:8090/database/api/vehicle/test/0",
"path": "/backend/api/vehicle/test/0"
}
您可以看到原来的“消息”字段丢失了。
我使用:
后端和数据库以Tomcat(web and webflux in the same application)开头。
这是后端:
@GetMapping(path = "/test/{id}")
public Mono<Integer> test(@PathVariable String id) {
return vehicleService.test(id);
}
使用vehicleService.test:
public Mono<Integer> test(String id) {
return WebClient
.create("http://localhost:8090/database/api")
.get()
.uri("/vehicle/test/{id}", id)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(Integer.class);
}
这是数据库:
@GetMapping(path = "/test/{id}")
public Mono<Integer> test(@PathVariable String id) throws Exception {
if (id.equals("0")) {
throw new DatabaseException("I'm DatabaseException (0)");
}
return Mono.just(Integer.valueOf(2));
}
我也尝试过return Mono.error(new DatabaseException("I'm DatabaseException (0)"));
和DatabaseException:
public class DatabaseException extends ResponseStatusException {
private static final long serialVersionUID = 1L;
public DatabaseException(String message) {
super(HttpStatus.BAD_REQUEST, message);
}
}
似乎我的后端转换了响应,并且在互联网上找不到任何答案。
代替retrieve
的WebClient
,可以使用exchange
来处理错误并传播自定义异常以及从服务响应中检索到的消息。
private void execute()
{
WebClient webClient = WebClient.create();
webClient.get()
.uri("http://localhost:8089")
.exchange()
.flatMap(this::handleResponse)
.doOnNext(System.out::println)
.block(); // not required, just for testin purposes
}
private Mono<Response> handleResponse(ClientResponse clientResponse)
{
if (clientResponse.statusCode().isError())
{
return clientResponse.bodyToMono(Response.class)
.flatMap(response -> Mono.error(new RuntimeException(response.message)));
}
return clientResponse.bodyToMono(Response.class);
}
private static class Response
{
private String message;
public Response()
{
}
public String getMessage()
{
return message;
}
public void setMessage(String message)
{
this.message = message;
}
@Override
public String toString()
{
return "Response{" +
"message='" + message + '\'' +
'}';
}
}