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.