如何为ZuulException自定义Spring Boot Controller API响应

时间:2018-11-12 13:18:13

标签: spring-boot netflix-zuul

我们将Zuul,Eureka和spring boot应用程序服务用于REST API。

假设我的春季启动服务已关闭,并且当我尝试使用Zuul API网关访问API时,我遇到了ZuulException,响应如下:

{
    "timestamp": "2018-10-12T14:29:09.632+0000",
    "status": 500,
    "error": "Internal Server Error",
    "exception": "com.netflix.zuul.exception.ZuulException",
    "message": "GENERAL"
}

我要自定义响应格式,如下所示:

{
    "success": false,
    "message": "Service is down. Please try later"
}

我尝试实现https://stackoverflow.com/a/39841785/5506061,但是它对我不起作用。

请提出如何自定义ZuulException的响应。

1 个答案:

答案 0 :(得分:0)

如果需要,您可以实现自己的FallbackProvider并根据原因自定义响应。

类似:

@Component
public class CustomFallbackBasedOnCause implements FallbackProvider {

private static final String DEFAULT_MSG = "{\"success\": false,\"message\": \"Service is down. Please try later\"}";

@Override
public String getRoute() {
    return "*"; // * = all routes
}

@Override
public ClientHttpResponse fallbackResponse(final Throwable cause) {
    if (cause instanceof HystrixTimeoutException) {
        return response(HttpStatus.GATEWAY_TIMEOUT);
    } else {
        return fallbackResponse();
    }
}

@Override
public ClientHttpResponse fallbackResponse() {
    return response(HttpStatus.INTERNAL_SERVER_ERROR);
}

private ClientHttpResponse response(final HttpStatus status) {
    return new ClientHttpResponse() {
        @Override
        public HttpStatus getStatusCode() throws IOException {
            return status;
        }

        @Override
        public int getRawStatusCode() throws IOException {
            return status.value();
        }

        @Override
        public String getStatusText() throws IOException {
            return status.getReasonPhrase();
        }

        @Override
        public void close() {
        }

        @Override
        public InputStream getBody() throws IOException {
            return new ByteArrayInputStream(DEFAULT_MSG.getBytes());
        }

        @Override
        public HttpHeaders getHeaders() {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            return headers;
        }
    };
}
}

您可以在getRoute()方法中看到,您可以指定此customFallback将用于所有路由(return "*")还是特定路由。

如果您使用注册表服务(例如Eureka)。您没有指定路线URL,而是指定了服务ID。 return "SERVICEID"