[英]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.