需求: 在一次请求的过程中,想要获取request和response。 如果每个方法都需要把这两个当成入参,这样显得很不雅观。Spring web包里就提供了RequestContextHolder这个类来方便获取请求参数和返回参数。 RequestContextHolder
public abstract class RequestContextHolder {
private static final ThreadLocal<RequestAttributes> requestAttributesHolder =
new NamedThreadLocal<>("Request attributes");
private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder =
new NamedInheritableThreadLocal<>("Request context");
/**
* Return the RequestAttributes currently bound to the thread.
* @return the RequestAttributes currently bound to the thread,
* or {@code null} if none bound
*/
@Nullable
public static RequestAttributes getRequestAttributes() {
RequestAttributes attributes = requestAttributesHolder.get();
if (attributes == null) {
attributes = inheritableRequestAttributesHolder.get();
}
return attributes;
}
/**
* Bind the given RequestAttributes to the current thread,
* <i>not</i> exposing it as inheritable for child threads.
* @param attributes the RequestAttributes to expose
* @see #setRequestAttributes(RequestAttributes, boolean)
*/
public static void setRequestAttributes(@Nullable RequestAttributes attributes) {
setRequestAttributes(attributes, false);
}
/**
* Bind the given RequestAttributes to the current thread.
* @param attributes the RequestAttributes to expose,
* or {@code null} to reset the thread-bound context
* @param inheritable whether to expose the RequestAttributes as inheritable
* for child threads (using an {@link InheritableThreadLocal})
*/
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();
}
}
}
}
RequestContextHolder使用了线程局部变量ThreadLocal,可以获取当前线程的请求参数request、返回参数。
项目里的使用,可以写一个工具类:
public class HttpHolderUtil {
public static HttpServletRequest getRequest() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
if(servletRequestAttributes==null) {
return null;
}
return servletRequestAttributes.getRequest();
}
public static HttpServletResponse getResponse() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
if(servletRequestAttributes==null) {
return null;
}
return servletRequestAttributes.getResponse();
}
}
这个工具类大部分情况下可以使用,比如
HttpHolderUtil.getRequest().getHeader("host")
不过在一些特殊场景下可能会失效,比如文件上传等。
参考:
RequestContextHolder获取request_采采茶的博客-CSDN博客_requestcontextholder