上代码
封装工具类即可在过滤器、拦截器、aop等地方使用(转发重定向动手试试吧印象更深刻,子线程或线程池需要使用阿里的threadLoacl)
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Slf4j
public class WebUtil {
private static final String USERID_ATTRIBUTE_NAME = "_user_id";
public static void setUserId(Integer userId) {
setAttribute(USERID_ATTRIBUTE_NAME, userId);
}
public static Integer getUserId() {
return Optional.ofNullable((Integer) getAttribute(USERID_ATTRIBUTE_NAME)).orElse(null);
}
/**
* 取
*/
public static Object getAttribute(String name) {
return getRequest().getAttribute(name);
}
/**
* 存
*/
public static void setAttribute(String name, Object val) {
getRequest().setAttribute(name, val);
}
/**
* 获取 HttpServletRequest
*/
public static HttpServletRequest getRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
}
/**
* 获取 HttpServletResponse
*/
public static HttpServletResponse getResponse() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getResponse();
}
}
源码
可以看到ServletRequestAttributes对象就在ThreadLocal中,无需自己处理生命周期
而HttpServletRequest可已从ServletRequestAttributes中获取
public abstract class RequestContextHolder {
private static final ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal("Request attributes");
private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder = new NamedInheritableThreadLocal("Request context");
public static void resetRequestAttributes() {
requestAttributesHolder.remove();
inheritableRequestAttributesHolder.remove();
}
@Nullable
public static RequestAttributes getRequestAttributes() {
RequestAttributes attributes = (RequestAttributes)requestAttributesHolder.get();
if (attributes == null) {
attributes = (RequestAttributes)inheritableRequestAttributesHolder.get();
}
return attributes;
}
}
而我们的需要的东西就保存在这里了,一个ConcurrentHashMap
public class Request implements HttpServletRequest {
private final Map<String, Object> attributes = new ConcurrentHashMap<>();
}