结构如下
1、api
ProcessFeignApi
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import .provider.Feign.hystrix.ProcessFeignApiHystrix;
import Interceptor.OrderInterceptor;
@FeignClient(value = "调用的服务名",configuration=OrderInterceptor.class,fallbackFactory =ProcessFeignApiHystrix.class)
public interface ProcessFeignApi {
@GetMapping("/process/hello")
String hello();
}
ProcessFeignApiHystrix 熔断
import org.springframework.stereotype.Component;
import ProcessFeignApi;
import feign.hystrix.FallbackFactory;
@Component
public class ProcessFeignApiHystrix implements FallbackFactory<ProcessFeignApi> {
@Override
public ProcessFeignApi create(Throwable cause) {
String msg = cause == null ? "" : cause.getMessage();
return new ProcessFeignApi() {
@Override
public String hello() {
return "服务降级"+msg;
}
};
}
}
OrderInterceptor 配置类
import java.util.Enumeration;
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;
@Component//将本类交由spring管理
public class OrderInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
/*
* 获取原线程的request对象的请求头中的token
* RequestContextHolder.getRequestAttributes():获取request原始的请求头对象
* 接口类RequestAttributes不能使用,所以强转为ServletRequestAttributes类型
*/
ServletRequestAttributes servletRequestAttributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//防止空指针
if (servletRequestAttributes==null) {
return;
}
//获取原Request对象
HttpServletRequest request = servletRequestAttributes.getRequest();
//把原request的请求头的所有参数都拿出来
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
//获取每个请求头参数的名字
String name = headerNames.nextElement();
//获取值
String value = request.getHeader(name);
//放到feign调用对象的request中去
requestTemplate.header(name,value);
}
}
}
pom配置
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2、客户端
@Autowired
private ProcessFeignApi api;
@PostMapping(value="/testFeign")
public String testFeign(){
String resutl= api.hello();
return result;
}
客户端中pom引入api配置,才能调用api接口
<dependency>
<groupId>com.XXX</groupId>
<artifactId>XXX-provider-api</artifactId>
<version>V1.0</version>
</dependency>
3、服务端
简单的测试接口
@GetMapping(value = "/hello")
public String hello() {
return "aaaaaaa";
}
遇到的问题
1、401 , {“error”:“unauthorized”,“error_description”:“Full authentication is required to access this resource”}
疑似token无法传递过去被调用的服务导致报错,参考OrderInterceptor
经查询解决办法是设置配置类,手动传递token信息
2、配置了上述内容之后还是报错,RequestContextHolder.getRequestAttributes()获取不到内容,为null。这是由于hystrix的隔离策略导致的,详见以下文章
连接1
连接2
连接3
解决以上问题后即可调用服务