繁体   English   中英

使用Spring云网关时如何处理404错误

[英]How to handle 404 error when using Spring Cloud Gateway

应用程序 我正在为 spring 云网关内的前端应用程序的 static 文件提供服务。 目前,除了预定义的一次之外,任何路线最终都如预期的那样成为 404。

@Bean
public RouterFunction<ServerResponse> htmlRemoteAppointmentRouter(
      @Value("classpath:/static/index.html")
      Resource html) {
    return route(GET("/"), request -> ok().contentType(MediaType.TEXT_HTML).bodyValue(html))
        .andRoute(GET("/home/{*path}"), request -> ok().contentType(MediaType.TEXT_HTML).bodyValue(html))
        .andRoute(GET("/user/{*path}"), request -> ok().contentType(MediaType.TEXT_HTML).bodyValue(html));
}

但是,我期望的是处理 404 错误并为所有失败的 GET 请求提供 index.html 。

我尝试添加/error映射。 但是在客户端,它仍然显示 404 的Whitelabel Error Page

@Controller
public class ErrorHandler implements ErrorController {
    @RequestMapping("/error")
    public String something() {
        return "error";
    }
}
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class ErrorHandler implements ErrorController {

    @ResponseBody
    @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
    public String errorHtml() {
        return "custom error controller";
    }
}

请求映射基本上是从 BasicErrorController 的源代码中复制而来的。 https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet /error/BasicErrorController.java

需要@ResponseBody注释,因为该方法返回一个字符串。 另外两个@RequestMapping注解是直接从源码中复制过来的。

在 Spring 云网关中,您应该扩展 AbstractErrorWebExceptionHandler。 当您使用 RouterFunction 时,我猜想那里涉及 webflux。 The next example is extracted from spring boot (v2.7.3) docs ( https://docs.spring.io/spring-boot/docs/2.7.3/reference/htmlsingle/#web.reactive.webflux.error-handling ) :

@Component
public class MyErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
    
    public MyErrorWebExceptionHandler(ErrorAttributes errorAttributes, Resources resources, ApplicationContext applicationContext) {
        super(errorAttributes, resources, applicationContext);
    }
    
    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return RouterFunctions.route(this::acceptsXml, this::handleErrorAsXml);
    }
    
    private boolean acceptsXml(ServerRequest request) {
        return request.headers().accept().contains(MediaType.APPLICATION_XML);
    }
    
    public Mono<ServerResponse> handleErrorAsXml(ServerRequest request) {
        BodyBuilder builder = ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR);
        // ... additional builder calls
        return builder.build();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM