>Java >java지도 시간 >Spring Cloud Gateway의 전역 예외 처리 소개(코드 예)

Spring Cloud Gateway의 전역 예외 처리 소개(코드 예)

不言
不言앞으로
2019-03-06 15:46:503054검색

이 기사에서는 Spring Cloud Gateway의 전역 예외 처리(코드 예제)에 대해 소개합니다. 이는 특정 참조 가치가 있으므로 도움이 필요한 친구에게 도움이 되기를 바랍니다.

Spring Cloud Gateway의 전역 예외 처리는 @ControllerAdvice를 사용하여 직접 처리할 수 없습니다. 발생한 예외 정보를 추적하여 해당 소스 코드를 찾고 비즈니스 요구 사항에 맞게 일부 처리 논리를 사용자 정의하세요.

게이트웨이는 인터페이스의 프록시 전달자이고 백엔드는 REST API에 해당하며 반환 데이터 형식은 JSON입니다. 처리가 이루어지지 않은 경우 예외가 발생하면 게이트웨이에서 제공하는 기본 오류 메시지는 프런트 엔드에서 예외를 처리하기에는 불편한 페이지입니다.

예외 정보를 처리하고 JSON 형식의 데이터를 클라이언트에 반환해야 합니다. 먼저 구현된 코드를 살펴보고, 그다음 주의할 점을 알려드리겠습니다.

사용자 정의된 예외 처리 논리:

package com.cxytiandi.gateway.exception;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
/**
 * 自定义异常处理
 * 
 * <p>异常时用JSON代替HTML异常信息<p>
 * 
 * @author yinjihuan
 *
 */
public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler {

    public JsonExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
            ErrorProperties errorProperties, ApplicationContext applicationContext) {
        super(errorAttributes, resourceProperties, errorProperties, applicationContext);
    }

    /**
     * 获取异常属性
     */
    @Override
    protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
        int code = 500;
        Throwable error = super.getError(request);
        if (error instanceof org.springframework.cloud.gateway.support.NotFoundException) {
            code = 404;
        }
        return response(code, this.buildMessage(request, error));
    }
    /**
     * 指定响应处理方法为JSON处理的方法
     * @param errorAttributes
     */
    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
    }

    /**
     * 根据code获取对应的HttpStatus
     * @param errorAttributes
     */
    @Override
    protected HttpStatus getHttpStatus(Map<String, Object> errorAttributes) {
        int statusCode = (int) errorAttributes.get("code");
        return HttpStatus.valueOf(statusCode);
    }

    /**
     * 构建异常信息
     * @param request
     * @param ex
     * @return
     */
    private String buildMessage(ServerRequest request, Throwable ex) {
        StringBuilder message = new StringBuilder("Failed to handle request [");
        message.append(request.methodName());
        message.append(" ");
        message.append(request.uri());
        message.append("]");
        if (ex != null) {
            message.append(": ");
            message.append(ex.getMessage());
        }
        return message.toString();
    }

    /**
     * 构建返回的JSON数据格式
     * @param status        状态码
     * @param errorMessage  异常信息
     * @return
     */
    public static Map<String, Object> response(int status, String errorMessage) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", status);
        map.put("message", errorMessage);
        map.put("data", null);
        return map;
    }

}

기본 구성 재정의:

package com.cxytiandi.gateway.exception;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.result.view.ViewResolver;
/**
 * 覆盖默认的异常处理
 * 
 * @author yinjihuan
 *
 */
@Configuration
@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
public class ErrorHandlerConfiguration {

    private final ServerProperties serverProperties;

    private final ApplicationContext applicationContext;

    private final ResourceProperties resourceProperties;

    private final List<ViewResolver> viewResolvers;

    private final ServerCodecConfigurer serverCodecConfigurer;

    public ErrorHandlerConfiguration(ServerProperties serverProperties,
                                     ResourceProperties resourceProperties,
                                     ObjectProvider<List<ViewResolver>> viewResolversProvider,
                                     ServerCodecConfigurer serverCodecConfigurer,
                                     ApplicationContext applicationContext) {
        this.serverProperties = serverProperties;
        this.applicationContext = applicationContext;
        this.resourceProperties = resourceProperties;
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
        JsonExceptionHandler exceptionHandler = new JsonExceptionHandler(
                errorAttributes, 
                this.resourceProperties,
                this.serverProperties.getError(), 
                this.applicationContext);
        exceptionHandler.setViewResolvers(this.viewResolvers);
        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
        return exceptionHandler;
    }
    
}

Notes

  • 예외 발생 시 HTML 대신 JSON을 반환하는 방법은 무엇입니까?

org.springframework.boot.autoconfigure.web.reactive에서. error .DefaultErrorWebExceptionHandler의 getRoutingFunction() 메서드는 반환 형식을 제어합니다. 원래 코드는 다음과 같습니다.

@Override
protected RouterFunction<ServerResponse> getRoutingFunction(
            ErrorAttributes errorAttributes) {
       return RouterFunctions.route(acceptsTextHtml(), this::renderErrorView)
                .andRoute(RequestPredicates.all(), this::renderErrorResponse);
}

여기서 우선순위는 HTML로 표시하는 것입니다.

protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
       return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
  • getHttpStatus를 재설정해야 합니다.

의 원래 작성 방법은 상태를 통해 해당 HttpStatus를 얻는 것입니다. 코드는 다음과 같습니다.

protected HttpStatus getHttpStatus(Map<String, Object> errorAttributes) {
      int statusCode = (int) errorAttributes.get("status");
      return HttpStatus.valueOf(statusCode);
}

우리가 정의한 형식에 상태 필드가 없으면 오류가 발생합니다. 보고했는데 해당 응답 코드를 찾을 수 없거나 데이터가 반환됩니다. 형식에 상태 하위 섹션을 추가하거나 다시 작성하세요. 여기서 반환하는 것은 코드이므로 코드를 다시 작성해야 합니다.

@Override
protected HttpStatus getHttpStatus(Map<String, Object> errorAttributes) {
    int statusCode = (int) errorAttributes.get("code");
    return HttpStatus.valueOf(statusCode);
}

위 내용은 Spring Cloud Gateway의 전역 예외 처리 소개(코드 예)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제