最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot Feign服務(wù)調(diào)用之間帶token問(wèn)題

 更新時(shí)間:2021年09月15日 09:54:18   作者:如漩渦  
這篇文章主要介紹了Spring Boot Feign服務(wù)調(diào)用之間帶token的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Feign服務(wù)調(diào)服務(wù)傳遞數(shù)據(jù)帶token驗(yàn)證

Feign服務(wù)調(diào)服務(wù)就不多做介紹了,值得提醒的是,F(xiàn)eign服務(wù)調(diào)服務(wù)傳遞數(shù)據(jù)的時(shí)候,比如某用戶服務(wù)是需要帶token驗(yàn)證的,而調(diào)用那個(gè)用戶服務(wù)的時(shí)候報(bào)錯(cuò),提示token為空,是因?yàn)镕eign請(qǐng)求的時(shí)候沒(méi)有帶上token

解決方式

要解決這個(gè)問(wèn)題,想必能猜到最方便的就是往請(qǐng)求頭里加上token,一起帶過(guò)去

Feign有提供一個(gè)接口,RequestInterceptor

只要實(shí)現(xiàn)這個(gè)接口,簡(jiǎn)單做一些處理,比如說(shuō)我們驗(yàn)證請(qǐng)求頭的token叫Access-Token,我們就先取出當(dāng)前請(qǐng)求的token,然后放到feign請(qǐng)求頭上

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
 * Feign配置
 * 使用FeignClient進(jìn)行服務(wù)間調(diào)用,傳遞headers信息
 */
@Configuration
public class FeignConfig implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //添加token
        requestTemplate.header("Access-Token", request.getHeader("Access-Token"));
    }
}

這樣已經(jīng)成功往Feign請(qǐng)求頭里加上了Token,還可以這樣,為了方便本地調(diào)試,可以在Spring Boot加上過(guò)濾器,每次本地調(diào)用沒(méi)有Token的時(shí)候加上一個(gè),只要實(shí)現(xiàn)Spring提供的Filter接口

import org.apache.commons.lang3.StringUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
/**
 * 每次請(qǐng)求過(guò)濾器攔截加Token
 */
public class AddTokenFilter implements Filter {
    /**
     * superAdmin
     */
    private static final String DEFAULT_TOKEN = "你的token";
    private String profilesActive;
    public AddTokenFilter(String profilesActive) {
        super();
        this.profilesActive = profilesActive;
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
     //判斷是開(kāi)發(fā)模式(dev)還是生產(chǎn)壞境(pro)
     //如果不是開(kāi)發(fā)壞境,不做任何操作,是開(kāi)發(fā)壞境,往本地測(cè)試的request加請(qǐng)求頭
        if (profilesActive == null || !EnumEnvType.DEV.toString().equalsIgnoreCase(profilesActive)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        filterChain.doFilter(new CustomeizedRequest((HttpServletRequest) servletRequest), servletResponse);
    }
    @Override
    public void destroy() {
    }
//繼承HttpServletRequestWrapper ,重寫(xiě)getHeader獲取請(qǐng)求頭的值
    private class CustomeizedRequest extends HttpServletRequestWrapper {
        /**
         * Constructs a request object wrapping the given request.
         *
         * @param request
         * @throws IllegalArgumentException if the request is null
         */
        public CustomeizedRequest(HttpServletRequest request) {
            super(request);
        }
        @Override
        public String getHeader(String name) {
            if (!Constant.HTTP_HEADER_ACCESS_TOKEN.equalsIgnoreCase(name)) {
                return super.getHeader(name);
            }
            String token = super.getHeader(name);
            return StringUtils.isNotBlank(token) ? token : DEFAULT_TOKEN;
        }
    }
}

使用這個(gè)Filter很簡(jiǎn)單,新建一個(gè)WebMvcConfig類,配置一個(gè)bean

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.uhope.rl.watersource.filter.AddTokenFilter;
import com.uhope.rl.watersource.filter.ServiceFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.nio.charset.Charset;
/**
 * Spring MVC 配置
 * @author chenbin on 2017/12/25
 * @version 3.0.0
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    private final Logger logger = LoggerFactory.getLogger(WebMvcConfig.class);
    /**
     * 當(dāng)前激活的配置文件
     */
    @Value("${spring.profiles.active}")
    private String env;
    /**
     * 解決路徑資源映射問(wèn)題
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    }
    /**
     * 使用fastJson代替Jackjson解析JSON數(shù)據(jù)
     *
     * @return
     */
    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverters() {
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        /*
         * 轉(zhuǎn)換為JSON字符串,默認(rèn):
         * WriteNullListAsEmpty    List字段如果為null,輸出為[],而非null
         * WriteNullStringAsEmpty  字符類型字段如果為null,輸出為”“,而非null
         * WriteMapNullValue       是否輸出值為null的字段,默認(rèn)為false
         */
        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);
        fastConverter.setFastJsonConfig(fastJsonConfig);
        fastConverter.setDefaultCharset(Charset.forName("UTF-8"));
        HttpMessageConverter<?> converter = fastConverter;
        return new HttpMessageConverters(converter);
    }
    /**
     * 這個(gè)Filter 解決頁(yè)面跨域訪問(wèn)問(wèn)題
     */
    @Bean
    public FilterRegistrationBean omsFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new ServiceFilter());
        registration.addUrlPatterns("/*");
        registration.setName("MainFilter");
        registration.setAsyncSupported(true);
        registration.setOrder(1);
        return registration;
    }
    /**
     * 這個(gè)Filter 添加token
     */
    @Bean
    public FilterRegistrationBean addTokenFilter(){
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new AddTokenFilter(env));
        registration.addUrlPatterns("/*");
        registration.setName("addTokenFilter");
        registration.setAsyncSupported(true);
        registration.setOrder(2);
        return registration;
    }
}

