【发布时间】:2017-10-16 15:53:41
【问题描述】:
我们有一个微服务架构。每个服务都通过 Rest 公开数据。所有控制器均使用 Spring 设置:
@RestController
@RequestMapping(path = "foobar")
public class UiController {
@PostMapping("foo")
public ResponseEntity<Foo> addFoo(@RequestBody final FooDto fooDto) {
Foo fromDb = adminService.addFoo(converterToModel.convert(fooDto);
return ResponseEntity.ok(converterToDto.convert(fromDb));
}
如果由于某种原因 fooDto 无法添加到数据库中。抛出自定义异常:
@ResponseStatus(value = HttpStatus.CONFLICT)
public class FooAlreadyAssignedException extends RuntimeException {
public FooAlreadyAssignedException(String msg) {
super("The following foos are already assigned to foobar: " + msg);
}
}
在 Postman 中,在抛出上述异常后,您会看到以下 JSON
{
"timestamp": 1508247298817,
"status": 409,
"error": "Conflict",
"exception": "com.foo.exception.FooCodeAlreadyExistsException",
"message": "A foo with code: foo already exists",
"path": "/foo/foobar"
}
我们有 4 种不同的服务,它们都以相同的方式设置。
我们的 UI 是在 Angular 4 中制作的,并对我们的网关进行 REST 调用。网关是微服务和 UI 之间的连接。它还公开了一个 REST 端点。它也是用 Spring 实现的。我添加了一张图片以进行澄清:
“编辑:我看到我没有完成箭头。当然所有数据都会传回 UI”
问题
Gateway 使用 RestTemplate 调用微服务的 API 当在微服务中抛出自定义异常时,网关会返回:
{
"timestamp": "2017-10-16T15:30:03.456Z",
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.web.client.HttpClientErrorException",
"message": "409 null",
"path": "/v1/printstations"
}
我的原始响应 HttpStatus.conflict (status = 409) 似乎被网关包装在状态 500 消息中。我不希望这种行为,我希望它将原始消息传递给 UI。
关于如何控制这种行为的任何想法?
备注
我用 Postman 测试过,如果你直接访问微服务,它会返回 409,并在自定义异常中写入消息
我已经尝试过覆盖 Springs ResponseErrorHandler 但无法以这种方式找到合适的解决方案。
【问题讨论】:
-
那么,网关的代码是什么?
-
正如我所说,它是使用 Spring 设置的(因此与微服务相同),但使用 RestTemplate 来调用微服务的 API
标签: java spring rest exception