Java Http错误消息未从Microservice传播到Webapp
我正在构建一个基于springbootmicroservice的应用程序,我很难将错误消息从包含所有业务逻辑的服务传播回webapp。在我的服务中,我抛出如下异常:Java Http错误消息未从Microservice传播到Webapp,java,spring,rest,spring-mvc,Java,Spring,Rest,Spring Mvc,我正在构建一个基于springbootmicroservice的应用程序,我很难将错误消息从包含所有业务逻辑的服务传播回webapp。在我的服务中,我抛出如下异常: @ResponseStatus(HttpStatus.BAD_REQUEST) public class Http400ServiceException extends Exception { public Http400ServiceException() { super("Some error mess
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class Http400ServiceException extends Exception {
public Http400ServiceException() {
super("Some error message");
}
}
{
"timestamp": 1459453512220
"status": 403
"error": "Forbidden"
"exception": "com.mysite.mypackage.exceptions.Http403ServiceException"
"message": "Username Rob must be between 5 and 16 characters long"
"path": "/createLogin"
}
@Override
public RuntimeException handleException(Exception e) {
...
if (e instanceof HttpClientErrorException) {
HttpClientErrorException httpError = (HttpClientErrorException) e;
LOGGER.info(httpError.getResponseBodyAsString());
}
...
}
一切都按预期运行,并按预期发送响应代码。因此,如果我的服务发送了403异常,我会在webapp中得到403。我现在要做的是从我的服务中的异常中获取错误消息
问题
当我以生成403的方式从rest客户端插入服务时,响应(JSON)如下所示:
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class Http400ServiceException extends Exception {
public Http400ServiceException() {
super("Some error message");
}
}
{
"timestamp": 1459453512220
"status": 403
"error": "Forbidden"
"exception": "com.mysite.mypackage.exceptions.Http403ServiceException"
"message": "Username Rob must be between 5 and 16 characters long"
"path": "/createLogin"
}
@Override
public RuntimeException handleException(Exception e) {
...
if (e instanceof HttpClientErrorException) {
HttpClientErrorException httpError = (HttpClientErrorException) e;
LOGGER.info(httpError.getResponseBodyAsString());
}
...
}
但是,由于某些原因,我无法从我的webapp访问“消息”字段。我在webapp中有一些通用错误处理代码,如下所示:
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class Http400ServiceException extends Exception {
public Http400ServiceException() {
super("Some error message");
}
}
{
"timestamp": 1459453512220
"status": 403
"error": "Forbidden"
"exception": "com.mysite.mypackage.exceptions.Http403ServiceException"
"message": "Username Rob must be between 5 and 16 characters long"
"path": "/createLogin"
}
@Override
public RuntimeException handleException(Exception e) {
...
if (e instanceof HttpClientErrorException) {
HttpClientErrorException httpError = (HttpClientErrorException) e;
LOGGER.info(httpError.getResponseBodyAsString());
}
...
}
但当我在调试中查看日志/运行应用程序时,httpError.getResponseBodyAsString()
返回null。它有正确的响应代码,只是没有响应体
如果有人能了解出了什么问题,我将不胜感激。因此,我们在开发应用程序的其他领域时,将此问题搁置了几个月。但为了防止其他人在试图解决类似问题时看到这一点,我最终采取的方法如下
- 为要实现的所有服务的所有响应创建一个接口,并创建一个异常类型以指示异常是由于用户错误引起的:
public interface IModel { boolean isError(); UserException getError(); }
- 在每个服务的控制器中,捕获任何异常并从中创建某种IModel:
@ResponseStatus(HttpStatus.OK) @ExceptionHandler(UserException.class) public IModel handleException(UserException exception) { return exception.toModel(); }
- 在用于调用服务的组件中,如果响应上有UserException,则抛出它,否则返回响应正文:
public <T extends IModel> T makeCall(Object payload, Endpoint<T> endpoint) throws UserException { ... ResponseEntity<T> response = restTemplate.postForEntity(endpoint.getEndpointUrl(), payload, endpoint.getReturnType()); if (response.getBody().isError()) { throw response.getBody().getError(); } ... return response.getBody(); }
我觉得有一种更干净的方法,但这是迄今为止我能想到的最好的方法。如果我找到更好的方法,我会更新它。你有
@ResponseStatus
,所以我猜只返回状态。您还需要添加@ResponseBody
,可能还需要一些配置。这就是我现在正在研究的内容。虽然运气不好,法梅会帮忙的。它使用@ControllerAdvice
。