Heim  >  Artikel  >  Java  >  Einführung in die globale Ausnahmebehandlung von Spring Cloud Gateway (Codebeispiel)

Einführung in die globale Ausnahmebehandlung von Spring Cloud Gateway (Codebeispiel)

不言
不言nach vorne
2019-03-06 15:46:503010Durchsuche

Dieser Artikel bietet Ihnen eine Einführung in die globale Ausnahmebehandlung (Codebeispiele). Ich hoffe, dass er für Freunde hilfreich ist.

Die globale Ausnahmebehandlung in Spring Cloud Gateway kann nicht direkt mit @ControllerAdvice behandelt werden, indem Sie die ausgelösten Ausnahmeinformationen verfolgen, den entsprechenden Quellcode finden und einige Verarbeitungslogiken an die Geschäftsanforderungen anpassen.

Das Gateway ist ein Proxy-Forwarder für die Schnittstelle, das Backend entspricht der REST-API und das Rückgabedatenformat ist JSON. Wenn keine Verarbeitung erfolgt und eine Ausnahme auftritt, ist die vom Gateway ausgegebene Standardfehlermeldung die Seite, was für das Front-End bei der Behandlung von Ausnahmen unpraktisch ist.

Muss Ausnahmeinformationen verarbeiten und Daten im JSON-Format an den Client zurückgeben. Schauen wir uns zunächst den implementierten Code an, dann erkläre ich Ihnen, worauf Sie achten müssen.

Benutzerdefinierte Ausnahmebehandlungslogik:

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;
    }

}

Überschreiben Sie die Standardkonfiguration:

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;
    }
    
}

Hinweise

  • So geben Sie bei einer Ausnahme JSON anstelle von HTML zurück Tritt auf ?

Die Methode getRoutingFunction() in org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler steuert das Rückgabeformat wie folgt:

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

Diese Edge-Priorität wird in HTML angezeigt. Wenn Sie JSON verwenden möchten, können Sie sie wie folgt ändern:

protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
       return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
  • getHttpStatus muss neu geschrieben werden

Das Original Methode ist durch status Um den entsprechenden HttpStatus zu erhalten, lautet der Code wie folgt:

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

Wenn in dem von uns definierten Format kein Statusfeld vorhanden ist, wird ein Fehler gemeldet und der entsprechende Antwortcode kann nicht gefunden werden, oder Der Status-Unterabschnitt wird zum zurückgegebenen Datenformat hinzugefügt oder neu geschrieben. Was ich zurückgebe, ist Code, also muss ich ihn neu schreiben. Der Code lautet wie folgt:

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

Das obige ist der detaillierte Inhalt vonEinführung in die globale Ausnahmebehandlung von Spring Cloud Gateway (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen