Feign HATEOS 响应包含错误的服务器、端口信息
Feign HATEOS response contains wrong server,port information
我正在 Spring Cloud 上工作并使用 Josh Long 在
的示例项目
Bootiful Microservice by Josh Long
有一个 API 网关 reservation-client 使用来自服务 reservation-service 的数据,它提供了一个 HATEOAS响应,然后转换为简单的 JSON 响应。
@RestController
@RequestMapping("/reservations")
class ReservationApiGateway {
方法:
@HystrixCommand(fallbackMethod = "fallback")
@RequestMapping(method = RequestMethod.GET, value = "/names")
public Collection<String> names() {
return this.reservationReader
.read()
.getContent()
.stream()
.map(Reservation::getReservationName)
.collect(Collectors.toList());
}
我修改它以像这样向我转发 HATEOAS 响应。
@HystrixCommand(fallbackMethod = "fallback")
@RequestMapping(method = RequestMethod.GET, value = "/names")
public Resources<Resource<Reservation>> names() {
return this.reservationReader
.read();
}
这给了我一个 HATEAOS 响应,但链接全部来自 reservation-service - 。
"_links" : {
"self" : {
"href" : "**http://192.168.0.3:7000/reservations/1**"
},
"reservation" : {
"href" : "http://192.168.0.3:7000/reservations/1"
}
}
如何确保 Feign 更新 API 网关的服务器和端口的链接? - http://192.168.0.3:9999/reservations/1
来自预订客户端的相同响应(与预订服务相同):
{
"_embedded" : {
"reservations" : [ {
"reservationName" : "Josh",
"_links" : {
"self" : {
"href" : "http://192.168.0.3:7000/reservations/1"
},
"reservation" : {
"href" : "http://192.168.0.3:7000/reservations/1"
}
}
}, {
"reservationName" : "Dr. Johnson",
"_links" : {
"self" : {
"href" : "http://192.168.0.3:7000/reservations/2"
},
"reservation" : {
"href" : "http://192.168.0.3:7000/reservations/2"
}
}
}, {
"reservationName" : "Dr. Syer",
"_links" : {
"self" : {
"href" : "http://192.168.0.3:7000/reservations/3"
},
"reservation" : {
"href" : "http://192.168.0.3:7000/reservations/3"
}
}
}, {
"reservationName" : "Dr. Pollack",
"_links" : {
"self" : {
"href" : "http://192.168.0.3:7000/reservations/4"
},
"reservation" : {
"href" : "http://192.168.0.3:7000/reservations/4"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://192.168.0.3:7000/reservations{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://192.168.0.3:7000/profile/reservations"
},
"search" : {
"href" : "http://192.168.0.3:7000/reservations/search"
}
}
}
我明白了。
解决方案在 X-Forwarded-Host http header 中。 X-Forwarded-Host 实质上告诉 Spring 任何具有此 header 的 HATEOS 响应,链接中的主机和端口信息应更新为 X-Forwarded-Host http header。
所以,在 API 网关 reservation-client 代码中,我添加了这个拦截 Feign 对后端服务 reservation-service 的调用的代码片段,并将 http header 添加到要求。
@Component
class LanguageRequestInterceptor implements RequestInterceptor {
private static final String X_FORWARDED_HOST = "X-Forwarded-Host";
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
return;
}
HttpServletRequest request = requestAttributes.getRequest();
if (request == null) {
return;
}
requestTemplate.header(X_FORWARDED_HOST, "localhost:9999");
}
}
现在,所有 HATOES 响应都有 API 网关的主机和端口信息,而不是后端 HATEOS 服务。
我正在 Spring Cloud 上工作并使用 Josh Long 在
的示例项目Bootiful Microservice by Josh Long
有一个 API 网关 reservation-client 使用来自服务 reservation-service 的数据,它提供了一个 HATEOAS响应,然后转换为简单的 JSON 响应。
@RestController
@RequestMapping("/reservations")
class ReservationApiGateway {
方法:
@HystrixCommand(fallbackMethod = "fallback")
@RequestMapping(method = RequestMethod.GET, value = "/names")
public Collection<String> names() {
return this.reservationReader
.read()
.getContent()
.stream()
.map(Reservation::getReservationName)
.collect(Collectors.toList());
}
我修改它以像这样向我转发 HATEOAS 响应。
@HystrixCommand(fallbackMethod = "fallback")
@RequestMapping(method = RequestMethod.GET, value = "/names")
public Resources<Resource<Reservation>> names() {
return this.reservationReader
.read();
}
这给了我一个 HATEAOS 响应,但链接全部来自 reservation-service - 。
"_links" : {
"self" : {
"href" : "**http://192.168.0.3:7000/reservations/1**"
},
"reservation" : {
"href" : "http://192.168.0.3:7000/reservations/1"
}
}
如何确保 Feign 更新 API 网关的服务器和端口的链接? - http://192.168.0.3:9999/reservations/1
来自预订客户端的相同响应(与预订服务相同):
{
"_embedded" : {
"reservations" : [ {
"reservationName" : "Josh",
"_links" : {
"self" : {
"href" : "http://192.168.0.3:7000/reservations/1"
},
"reservation" : {
"href" : "http://192.168.0.3:7000/reservations/1"
}
}
}, {
"reservationName" : "Dr. Johnson",
"_links" : {
"self" : {
"href" : "http://192.168.0.3:7000/reservations/2"
},
"reservation" : {
"href" : "http://192.168.0.3:7000/reservations/2"
}
}
}, {
"reservationName" : "Dr. Syer",
"_links" : {
"self" : {
"href" : "http://192.168.0.3:7000/reservations/3"
},
"reservation" : {
"href" : "http://192.168.0.3:7000/reservations/3"
}
}
}, {
"reservationName" : "Dr. Pollack",
"_links" : {
"self" : {
"href" : "http://192.168.0.3:7000/reservations/4"
},
"reservation" : {
"href" : "http://192.168.0.3:7000/reservations/4"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://192.168.0.3:7000/reservations{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://192.168.0.3:7000/profile/reservations"
},
"search" : {
"href" : "http://192.168.0.3:7000/reservations/search"
}
}
}
我明白了。
解决方案在 X-Forwarded-Host http header 中。 X-Forwarded-Host 实质上告诉 Spring 任何具有此 header 的 HATEOS 响应,链接中的主机和端口信息应更新为 X-Forwarded-Host http header。
所以,在 API 网关 reservation-client 代码中,我添加了这个拦截 Feign 对后端服务 reservation-service 的调用的代码片段,并将 http header 添加到要求。
@Component
class LanguageRequestInterceptor implements RequestInterceptor {
private static final String X_FORWARDED_HOST = "X-Forwarded-Host";
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
return;
}
HttpServletRequest request = requestAttributes.getRequest();
if (request == null) {
return;
}
requestTemplate.header(X_FORWARDED_HOST, "localhost:9999");
}
}
现在,所有 HATOES 响应都有 API 网关的主机和端口信息,而不是后端 HATEOS 服务。