Springboot中使用线程拿到当前账号信息

Springboot中使用线程的思想拿到当前账号信息

1.简介

我查看源码发现springboot中有定义好了的线程还有线程池,下面这个类就是关于请求的线程,我们通过线程拿到请求对象,这个线程在用户有效连接服务器就在,所以用户在线的状态下,这个线程必然存在,通过调用((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()就可以拿到线程中的请求对象,有了这个对象,就可以进一步拿到HttpSession类的对象,那就可以拿到当前账号信息了。

package org.springframework.web.context.request;

import javax.faces.context.FacesContext;
import org.springframework.core.NamedInheritableThreadLocal;
import org.springframework.core.NamedThreadLocal;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;

public abstract class RequestContextHolder {
    private static final boolean jsfPresent = ClassUtils.isPresent("javax.faces.context.FacesContext", RequestContextHolder.class.getClassLoader());
    private static final ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal("Request attributes");
    private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder = new NamedInheritableThreadLocal("Request context");

    public RequestContextHolder() {
    }

    public static void resetRequestAttributes() {
        requestAttributesHolder.remove();
        inheritableRequestAttributesHolder.remove();
    }

    public static void setRequestAttributes(@Nullable RequestAttributes attributes) {
        setRequestAttributes(attributes, false);
    }

    public static void setRequestAttributes(@Nullable RequestAttributes attributes, boolean inheritable) {
        if (attributes == null) {
            resetRequestAttributes();
        } else if (inheritable) {
            inheritableRequestAttributesHolder.set(attributes);
            requestAttributesHolder.remove();
        } else {
            requestAttributesHolder.set(attributes);
            inheritableRequestAttributesHolder.remove();
        }

    }

    @Nullable
    public static RequestAttributes getRequestAttributes() {
        RequestAttributes attributes = (RequestAttributes)requestAttributesHolder.get();
        if (attributes == null) {
            attributes = (RequestAttributes)inheritableRequestAttributesHolder.get();
        }

        return attributes;
    }

    public static RequestAttributes currentRequestAttributes() throws IllegalStateException {
        RequestAttributes attributes = getRequestAttributes();
        if (attributes == null) {
            if (jsfPresent) {
                attributes = RequestContextHolder.FacesRequestAttributesFactory.getFacesRequestAttributes();
            }

            if (attributes == null) {
                throw new IllegalStateException("No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.");
            }
        }

        return attributes;
    }

    private static class FacesRequestAttributesFactory {
        private FacesRequestAttributesFactory() {
        }

        @Nullable
        public static RequestAttributes getFacesRequestAttributes() {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            return facesContext != null ? new FacesRequestAttributes(facesContext) : null;
        }
    }
}

2.写一个工具类用来获取请求对象

@Component
public class LogInThread {
    public static HttpServletRequest getRequest(){
    return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }
}

3.测试获取账号信息

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public @ResponseBody
    ResultUtil login(@RequestBody HashMap map, HttpSession session){
        String name=(String)map.get("name");
        String pass=(String)map.get("pass");
        if(userService.login(name,pass,session)){
            return new ResultUtil(200,"Success");
        }else{
            return new ResultUtil(200,"账号或密码错误");
        }
    }
    @PostMapping("/test")
    public @ResponseBody String deleteUser(){
        HttpSession session=LogInThread.getRequest().getSession();
        System.out.println(session.getAttribute(session.getId()));
        
        return session.getAttribute(session.getId())
    }

}

上一篇:C++ 11中的bind解析


下一篇:《OpenGL编程指南(原书第9版)》——第1章 1.0OpenGL概述