在请求拦截器中统一配置
适用于当一个调用链涉及到多个微服务,一些参数需要在整个调用链中传递。比如为了安全每个服务都需要对请求头中token的校验。
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
/**
* 请求拦截器,将原始请求header中数据原样通过feign传输
*
* @Author xiyang
* @Date 2022/10/21
*/
@Slf4j
@Configuration
public class FeignConfig implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
// 从MQ收到消息时需要RPC
log.info("requestAttributes is null");
return;
}
ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes;
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
// 跳过 content-length, 防止RPC时参数长度与请求时不一致
if ("content-length".equalsIgnoreCase(name)) {
continue;
}
requestTemplate.header(name, values);
}
}
}
}
然后在feignClient中配置自定义的配置类,覆盖默认的配置
@FeignClient(value = "service-name", configuration = FeignConfig.class)
public interface FeignTest {
}
通过@RequestHeader注解
有时候我们需要传一些自定义的header参数,而不需要传全部header参数,只需要在调用的接口上添加@RequestHeader注解,Feign调用时,会自动封装成header参数
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
@FeignClient(value = "service-name")
public interface FeignTest {
/**
* 通过 @RequestHeader 将参数封装到HTTP header中
*
* @param token
* @param msgId
*/
@GetMapping(value = "/test")
void test(@RequestHeader("x-token") String token, @RequestHeader("x-msgId") String msgId);
}