我使用 Spring Cloud Gateway (MVC) 作为我的前端 (SPA) 和后端之间的 BFF。 一切都按预期工作,但如果后端返回错误(例如 409), 网关返回 500 并带有 HTML 作为响应。
深入挖掘,我发现以下错误:
2024-10-23T16:30:47.804+02:00 ERROR 31792 --- [edepot-api-gateway] [nio-7081-exec-6] o.a.c.c.C.[Tomcat].[localhost] : Exception Processing [ErrorPage[errorCode=0, location=/error]]
jakarta.servlet.ServletException: Request processing failed: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:4200/error": http://localhost:4200/error
其原因是:
java.io.FileNotFoundException: http://localhost:4200/error
但是来自后端的错误被正确接收(日志在上面之前):
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:8080/api/x": Server returned HTTP response code: 409 for URL: http://localhost:8080/api/x
我想知道这是否与 Tomcat 错误处理有关,或者网关配置错误有关? 奇怪的是它返回 HTML 而不是 JSON。
这是我的网关配置:
spring.cloud.gateway.mvc.routes[0].id=api
spring.cloud.gateway.mvc.routes[0].uri=${backend-uri}
spring.cloud.gateway.mvc.routes[0].predicates[0]=Path=/api/**
spring.cloud.gateway.mvc.routes[0].filters[0].name=DedupeResponseHeader
spring.cloud.gateway.mvc.routes[0].filters[0].args[name]=Access-Control-Allow-Credentials Access-Control-Allow-Origin
spring.cloud.gateway.mvc.routes[0].filters[1].name=TokenRelay
//spring.cloud.gateway.mvc.routes[1] irrelevant
#Frontend routes
spring.cloud.gateway.mvc.routes[2].id=frontend
spring.cloud.gateway.mvc.routes[2].uri=${frontend-uri}
spring.cloud.gateway.mvc.routes[2].predicates=Path=/**
# Forwarding support
spring.cloud.gateway.mvc.http-client.type=autodetect
spring.cloud.gateway.mvc.http-client.connect-timeout=60s
spring.cloud.gateway.mvc.http-client.read-timeout=60s
#spring.cloud.mvc.discovery.enabled=true
默认的 JDK HttpClient 似乎无法正常工作。由于以下配置,因此使用了 HttpUrlConnection。
确保未配置:
spring.cloud.gateway.mvc.http-client.type=autodetect
如果它仍然不起作用(因为我在使用默认 HttpClient 时遇到转发问题),您可以使用替代客户端:
应用程序属性:
spring.cloud.gateway.mvc.http-client.type=autodetect
pom.xml:
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>