小結(jié)一下

這樣就實(shí)現(xiàn)了開(kāi)發(fā)壞境下添加本地測(cè)試的token,若不是開(kāi)發(fā)壞境,用網(wǎng)頁(yè)請(qǐng)求過(guò)來(lái)的token,很方便,也解決了Feign丟失請(qǐng)求頭的問(wèn)題

Feign調(diào)用進(jìn)行token鑒權(quán)

1、項(xiàng)目場(chǎng)景

這邊使用 兩個(gè)springboot應(yīng)用,中間通過(guò)feign來(lái)進(jìn)行遠(yuǎn)程調(diào)用(是的沒(méi)錯(cuò),架構(gòu)就是這么奇葩)。然后在調(diào)用feign的時(shí)候,希望可以進(jìn)行token鑒權(quán)。

2、解決辦法

請(qǐng)求進(jìn)來(lái)時(shí),通過(guò)攔截器,校驗(yàn)header的token,然后在業(yè)務(wù)中調(diào)用feignClient時(shí),通過(guò)新加一個(gè)feign攔截器,攔截feign請(qǐng)求,把當(dāng)前的header中的token添加到feign的請(qǐng)求頭中去。實(shí)現(xiàn)token在鏈路中的傳遞。

3、具體實(shí)現(xiàn)

新增 feign 攔截器配置

/**
 * Feign請(qǐng)求攔截器配置.
 *
 * @author linzp
 * @version 1.0.0
 * @date 2021/4/16 21:19
 */
@Configuration
public class FeignInterceptorConfig implements RequestInterceptor {
    public FeignInterceptorConfig() {}
    @Override
    public void apply(RequestTemplate template) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //設(shè)置token到請(qǐng)求頭
        template.header(ConstantCommon.HEADER_TOKEN_KEY, request.getHeader(ConstantCommon.HEADER_TOKEN_KEY));
    }
}

然后在feignClient接口中,添加 == configuration = FeignInterceptorConfig.class==

注意有Bug?。。?/strong>

注意?。?!,這里會(huì)有個(gè)異常,獲取到的request會(huì)是null。原因是hytrix隔離策略是thread,無(wú)法讀到 threadLocal變量。

解決辦法!!更改策略

在配置文件中新增如下配置,即可解決!

