素材牛VIP会员
如何在 Spring容器 service层获取当前登录用户信息?
 威***军  分类:Java代码  人气:797  回帖:7  发布于6年前 收藏

用户信息绑定会话,怎样才可以在服务层注入?

讨论这个帖子(7)垃圾回帖将一律封号处理……

Lv6 码匠
su***an JAVA开发工程师 6年前#1

谢谢邀请回答。
如果不想在controller拿到用户信息传到service层,直接在service层也是可以拿到的。
spring mvc在处理请求的时候,会把请求对象放到RequestContextHolder持有的ThreadLocal对象中,你可以去看看DispatcherServlet类的源代码。
在service层可以按照如下代码获取:

//获取到当前线程绑定的请求对象
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
//已经拿到session,就可以拿到session中保存的用户信息了。
        System.out.println(request.getSession().getAttribute("userInfo"));
Lv4 码徒
Su***er JS工程师 6年前#2

SecurityContextHolder 可以处理登录用户的存取,

UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
        userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource()
        .buildDetails(httpRequest));
SecurityContextHolder.getContext().setAuthentication(authentication);
UsernamePasswordAuthenticationToken authentication = SecurityContextHolder.getContext().getAuthentication();
Lv2 入门
蒙***生 职业无 6年前#3

比较简单方法就是页面直接将用户信息传入servlet然后显示到页面上
ActionContext.getContext().put("name", name);
${username }

Lv1 新人
Sm***ty CEO 6年前#4

什么RequestContextHolder, shiro啊这些, 你不看源码相信用起来不会安心的, 还是自己写靠谱且简洁, 原理就是使用ThreadLocal这个技术, 以前后端分离的项目(java只是接口, 不渲染界面)为例, 流程我简单说下:

  1. 用户登录成功后, 生成登录成功的token(JWT你可以看下)连同用户的基本信息往redis中插入, 登录接口返回给客户端jwt, 客户端存储到localStorage中
  2. 用户再次请求, 即有接口调用会带着jwt作为参数(可放在header中)请求服务器接口, 用filter来对jwt进行验证, 并从redis中取出当前用户的基本信息, 放到ThreadLocal中,一般我是建立一个SessionContext类, 这个类有一个addSession和getSession方法, 分别是往SessionContext的一个static field ThreadLocal插入和从ThreadLocal中取
  3. 在任何地方获取当前用户信息都ok了, Controller也好, Service也好, easy吧, 直接在任何地方调用SessionContext.getCurrentUser()即可

tip: 有@Async注解的方法不能用, 因为新建立了一个Thread, 这种异步方法获取用户信息只能参数传递进来

相信源码你就不需要了吧, 如果不明白的话, 使劲学习一下ThreadLocal就可以了, 记得给我设置为最佳答案

Lv1 新人
BO***OS 职业无 6年前#5

ThreadLocal?

Lv2 入门
一***句 职业无 6年前#6
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        ShiroUser user = null;
        if (req != null) {
            user = (ShiroUser) req.getSession().getAttribute("currentUser");
        }

所以你想再service层获取的是request 对不对!!

Lv4 码徒
大***咒 JAVA开发工程师 6年前#7

设计不合理,用户信息应该在Controller层获取,然后传入Service层使用。

 文明上网,理性发言!   😉 阿里云幸运券,戳我领取