简体   繁体   中英

How to handle 404 error when using Spring Cloud Gateway

Application I'm working serving static files of a frontend application inside the spring cloud gateway. At the moment any route other than the predefined once are ended up being 404 as expected.

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

How ever, what I'm expecting is to handle the 404 error and serve the index.html for all the failing GET requests.

I tried to add the /error mapping. However on client, it still shows the Whitelabel Error Page for 404.

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

The request mappings are basically copied from the source code of BasicErrorController. See 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

The @ResponseBody annotation is needed because the method is returning a string. The other two @RequestMapping annotations are directly copied from the source code.

In Spring Cloud Gateway you should extend AbstractErrorWebExceptionHandler. As you're using RouterFunction i guessed webflux involved there. 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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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