关于ThreadLocal对request和response的用法说明

网友投稿 439 2023-04-28

关于ThreadLocal对request和response的用法说明

记得在一篇博文中看到描述threadLocal的一句话:

ThreadLocal除了适用于多线程保证每条线程都有自己的变量副本外,还适用于在线程上下文中共享某些变量值。

这两种说法是有区别的。前者强调的是,使用ThreadLocal对副本做保护,避免同步、加锁,降低效率;后者强调的是,某个变量线程上下文中,A处用到、B处用到、C处用到,先在入口处set一个值,后使用ThreadLocal的get方法直接在需要用到的地方拿这个值。

项目中,最近理由cookie存值,使用到了threadLocal这个字段,自己就想去研究下,原理这里跟后者强调的一样,上代码

1.web.xml里边配置过滤器,拦截请求,做处理

InterceptorFilter

com.fx.anniversary.core.filter.InterceptorFilter

InterceptorFilternJmEgQ

/*

2.赋值

public class InterceptorFilter implements Filter{

publicvoiddestroy(){

}

publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{

HttpServletRequesthttpRequest=(HttpServletRequest)request;

HttpServletResponsehttpResponse=(HttpServletResponse)response;

InterceptorContext.setRequest(httpRequest);

InterceptorContext.setResponse(httpResponse);

try{

chain.doFilter(request,

response);

}finally{

//不管有木有出现异常,finally块中代码都会执行;在这里,相当于只服务于当前请求。

InterceptorContext.removeRequest();

InterceptorContext.removeResponse();

}

}

public void init(FilterConfigfilterConfig)throwsServletException{

}

}

3.InterceptorContext实体

public class InterceptorContext{

private static ThreadLocal _request = newThreadLocal();

private static ThreadLocal _response = newThreadLocal();

publicstaticvoidsetRequest(HttpServletRequestrequest){

_request.set(request);

}

public static HttpServletRequestgetRequest(){

HttpServletRequestrequest=_request.get();returnrequest;

}

public static void removeRequest(){

_request.remove();

}

public static void setResponse(HttpServletResponseresponse){

_response.set(response);

}

public static HttpServletResponsegetResponse(){

HttpServletResponseresponse=_response.get();

return response;

}

public static void removeResponse(){

_response.remove();

}

}

4.项目中的开始调用。(因为这两个方法调用的地方太多,每次都带一个参数也比较繁琐,所以采用这种方式,文章开头总结过)

public String getAttribute(Stringkey){

HttpServletRequestrequest = InterceptorContext.getRequest();

Cookie[]cookies=request.getCookies();

if(cookies!=null){

for(Cookie cookie: cookies){

if(cookie.getName().equals(key)){

return cookie.getValue();

}

}

}

return"";

}

@Override

public void setAttribute(String key,String value){

HttpServletResponse response=InterceptorContext.getResponse();

Cookiecookie=newCookie(key,value);

response.addCookie(cookie);

}

补充知识:利用ThreadLocal管理request和session以及用户信息,实现 Use anywhere

1.我们有时需要获取request或session中的数据的时候,首先需要获取request和session对象,这个通常是在Controller的时候当做入参获取,这样方法的入参会显得很长很臃肿的感觉。这就是的出发点,接下来就展示一下是如何实现的。

2.首先我们写个一个-:WebContextFilter

package com.office.common.filter;

import java.io.IOException;

import javax.servlet.FilterChain;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.filter.OncePerRequestFilter;

import com.office.common.context.WebContextHolder;

/**

* webcontent信息加载到TheadLocal中

* @author Neo

* @date 2017年10月20日11:38:45

*/

public class WebContextFilter extends OncePerRequestFilter {

public WebContextFilter() {

}

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)

throws ServletException, IOException {

if (request == null || response == null) {

return;

} else {

WebContextHolder.shttp://etRequest(request);

WebContextHolder.setResponse(response);

filterChain.doFilter(request, response);

return;

}

}

}

3.然后我们将写好的-配置到web.xml中:

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

Archetype Created Web Application

contextConfigLocation

encodingFilter

org.springframework.web.filter.CharacterEncodingFilter

encoding

UTF-8

forceEncoding

true

encodingFilter

