• SpringBoot+SpringCloud实现登录用户信息在微服务之间的传递


    实现思路:

    1:准备一个ThreadLocal变量,供线程之间共享。

    2:每个微服务对所有过来的Feign调用进行过滤,然后从请求头中获取User用户信息,并存在ThreadLocal变量中。

    3:每个微服务在使用FeignClient调用别的微服务时,先从ThreadLocal里面取出user信息,并放在request的请求头中。

    4:封装为一个注解,在启动类上标记即可。

    代码样例:

    1:ThreadLocal工具类 :UserInfoContext 

    package com.test.domi.common.system;
    
    import com.test.domi.dao.UserInfo;
    
    public class UserInfoContext {
        private static ThreadLocal<UserInfo> userInfo = new ThreadLocal<UserInfo>();
        public static String KEY_USERINFO_IN_HTTP_HEADER = "X-AUTO-FP-USERINFO";
    
        public UserInfoContext() {
        }
    
        public static UserInfo getUser(){
            return (UserInfo)userInfo.get();
        }
    
        public static void setUser(UserInfo user){
            userInfo.set(user);
        }
    }

    2:准备承载用户信息的userInfo实体类(代码略)

    3:编写拦截器 : TransmitUserInfoFeighClientIntercepter 

    package com.test.domi.config;
    
    import com.alibaba.fastjson.JSON;
    import com.test.domi.common.system.UserInfoContext;
    import com.test.domi.dao.UserInfo;
    import feign.RequestInterceptor;
    import feign.RequestTemplate;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    
    public class TransmitUserInfoFeighClientIntercepter implements RequestInterceptor {
    
        private static final Logger log = LoggerFactory.getLogger(TransmitUserInfoFeighClientIntercepter.class);
        public TransmitUserInfoFeighClientIntercepter() {
        }
    
        @Override
        public void apply(RequestTemplate requestTemplate) {
            //从应用上下文中取出user信息,放入Feign的请求头中
            UserInfo user = UserInfoContext.getUser();
            if (user != null) {
                try {
                    String userJson = JSON.toJSONString(user);
                    requestTemplate.header("KEY_USERINFO_IN_HTTP_HEADER",new String[]{URLDecoder.decode(userJson,"UTF-8")});
                } catch (UnsupportedEncodingException e) {
                    log.error("用户信息设置错误",e);
                }
            }
        }
    }

    4:编写过滤器:TransmitUserInfoFilter 

    package com.test.domi.config;
    
    import com.alibaba.fastjson.JSON;
    import com.test.domi.common.system.UserInfoContext;
    import com.test.domi.dao.UserInfo;
    import org.apache.commons.lang.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    
    public class TransmitUserInfoFilter implements Filter {
    
        private static final Logger log = LoggerFactory.getLogger(TransmitUserInfoFeighClientIntercepter.class);
        public TransmitUserInfoFilter() {
        }
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
           this.initUserInfo((HttpServletRequest)request);
           chain.doFilter(request,response);
        }
    
        private void initUserInfo(HttpServletRequest request){
            String userJson = request.getHeader("KEY_USERINFO_IN_HTTP_HEADER");
            if (StringUtils.isNotBlank(userJson)) {
                try {
                    userJson = URLDecoder.decode(userJson,"UTF-8");
                    UserInfo userInfo = (UserInfo) JSON.parseObject(userJson,UserInfo.class);
                    //将UserInfo放入上下文中
                    UserInfoContext.setUser(userInfo);
                } catch (UnsupportedEncodingException e) {
                   log.error("init userInfo error",e);
                }
            }
        }
    
        @Override
        public void destroy() {
        }
    }

    5:编写注解实现类: EnableUserInfoTransmitterAutoConfiguration 

    
    
    package spring.cloud.common.config;

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import spring.cloud.common.interceptor.TransmitUserInfoFeighClientInterceptor;
    import spring.cloud.common.filter.TransmitUserInfoFilter;

    //@Configuration 在业务端通过注解EanbleUserInfoTransmitter加载
    public class EnableUserInfoTransmitterAutoConfiguration {

    public EnableUserInfoTransmitterAutoConfiguration() {
    }

    @Bean
    public TransmitUserInfoFeighClientInterceptor transmitUserInfo2FeighHttpHeader(){
    System.out.println("-----TransmitUserInfoFeighClientInterceptor");
    return new TransmitUserInfoFeighClientInterceptor();
    }

    @Bean
    public TransmitUserInfoFilter transmitUserInfoFromHttpHeader(){
    System.out.println("-----TransmitUserInfoFilter");
    return new TransmitUserInfoFilter();
    }
    }
     

    6:编写注解 EnableUserInfoTransmitter 

    package com.test.domi.annotation;
    
    import com.test.domi.config.EnableUserInfoTransmitterAutoConfiguration;
    import org.springframework.context.annotation.Import;
    
    import java.lang.annotation.*;
    
    @Documented
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Import({EnableUserInfoTransmitterAutoConfiguration.class})
    public @interface EnableUserInfoTransmitter {
    }

    7:在启动类上标记注解即可使用(无侵入)

    package com.test.domi;
    
    import com.test.domi.annotation.EnableUserInfoTransmitter;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @EnableDiscoveryClient
    @SpringBootApplication
    @MapperScan("com.test.domi.dao")
    @EnableUserInfoTransmitter
    public class TestCommonClient {
    
        public static void main(String[] args){
    
            SpringApplication.run(TestCommonClient.class,args);
        }
    }
  • 相关阅读:
    SpringBoot基础
    开始一个新的springboot项目checklist
    五项修炼: 终生学习者
    价值流分析-改进方法论
    伯努利方程
    会计语言
    svg蒙版mask
    从svg到计算机图形学
    xflux 调节屏幕色温
    处理器架构
  • 原文地址:https://www.cnblogs.com/domi22/p/9248536.html
Copyright © 2020-2023  润新知