我尝试使用 Feign 解决以下问题:
我发现执行此操作的唯一方法是返回此处指定的
feign.Response
对象:How to read header value from feign Response
因此,我实现了以下客户端(在 Kotlin 中),调用该客户端的服务可以从返回的
feign.Response
中提取标头值。我不想将 feign.Response
返回给呼叫服务,但我看不到其他方法。
@FeignClient(
name = "doSomething",
url = "\${doSomething.baseUrl}",
configuration = [DoSomethingClientConfiguration::class]
)
interface DoSomethingClient {
@PostMapping(value = ["/create-something"], consumes = [APPLICATION_JSON_VALUE])
fun createSomething(thingToCreate: ThingToCreate) : feign.Response
}
我遇到的问题如下:由于
createSomething(...
方法现在返回一个feign.Response
,我的ErrorDecoder
中定义的默认Retryer.Default
和DoSomethingClientConfiguration
被绕过,并且 feign.Response
(在本例中为 404
)返回到调用服务来处理它,这是不可取的。
我正在寻找的解决方案是一种更智能的方法来返回
feign.Response
标头值,而不必返回feign.Response
本身,这会导致它绕过默认行为。
有什么想法吗?
您可以实现自己的解码器和“Response”类,或者使用 spring-cloud-starter-openfeign org.springframework.http.ResponseEntity 中的一个
package backend.core.circuitbreak;
import java.util.Enumeration;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class FeignRequestInterceptor implements RequestInterceptor
{
@PostConstruct
private void init()
{
log.info("Interceptor that copies the header of a request was initialized");
}
@Override
public void apply(RequestTemplate requestTemplate)
{
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
if (requestAttributes == null)
{
return;
}
HttpServletRequest request = requestAttributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements())
{
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
log.debug("Copy header {} {}", headerName, headerValue);
requestTemplate.header(headerName, headerValue);
}
}
}