/*

webContentFilter

com.office.common.filter.WebContextFilter

webContentFilter

/*

org.springframework.web.context.ContextLoaderListener

springMVC

org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

classpath*:applicationContext.xml

1

springMVC

/

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

Archetype Created Web Application

contextConfigLocation

encodingFilter

org.springframework.web.filter.CharacterEncodingFilter

encoding

UTF-8

forceEncoding

true

encodingFilter

/*

webContentFilter

com.office.common.filter.WebContextFilter

webContentFilter

/*

org.springframework.web.context.ContextLoaderListener

springMVC

org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

classpath*:applicationContext.xml

1

springMVC

/

4.编写一个同一个管理操作工具类:WebContextHolder

package com.office.common.context;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import com.office.common.dto.UserDTO;

/**

* 上下文

* @author Neo

* @date 2017年10月20日11:42:57

*/

@SuppressWarnings({ "rawtypes", "unchecked" })

public class WebContextHolder {

public WebContextHolder() {

}

public static String getRequestIp() {

if (getRequest() == null)

return null;

HttpServletRequest request = getRequest();

String ip = request.getHeader("X-Forwarded-For");

if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))

ip = request.getHeader("Proxy-Client-IP");

if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))

ip = request.getHeader("WL-Proxy-Client-IP");

if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))

ip = request.getHeader("HTTP_CLIENT_IP");

if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))

ip = request.getHeader("HTTP_X_FORWARDED_FOR");

if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))

ip = request.getRemoteAddr();

} else if (ip.length() > 15) {

String ips[] = ip.split(",");

int index = 0;

do {

if (index >= ips.length)

break;

String strIp = ips[index];

if (!"unknown".equalsIgnoreCase(strIp)) {

ip = strIp;

break;

}

index++;

} while (true);

}

return ip;

}

public static HttpServletRequest getRequest() {

if (requestLocal == null)

return null;

else

return (HttpServletRequest) requestLocal.get();

}

public static String getContextPath() {

if (getRequest() == null)

return null;

else

return (new StringBuilder()).append(getRequest().getContextPath()).append("/").toString();

}

public static String getCurrRequestURI() {

if (getRequest() == null)

return null;

else

return (new StringBuilder()).append(getRequest().getRequestURI().replace(getRequest().getContextPath(), ""))

.append("/").toString();

}

public static HttpServletResponse getResponse() {

if (responseLocal == null)

return null;

else

return (HttpServletResponse) responseLocal.get();

}

public static HttpSession getSession() {

if (requestLocal == null)

return null;

if (requestLocal.get() == null)

return null;

else

return ((HttpServletRequest) requestLocal.get()).getSession();

}

public static UserDTO getLoginUserSession(Class loginUserClass) {

if (getSession() == null)

return null;

Object obj = getSession().getAttribute(CURRENT_USER);

if (obj == null)

return null;

else

return (UserDTO) obj;

}

public static UserDTO getLoginUserSession() {

return getLoginUserSession(UserDTO.class);

}

public static void createLoginUserSession(UserDTO loginUser) {

if (loginUser != null)

getSession().setAttribute(CURRENT_USER, loginUser);

}

public static void destroyLoginUserSession() {

if (getLoginUserSession() != null) {

getSession().removeAttribute(CURRENT_USER);

getSession().invalidate();

}

}

public static void setRequest(HttpServletRequest request) {

if (requestLocal == null)

requestLocal = new ThreadLocal();

requestLocal.set(request);

}

public static void setResponse(HttpServletResponse response) {

if (responseLocal == null)

responseLocal = new ThreadLocal();

responseLocal.set(response);

}

/**

* 获取项目请求的根目录

*

* @return eg:http://localhost:8080/projectName

*/

public static String getProjectRequestRootPath() {

HttpServletRequest request = WebContextHolder.getRequest();

StringBuffer sb = new StringBuffer();

sb.append(request.getScheme()).

append("://").

append(request.getServerName()).

append(":").

append(request.getServerPort()).

append(request.getContextPath()).

append("/");

return sb.toString();

}

private static ThreadLocal requestLocal;

private static ThreadLocal responseLocal;

public static String CURRENT_USER = "CURRENT_USER";

}

5.使用展示:

//我们可以在任何地方使用这种方法取值

WebContextHolder.getRequest().getParameter("id");

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:笔记本电脑怎么打开小程序(笔记本电脑怎么打开小程序功能)
下一篇:Java通过反射将 Excel 解析成对象集合实例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~