如何在Service层获取用户session中保存的用户信息的方法


/**
 *
 * Description: 用ThreadLocal提供一个存储线程内变量的地方. <p/>
 * 客户端代码可以用静态方法存储和获取线程内变量,不需要依赖于HttpSession.
 * web层的Controller可通过此处向business层传入user_id之类的变量
 *
 */
@SuppressWarnings("unchecked")
public class UserSession {
    /** * 保存变量的ThreadLocal,保持在同一线程中同步数据. */
    private static final ThreadLocal SESSION_MAP = new ThreadLocal();

    /** * 工具类的protected构造方法. */
    protected UserSession() {
    }

    /**
     * 获得线程中保存的属性.
     *
     * @param attribute
     *            属性名称
     * @return 属性值
     */
    public static Object get(String attribute) {
        Map map = (Map) SESSION_MAP.get();
        System.out.println(map.toString());
        System.out.println(map.containsKey("usersession"));

        return map.get(attribute);
    }

    /**
     * 获得线程中保存的属性,使用指定类型进行转型.
     *
     * @param attribute
     *            属性名称
     * @param clazz
     *            类型
     * @param <T>
     *            自动转型
     * @return 属性值
     */
    public static <T> T get(String attribute, Class<T> clazz) {
        return (T) get(attribute);
    }

    /**
     * 设置制定属性名的值.
     *
     * @param attribute
     *            属性名称
     * @param value
     *            属性值
     */
    public static void set(String attribute, Object value) {
        Map map = (Map) SESSION_MAP.get();

        if (map == null) {
            map = new HashMap();
            SESSION_MAP.set(map);
        }

        map.put(attribute, value);
    }

}



我在用户登录的时候 执行:

UserSession.set("User",User);

然后在我需要的service层中执行:

UserSession.get("User");
//UserSession.get("User",User.class);

此时会出现一个bug:这样第一次取到session中的User对象,后面的请求都取不到了。


解决方法:ThreadLocal 是当前请求(前台对后台的每个请求都会被认为是一个独立的线程)的对象。每一次线程请求的时候,都需要从session中把session对象取出来。放到ThreadLocal中去(最好的方式是通过filter拦截器实现)。 这样才能从service中取得到。acegi就是这么处理的


拦截器代码:

public class SessionFilterUtil implements Filter {

    public void destroy() {

    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest session_request = (HttpServletRequest) request;
        HttpServletResponse session_response = (HttpServletResponse) response;
        HttpSession session = session_request.getSession();
        User user = (User) session.getAttribute("user");
        if (user != null) {
            UserSession.set("userSession", session);
            chain.doFilter(request, response);
        } else {
            String uri = session_request.getRequestURI();         // 获取uri信息
            String ctx = session_request.getContextPath();         // 获取上下文,如/项目名
            if(uri.indexOf("!") != -1){
                String method = uri.substring(uri.indexOf("!") + 1, uri.indexOf(".action"));
                if(method.equals("bistore_login")){
                    chain.doFilter(request, response);
                }
            }
            session_response.getWriter().print("<script>location.href='" + ctx + "/adf/login!bistore_login.action'</script>");
        }
    }

    public void init(FilterConfig filterConfig) throws ServletException {

    }

}




  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是实现步骤: 1. 首先需要在 pom.xml 添加 Redis 相关的依赖,例如:jedis、spring-boot-starter-data-redis 等。 2. 在 application.properties 文件配置 Redis 相关信息,如下: ``` spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password= ``` 3. 创建一个 User 类,用于存储用户信息,例如:用户 id、用户名、密码等。 ``` public class User { private String id; private String username; private String password; // getter 和 setter 方法省略 } ``` 4. 创建一个 UserService 类,用于操作 Redis 存储用户信息。具体包括以下方法: - saveUser(User user):将用户信息存储到 Redis 。 - getUserById(String id):根据用户 id 从 Redis 获取用户信息。 - deleteUserById(String id):根据用户 id 从 Redis 删除用户信息。 示例代码如下: ``` @Service public class UserService { @Autowired private StringRedisTemplate redisTemplate; private static final String REDIS_KEY_PREFIX = "user:"; public void saveUser(User user) { String key = REDIS_KEY_PREFIX + user.getId(); redisTemplate.opsForHash().put(key, "id", user.getId()); redisTemplate.opsForHash().put(key, "username", user.getUsername()); redisTemplate.opsForHash().put(key, "password", user.getPassword()); } public User getUserById(String id) { String key = REDIS_KEY_PREFIX + id; String username = (String) redisTemplate.opsForHash().get(key, "username"); String password = (String) redisTemplate.opsForHash().get(key, "password"); User user = new User(); user.setId(id); user.setUsername(username); user.setPassword(password); return user; } public void deleteUserById(String id) { String key = REDIS_KEY_PREFIX + id; redisTemplate.delete(key); } } ``` 5. 在登录接口,验证用户信息是否正确,并将用户信息保存到 Redis 。示例代码如下: ``` @RestController public class LoginController { @Autowired private UserService userService; @PostMapping("/login") public String login(@RequestBody User user) { // 验证用户信息是否正确 if (!"admin".equals(user.getUsername()) || !"123456".equals(user.getPassword())) { return "用户名或密码错误"; } // 将用户信息存储到 Redis userService.saveUser(user); return "登录成功"; } } ``` 6. 在需要验证用户信息的接口,从 Redis 获取用户信息,并验证用户是否已登录。示例代码如下: ``` @RestController public class UserController { @Autowired private UserService userService; @GetMapping("/user") public String getUser(@RequestParam String userId, HttpServletRequest request) { // 从 Redis 获取用户信息 User user = userService.getUserById(userId); if (user == null) { return "用户不存在"; } // 验证用户是否已登录 String sessionId = request.getSession().getId(); String loginUserId = redisTemplate.opsForValue().get("login:" + sessionId); if (!userId.equals(loginUserId)) { return "用户未登录"; } // TODO:返回用户信息 } } ``` 以上就是使用 Spring Boot 和 Redis 实现用户登录用户信息存储以及验证的步骤。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值