# 更換hystrix策略,解決無(wú)法傳遞threadLocal變量問(wèn)題
hystrix:
    command:
        default:
            execution:
                isolation:
                    strategy: SEMAPHORE

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • JAVA調(diào)用JavaScript的方法示例

    JAVA調(diào)用JavaScript的方法示例

    本文主要介紹了JAVA調(diào)用JavaScript的方法示例,主要介紹了兩種方式,一種是使用Java的ScriptEngine接口,另一種是使用Java的URLConnection類來(lái)獲取JS文件,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • Java詳細(xì)講解Math和Random類中有哪些常用方法

    Java詳細(xì)講解Math和Random類中有哪些常用方法

    Math類位于java.lang包中,包含很多用于科學(xué)計(jì)算的類方法,這些方法可以直接通過(guò)類名調(diào)用。Random類獲取隨機(jī)數(shù),位于java.util包中,本篇帶你了解它們的常用方法
    2022-05-05
  • Java 構(gòu)造方法的使用詳解

    Java 構(gòu)造方法的使用詳解

    構(gòu)造方法是類的一種特殊方法,用來(lái)初始化類的一個(gè)新的對(duì)象,在創(chuàng)建對(duì)象(new 運(yùn)算符)之后自動(dòng)調(diào)用。Java 中的每個(gè)類都有一個(gè)默認(rèn)的構(gòu)造方法,并且可以有一個(gè)以上的構(gòu)造方法
    2021-11-11
  • java線程并發(fā)blockingqueue類使用示例

    java線程并發(fā)blockingqueue類使用示例

    BlockingQueue是一種特殊的Queue,若BlockingQueue是空的,從BlockingQueue取東西的操作將會(huì)被阻斷進(jìn)入等待狀態(tài)直到BlocingkQueue進(jìn)了新貨才會(huì)被喚醒,下面是用BlockingQueue來(lái)實(shí)現(xiàn)Producer和Consumer的例子
    2014-01-01
  • 解決MyBatis中Enum字段參數(shù)解析問(wèn)題

    解決MyBatis中Enum字段參數(shù)解析問(wèn)題

    本文主要介紹了解決MyBatis中Enum字段參數(shù)解析問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • java多態(tài)實(shí)現(xiàn)電子寵物系統(tǒng)

    java多態(tài)實(shí)現(xiàn)電子寵物系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java多態(tài)實(shí)現(xiàn)電子寵物系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 常見(jiàn)的java面試題

    常見(jiàn)的java面試題

    這篇文章主要為大家詳細(xì)介紹了常見(jiàn)的java面試題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • java 代理機(jī)制的實(shí)例詳解

    java 代理機(jī)制的實(shí)例詳解

    這篇文章主要介紹了java 代理機(jī)制的實(shí)例詳解的相關(guān)資料,這里說(shuō)明下如何實(shí)現(xiàn)代理機(jī)制,幫助大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-08-08
  • Spring Boot使用過(guò)濾器和攔截器分別實(shí)現(xiàn)REST接口簡(jiǎn)易安全認(rèn)證示例代碼詳解

    Spring Boot使用過(guò)濾器和攔截器分別實(shí)現(xiàn)REST接口簡(jiǎn)易安全認(rèn)證示例代碼詳解

    這篇文章主要介紹了Spring Boot使用過(guò)濾器和攔截器分別實(shí)現(xiàn)REST接口簡(jiǎn)易安全認(rèn)證示例代碼,通過(guò)開(kāi)發(fā)實(shí)踐,理解過(guò)濾器和攔截器的工作原理,需要的朋友可以參考下
    2018-06-06
  • Java多線程之原子類解析

    Java多線程之原子類解析

    這篇文章主要介紹了Java多線程之原子類解析,Java原子類是一種多線程編程中常用的工具,用于實(shí)現(xiàn)線程安全的操作,它們提供了一種原子性操作的機(jī)制,確保多個(gè)線程同時(shí)訪問(wèn)共享變量時(shí)的數(shù)據(jù)一致性,需要的朋友可以參考下
    2023-10-10

最新評(píng)論

盘山县| 南郑县| 诸暨市| 东丰县| 五峰| 蓬莱市| 陆川县| 永昌县| 龙海市| 曲麻莱县| 巫山县| 镇安县| 托克逊县| 永兴县| 奉新县| 克什克腾旗| 阜南县| 田东县| 攀枝花市| 铜鼓县| 张家川| 东港市| 铁岭县| 海丰县| 大关县| 布拖县| 大足县| 保康县| 屏东市| 泰宁县| 天柱县| 邵东县| 蛟河市| 湘乡市| 越西县| 泊头市| 武义县| 泸州市| 马关县| 龙口市| 郸城县|