小编给大家分享一下微服务feign调用添加token的问题,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!
具体的怎么调用就不说了 如下配置,就可以在请求头中添加需要的请求头信息。
package localdate; import feign.RequestInterceptor; import feign.RequestTemplate; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; 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.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.Map; /** * feign调用服务时,会丢失请求头信息。需要在这里把认证信息收到添加上去 * @author TRON * @since 2019-11-23 * * */ @Configuration @Slf4j public class FeignTokenInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { log.info("======上下文中获取原请求信息======"); String token = "without token"; HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); String HeadValue = request.getHeader(headerName); log.info("===原请求头信息=== headName: {}, headValue: {}", headerName, HeadValue); if (headerName.equals("X-Authorization-access_token")||headerName.equals("x-authorization-access_token")) { token = HeadValue; } } log.info("=======Feign添加头部信息start======"); // requestTemplate.header("X-Authorization-access_token", token); requestTemplate.header("X-Authorization-access_token", "tron123456"); log.info("=======Feign添加头部信息end======"); } }
package localdate; import com.netflix.hystrix.HystrixThreadPoolKey; import com.netflix.hystrix.strategy.HystrixPlugins; import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable; import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle; import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook; import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher; import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy; import com.netflix.hystrix.strategy.properties.HystrixProperty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * 自定义并发策略 * 将现有的并发策略作为新并发策略的成员变量 * 在新并发策略中,返回现有并发策略的线程池、Queue * * hystrix.command.default.execution.isolation.strategy=THREAD * Hystrix的默认隔离策略(官方推荐,当使用该隔离策略时,是没办法拿到 ThreadLocal 中的值的,但是RequestContextHolder 源码中,使用了两个ThreadLocal) * hystrix.command.default.execution.isolation.strategy=SEMAPHORE (将隔离策略改为SEMAPHORE 也可以解决这个问题,但是官方并不推荐这个策略,因为这个策略对网络资源消耗比较大) * * 主要是解决当 Hystrix的默认隔离策略是THREAD时,不能通过RequestContextHolder获取到request对象的问题 * */ //@Configuration public class FeignConfig extends HystrixConcurrencyStrategy { private static final Logger log = LoggerFactory.getLogger(FeignConfig.class); private HystrixConcurrencyStrategy delegate; public FeignConfig() { try { this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy(); if (this.delegate instanceof FeignConfig) { // Welcome to singleton hell... return; } HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance().getCommandExecutionHook(); HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier(); HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher(); HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance().getPropertiesStrategy(); this.logCurrentStateOfHystrixPlugins(eventNotifier, metricsPublisher, propertiesStrategy); HystrixPlugins.reset(); HystrixPlugins.getInstance().registerConcurrencyStrategy(this); HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook); HystrixPlugins.getInstance().registerEventNotifier(eventNotifier); HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher); HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy); } catch (Exception e) { log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e); } } private void logCurrentStateOfHystrixPlugins(HystrixEventNotifier eventNotifier, HystrixMetricsPublisher metricsPublisher, HystrixPropertiesStrategy propertiesStrategy) { if (log.isDebugEnabled()) { log.debug("Current Hystrix plugins configuration is [" + "concurrencyStrategy [" + this.delegate + "]," + "eventNotifier [" + eventNotifier + "]," + "metricPublisher [" + metricsPublisher + "]," + "propertiesStrategy [" + propertiesStrategy + "]," + "]"); log.debug("Registering Sleuth Hystrix Concurrency Strategy."); } } @Override public <T> Callable<T> wrapCallable(Callable<T> callable) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); return new WrappedCallable<>(callable, requestAttributes); } @Override public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { return this.delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } @Override public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) { return this.delegate.getBlockingQueue(maxQueueSize); } @Override public <T> HystrixRequestVariable<T> getRequestVariable(HystrixRequestVariableLifecycle<T> rv) { return this.delegate.getRequestVariable(rv); } static class WrappedCallable<T> implements Callable<T> { private final Callable<T> target; private final RequestAttributes requestAttributes; public WrappedCallable(Callable<T> target, RequestAttributes requestAttributes) { this.target = target; this.requestAttributes = requestAttributes; } @Override public T call() throws Exception { try { RequestContextHolder.setRequestAttributes(requestAttributes); return target.call(); } finally { RequestContextHolder.resetRequestAttributes(); } } } }
feign: client: config: default: connectTimeout: 5000 #连接超时3秒,连接失败时直接调用降级方法 readTimeout: 100000 #连接成功,处理数据的时间限制10秒 100000 读取时间过短会抛异常java.net.SocketTimeoutException: Read timed out loggerLevel: full #日志输出等级 hystrix: enabled: true hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 5000 #服务连接成功,但是时间过长,降级方法调用时间 60000 5000
我只是记录服务提供方、消费方的代码编写,配置什么的大家在网上搜,一大堆。
启动类上加上注解@EnableFeignClients,然后正常的写controller、service等业务逻辑
1.首先启动类上加上注解@EnableFeignClients
2.编写服务调用接口
3.编写接口熔断处理方法
4.本人遇到的问题是需要用到调用方的请求头里面的信息,但是在提供方取不到,这时可以通过在调用方增加配置来解决
import feign.RequestInterceptor; import feign.RequestTemplate; import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; /** * @author ydf * @date 2021/5/13 * @description: **/ public class FeignBasicAuthRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder .getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); Enumeration<String> headerNames = request.getHeaderNames(); if (headerNames != null) { while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); String values = request.getHeader(name); requestTemplate.header(name, values); } } } }
import com.jingling.netsign.applet.interceptor.FeignBasicAuthRequestInterceptor; import feign.RequestInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @author ydf * @date 2021/5/13 * @description: **/ @Configuration public class FeignSupportConfig { /** * feign请求拦截器 * * @return */ @Bean public RequestInterceptor requestInterceptor(){ return new FeignBasicAuthRequestInterceptor(); } }
看完了这篇文章,相信你对“微服务feign调用添加token的问题”有了一定的了解,如果想了解更多相关知识,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。