当前位置: 首页 > 编程笔记 >

SpringBoot+SpringCloud用户信息微服务传递实现解析

屠浩
2023-03-14
本文向大家介绍SpringBoot+SpringCloud用户信息微服务传递实现解析,包括了SpringBoot+SpringCloud用户信息微服务传递实现解析的使用技巧和注意事项,需要的朋友参考一下

这篇文章主要介绍了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
  html" target="_blank">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);
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 我听说亚马逊使用HTTP作为其基于微服务的架构。另一种方法是使用RabbitMQ或Solace Systems这样的消息传递系统。我个人对基于Solace的微服务架构有经验,但从未使用过REST。 知道像Amazon、Netflix、UK Gov等各种大联盟实现使用什么吗? 其他方面是,在微服务中,还需要以下东西(除了其他东西): *模式匹配 *异步消息传递。接收系统可能已关闭 *发布订阅 *缓存

  • 我正在计划开发一个基于微服务的架构应用程序,当我阅读Ronnie Mitra的书《微服务架构》时,我决定使用Kafka进行内部通信;马特·麦克拉蒂;迈克·阿蒙森;伊拉克利·纳达雷什维利说: 让微服务直接与消息代理(如RabbitMQ等)交互很少是个好主意。如果两个微服务通过消息队列通道直接通信,那么它们共享一个数据空间(通道),我们已经详细讨论了两个微服务共享一个数据空间的弊病。相反,我们可以做的

  • 我对尝试将微服务/SOA作为一种体系结构非常感兴趣,并且很难对服务之间的集成进行概念化。 我喜欢使用消息传递将客户端与服务分离的想法,但不理解系统如何独占地使用它。典型的异步操作和发布/订阅显然是有意义的——比如创建新订单、广播数据以进行报告等。我不明白的是,人们是否通常尝试在常见的请求/回复场景中使用消息传递——例如,用户点击他们的“个人资料”页面,而需要在页面上呈现的部分数据来自用户服务。 我

  • 本文向大家介绍C#微信小程序服务端获取用户解密信息实例代码,包括了C#微信小程序服务端获取用户解密信息实例代码的使用技巧和注意事项,需要的朋友参考一下  C#微信小程序服务端获取用户解密信息实例代码 实现代码: GetUsersHelper 帮助类 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

  • 本文向大家介绍SpringBoot中获取微信用户信息的方法,包括了SpringBoot中获取微信用户信息的方法的使用技巧和注意事项,需要的朋友参考一下 前言 不知道你是否参加过拼多多上邀请微信好友砍价功能,这个功能实现首先需要考虑的就是获取微信用户的信息。获取用户信息就是获取公众号下微信用户的信息,今天我就来讲讲如何从公众号下获取微信用户信息。 需要声明一点的是获取微信公众号下的用户信息的权限是服

  • 本文向大家介绍SpringCloud使用Feign实现服务调用,包括了SpringCloud使用Feign实现服务调用的使用技巧和注意事项,需要的朋友参考一下 Spring Cloud Feign简介 Spring Cloud Feign也是一个基础工具类,它整合了Spring Cloud Ribbon和Spring Cloud Hystrix,除了提供这两者的强大功能以外,它还提供了一种声明式的

  • 我知道消息传递系统是无阻塞和可扩展的,应该在微服务环境中使用。 我质疑的用例是: 假设有一个admin dashboard客户机负责发送API请求以创建Item对象。有一个微服务提供APIendpoint,它使用一个MySQL数据库来存储项目。还有一个微服务使用弹性搜索进行文本搜索。 如果此管理仪表板客户端: a.发送2个API调用;1次调用MySQL服务和另一个elasticsearch服务 或

  • 我们正在设计我们的新系统,它很可能是从头开始编写的,因为旧系统非常非常旧。对我们的系统来说,保留系统中发生的所有事情的审计跟踪日志非常重要。 由于审计跟踪的重要性,我们决定遵循事件源架构以获得它的所有好处。另一个关键因素是我们有多个团队在不同的“域”上工作。也就是说,我们想将每个域拆分为自己的服务(微服务架构),这样每个团队都可以独立工作。 我们面临的最大问题是谁将负责微服务之间的事件共享。例如,