Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Http错误消息未从Microservice传播到Webapp_Java_Spring_Rest_Spring Mvc - Fatal编程技术网

Java Http错误消息未从Microservice传播到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

我正在构建一个基于springbootmicroservice的应用程序,我很难将错误消息从包含所有业务逻辑的服务传播回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());
    }
    ...
}
一切都按预期运行,并按预期发送响应代码。因此,如果我的服务发送了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