关于ThreadLocal对request和response的用法说明
记得在一篇博文中看到描述threadLocal的一句话:
ThreadLocal除了适用于多线程保证每条线程都有自己的变量副本外,还适用于在线程上下文中共享某些变量值。
这两种说法是有区别的。前者强调的是,使用ThreadLocal对副本做保护,避免同步、加锁,降低效率;后者强调的是,某个变量线程上下文中,A处用到、B处用到、C处用到,先在入口处set一个值,后使用ThreadLocal的get方法直接在需要用到的地方拿这个值。
项目中,最近理由cookie存值,使用到了threadLocal这个字段,自己就想去研究下,原理这里跟后者强调的一样,上代码:
1.web.xml里边配置过滤器,拦截请求,做处理
InterceptorFilter com.fx.anniversary.core.filter.InterceptorFilter InterceptorFilter /*
2.赋值
publicclassInterceptorFilterimplementsFilter{ 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(); } } publicvoidinit(FilterConfigfilterConfig)throwsServletException{ } }
3.InterceptorContext实体
publicclassInterceptorContext{ privatestaticThreadLocal_request=newThreadLocal (); privatestaticThreadLocal _response=newThreadLocal (); publicstaticvoidsetRequest(HttpServletRequestrequest){ _request.set(request); } publicstaticHttpServletRequestgetRequest(){ HttpServletRequestrequest=_request.get();returnrequest; } publicstaticvoidremoveRequest(){ _request.remove(); } publicstaticvoidsetResponse(HttpServletResponseresponse){ _response.set(response); } publicstaticHttpServletResponsegetResponse(){ HttpServletResponseresponse=_response.get(); returnresponse; } publicstaticvoidremoveResponse(){ _response.remove(); } }
4.项目中的开始调用。(因为这两个方法调用的地方太多,每次都带一个参数也比较繁琐,所以采用这种方式,文章开头总结过)
publicStringgetAttribute(Stringkey){ HttpServletRequestrequest=InterceptorContext.getRequest(); Cookie[]cookies=request.getCookies(); if(cookies!=null){ for(Cookiecookie:cookies){ if(cookie.getName().equals(key)){ returncookie.getValue(); } } } return""; } @Override publicvoidsetAttribute(Stringkey,Stringvalue){ HttpServletResponseresponse=InterceptorContext.getResponse(); Cookiecookie=newCookie(key,value); response.addCookie(cookie); }
补充知识:利用ThreadLocal管理request和session以及用户信息,实现Useanywhere
1.我们有时需要获取request或session中的数据的时候,首先需要获取request和session对象,这个通常是在Controller的时候当做入参获取,这样方法的入参会显得很长很臃肿的感觉。这就是的出发点,接下来就展示一下是如何实现的。
2.首先我们写个一个拦截器:WebContextFilter
packagecom.office.common.filter; importjava.io.IOException; importjavax.servlet.FilterChain; importjavax.servlet.ServletException; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importorg.springframework.web.filter.OncePerRequestFilter; importcom.office.common.context.WebContextHolder; /** *webcontent信息加载到TheadLocal中 *@authorNeo *@date2017年10月20日11:38:45 */ publicclassWebContextFilterextendsOncePerRequestFilter{ publicWebContextFilter(){ } protectedvoiddoFilterInternal(HttpServletRequestrequest,HttpServletResponseresponse,FilterChainfilterChain) throwsServletException,IOException{ if(request==null||response==null){ return; }else{ WebContextHolder.setRequest(request); WebContextHolder.setResponse(response); filterChain.doFilter(request,response); return; } } }
3.然后我们将写好的拦截器配置到web.xml中:
ArchetypeCreatedWebApplication 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
packagecom.office.common.context; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjavax.servlet.http.HttpSession; importcom.office.common.dto.UserDTO; /** *上下文 *@authorNeo *@date2017年10月20日11:42:57 */ @SuppressWarnings({"rawtypes","unchecked"}) publicclassWebContextHolder{ publicWebContextHolder(){ } publicstaticStringgetRequestIp(){ if(getRequest()==null) returnnull; HttpServletRequestrequest=getRequest(); Stringip=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(); }elseif(ip.length()>15){ Stringips[]=ip.split(","); intindex=0; do{ if(index>=ips.length) break; StringstrIp=ips[index]; if(!"unknown".equalsIgnoreCase(strIp)){ ip=strIp; break; } index++; }while(true); } returnip; } publicstaticHttpServletRequestgetRequest(){ if(requestLocal==null) returnnull; else return(HttpServletRequest)requestLocal.get(); } publicstaticStringgetContextPath(){ if(getRequest()==null) returnnull; else return(newStringBuilder()).append(getRequest().getContextPath()).append("/").toString(); } publicstaticStringgetCurrRequestURI(){ if(getRequest()==null) returnnull; else return(newStringBuilder()).append(getRequest().getRequestURI().replace(getRequest().getContextPath(),"")) .append("/").toString(); } publicstaticHttpServletResponsegetResponse(){ if(responseLocal==null) returnnull; else return(HttpServletResponse)responseLocal.get(); } publicstaticHttpSessiongetSession(){ if(requestLocal==null) returnnull; if(requestLocal.get()==null) returnnull; else return((HttpServletRequest)requestLocal.get()).getSession(); } publicstaticUserDTOgetLoginUserSession(ClassloginUserClass){ if(getSession()==null) returnnull; Objectobj=getSession().getAttribute(CURRENT_USER); if(obj==null) returnnull; else return(UserDTO)obj; } publicstaticUserDTOgetLoginUserSession(){ returngetLoginUserSession(UserDTO.class); } publicstaticvoidcreateLoginUserSession(UserDTOloginUser){ if(loginUser!=null) getSession().setAttribute(CURRENT_USER,loginUser); } publicstaticvoiddestroyLoginUserSession(){ if(getLoginUserSession()!=null){ getSession().removeAttribute(CURRENT_USER); getSession().invalidate(); } } publicstaticvoidsetRequest(HttpServletRequestrequest){ if(requestLocal==null) requestLocal=newThreadLocal(); requestLocal.set(request); } publicstaticvoidsetResponse(HttpServletResponseresponse){ if(responseLocal==null) responseLocal=newThreadLocal(); responseLocal.set(response); } /** *获取项目请求的根目录 * *@returneg:http://localhost:8080/projectName */ publicstaticStringgetProjectRequestRootPath(){ HttpServletRequestrequest=WebContextHolder.getRequest(); StringBuffersb=newStringBuffer(); sb.append(request.getScheme()). append("://"). append(request.getServerName()). append(":"). append(request.getServerPort()). append(request.getContextPath()). append("/"); returnsb.toString(); } privatestaticThreadLocalrequestLocal; privatestaticThreadLocalresponseLocal; publicstaticStringCURRENT_USER="CURRENT_USER"; }
5.使用展示:
//我们可以在任何地方使用这种方法取值
WebContextHolder.getRequest().getParameter("id");
以上这篇关于ThreadLocal对request和response的用法说明就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。