盈彩体育注册(中国)有限公司
盈彩体育注册(中国)有限公司 您所在的位置:网站首页 盈彩体育注册(中国)有限公司 Java session id 获取机制 java从session中获取登录信息

Java session id 获取机制 java从session中获取登录信息

2024-05-06 12:32:14| 来源: 网络整理

说到Java web,那么在web端获取登陆用户信息几乎是所有系统都需要实现的功能,下面我们就来讲一下几种获取登陆用户信息的方法。

从session中获取

这是我们刚刚接触Java web时就了解的一种解决方案,配置一个登陆过滤器或者登陆拦截器,在用户登陆的时候将用户信息放到session中,然后控制层在session中取出用户信息,这是最简单也是最常见的一种解决方案。

随着用户量的增大,单部署的服务往往不能满足我们的需求,这时候往往我们会引入集群来分摊服务器的压力。但是引入集群后,从session中存取用户信息就会变得不那么靠谱了。

大家都知道session是存在服务端的,那么如果用户在集群机器A中登陆,用户信息就存储在了机器A上,此时如果用户新的请求被分发到集群机器B上,就无法获取用户信息了。

这是集群情况下用户信息被存储在集群中的单个服务器上导致的,解决方案主要有两种: - 让用户后续的所有请求都分发到用户登陆的那台机器 - 把用户信息存储在缓存中间件中,而不是集群中的每个服务器上

第一种方案可以在代理服务器(apache,nginx等)上配置session黏着,这样就能保证用户后续请求都会被路由到同一台机器上,这就解决了集群情况下拿不到用户信息的问题了。

当然,对ip进行hash算法使某一个用户的请求永远随机到某一台机器上也是一种思路。

从缓存中间件获取

从缓存中间件获取,就是把用户信息存储在缓存中间件中,控制层直接从缓存中间件中获取用户信息。

用户在登陆成功后,会生成一个token,然后以token为键,用户信息为值存储在缓存中间件中,并且把token发送到页面端。

页面端向服务端发送请求的时候带上这个token,服务端控制层可以根据这个token从缓存中间件中获取用户信息。

在集群情况下,用户信息还是存储在一个独立出来的缓存服务器上,这样就可以避免获取不到用户信息的问题了。

以上两种方法就是获取登陆用户信息的两种主要解决方案了,这里再从代码层面上给出一个小分享。

不论是从session中获取还是从缓存中间件中获取用户信息,不可避免的是在控制层需要显式的去获取用户

User user = (User)session.get("login_user");

或者

User user = (User)redisService.get(token);

几乎每个控制层方法都需要执行上面的语句获取一下用户信息,着就会显得很罗嗦,所以下面给出一个小分享来使用注解和HandlerMethodArgumentResolver结合优化控制层代码。

我们先来了解一下HandlerMethodArgumentResolver, SpringMvc中的HandlerAdapter会检测所有的 HandlerMethodArgumentResolver,对参数进行处理和加工。

这样,我们就可以自定义一个HandlerMethodArgumentResolver,读取请求中的token,根据token获取到用户信息,将用户信息通过自定义注解的方式传递到控制层。

没错,这个小分享是基于SpringMVC的,下面给出详细代码。

首先自定义一个注解,用来传递用户信息@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.PARAMETER)public @interface Logined {}自定义一个HandlerMethodArgumentResolver,用来获取用户信息public class LoginedArgumentResolver implements HandlerMethodArgumentResolver { private RedisService redisService; public LoginedArgumentResolver(RedisService redisService) { this.redisService = redisService; } @Override public boolean supportsParameter(MethodParameter parameter) { if (parameter.getParameterAnnotation(Logined.class) != null && parameter.getParameterType() == LoginUser.class) { // 如果该参数注解有@Logined才会执行下面的resolveArgument方法 return true; } return false; } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); String accessToken = request.getHeader(LocalConstant.ACCESS_TOKEN_KEY); LoginUser loginUser = (LoginUser)redisService.get(LocalConstant.REDIS_LOGIN_USER_KEY + accessToken); return loginUser; }}控制层获取用户信息@GetMapping("/getLoginUser")public LoginUser addCouple(@Logined LoginUser loginUser){ return loginUser;}

通过上面的Logined注解和LoginedArgumentResolver结合,在控制层中需要获取用户信息,若需要在参数中添加@Logined就可以了,是不是简单了很多呢,希望今天的分享可以给大家带来帮助。



【本文地址】 转载请注明 

最新文章

推荐文章

CopyRight 2018-2019 盈彩体育注册(中国)有限公司 版权所有 豫ICP备16040606号-1