安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

Springweb开发之Request获取三种方式

12月20日 飞仙轩投稿
  在开发JavaWeb项目中,我们经常使用HttpServletRequest获取请求参数、请求头等信息。在Spring项目,我们通常会使用Spring提供的注解获取参数,如RequestParam、RequestHeader。
  不过在某些场景下,我们可能需要从HttpServletRequest对象中取得更多的能力,如获取请求IP,获取请求域名等。这篇我们来学习如何在SpringMVC环境下获取HttpServletRequest,以及它们的实现方式,做到知其所以然。
  Controller方法参数
  使用注解后的SpringMVCcontroller方法可以作为handler处理请求,如果想获取request对象,只需要在方法中添加ServletRequest或HttpServletRequest类型参数即可。代码如下RestControllerpublicclassUserController{GetMapping(getUser)publicStringgetUser(HttpServletRequestrequest){returnrequestipis:request。getRemoteHost();}}
  扩展:如何要获取reponse,同例只要在方法中增加ServletResponse或HttpServletResponse类型参数即可。Controller方法参数实现原理
  通过上面的代码我们很容易就实现了,那spring是怎么帮我们搞定的呢?
  在springmvc中,所有浏览器发起的请求都会先交给DispatcherServlet处理。DispatcherServlet根据用户或默认的配置使用HandlerMapping查找可处理请求的处理器。DispatcherServlet拿到HandlerMapping返回的处理器链HandlerExecutionChain。整个处理器链包含拦截器和处理。DispatcherServlet将处理器适配为HandlerAdapter。DispatcherServlet使用拦截器进行请求前置处理。DispatcherServlet使用处理器进行请求处理。DispatcherServlet使用拦截器进行请求后置处理。DispatcherServlet从拦截器或处理器中提取到模型及视图ModelAndView。DispatcherServlet使用视图解析器ViewResolver解析视图出视图View。DispatcherServlet渲染视图,响应请求返回给浏览器。
  在上面第6步【DispatcherServlet使用处理器进行请求处理】时,在调用我们自己的controller方法之前,Spring通过HandlerMethodArgumentResolver向我们的controller方法注入对应的参数。
  静态方法
  除了通过controller方法参数获取HttpServletRequest对象,Spring还允许通过其提供的工具类的静态方法来获取HttpServletRequest。示例如下。HttpServletRequestrequest((ServletRequestAttributes)RequestContextHolder。currentRequestAttributes())。getRequest();静态方法实现原理
  上面的示例中,RequestContextHolder表示一个请求上下文的持有者,内部将每个请求上下文信息存储到ThreadLocal中。publicabstractclassRequestContextHolder{线程上下文RequestAttributesprivatestaticfinalThreadLocalRequestAttributesrequestAttributesHoldernewNamedThreadLocal(Requestattributes);支持继承的线程上下文RequestAttributesprivatestaticfinalThreadLocalRequestAttributesinheritableRequestAttributesHoldernewNamedInheritableThreadLocal(Requestcontext);}
  DispatcherServlet处理请求前会将request存至ServletRequestAttributes,然后放到RequestContextHolder中,具体可见DispatcherServlet的父类FrameworkServlet。processRequest()。直接注入
  还可以将HttpServletRequest当做普通的bean注入。代码如下RestControllerpublicclassUserController{AutowiredprivateHttpServletRGetMapping(getIP)publicStringgetIP(){returnrequestipis:request。getRemoteHost();}}直接注入分析
  通过Autowired的方式引入request也很简单,想想这里会有问题吗?。。。。。。。
  Controller不是一个单例bean对象吗?在一个Spring容器内只有一个实例,而每次请求都对应一个request对象,Spring是怎样做到使用一个request表示多个请求的?
  经过仔细分析,我们可以发现Spring注入bean时使用了底层的DefaultListableBeanFactory获取bean实例,相关代码如下。publicclassDefaultListableBeanFactoryextendsAbstractAutowireCapableBeanFactoryimplementsConfigurableListableBeanFactory,BeanDefinitionRegistry,Serializable{不依赖关系privatefinalMapC?,ObjectresolvableDependenciesnewConcurrentHashMap(16);查找候选beanprotectedMapString,ObjectfindAutowireCandidates(NullableStringbeanName,C?requiredType,DependencyDescriptordescriptor){部分代码省略MapString,ObjectresultnewLinkedHashMap(candidateNames。length);for(Map。EntryC?,ObjectclassObjectEntry:this。resolvableDependencies。entrySet()){C?autowiringTypeclassObjectEntry。getKey();if(autowiringType。isAssignableFrom(requiredType)){ObjectautowiringValueclassObjectEntry。getValue();解析ObjectFactoryautowiringValueAutowireUtils。resolveAutowiringValue(autowiringValue,requiredType);if(requiredType。isInstance(autowiringValue)){result。put(ObjectUtils。identityToString(autowiringValue),autowiringValue);}}}部分代码省略}}
  DefaultListableBeanFactory查找候选bean时会先从resolvableDependencies中查找,找到后调用AutowireUtils。resolveAutowiringValue方法再次解析。
  resolvableDependencies中对象是Spring中特殊的存在,不属于Spring管理的bean,需要手动注册到DefaultListableBeanFactory。
  我们继续跟踪源码。abstractclassAutowireUtils{publicstaticObjectresolveAutowiringValue(ObjectautowiringValue,C?requiredType){if(autowiringValueinstanceofObjectFactory!requiredType。isInstance(autowiringValue)){ObjectFactory类型值和所需类型不匹配,创建代理对象ObjectF?factory(ObjectF?)autowiringVif(autowiringValueinstanceofSerializablerequiredType。isInterface()){创建代理对象,可用于处理HttpServletRequest注入等问题autowiringValueProxy。newProxyInstance(requiredType。getClassLoader(),newC?〔〕{requiredType},newObjectFactoryDelegatingInvocationHandler(factory));}else{returnfactory。getObject();}}returnautowiringV}}
  当resolvableDependencies中对象是ObjectFactory类型,并且与所需的类型不匹配,Spring使用ObjectFactory创建了一个JDK代理对象:privatestaticclassObjectFactoryDelegatingInvocationHandlerimplementsInvocationHandler,Serializable{privatefinalObjectF?objectFpublicObjectFactoryDelegatingInvocationHandler(ObjectF?objectFactory){this。objectFactoryobjectF}OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object〔〕args)throwsThrowable{try{returnmethod。invoke(this。objectFactory。getObject(),args);}catch(InvocationTargetExceptionex){throwex。getTargetException();}}}
  代理的实现简单,每当所需类型的方法调用时,就调用ObjectFactory中获取的实例对象的对应方法。
  那怎么与HttpServletRequest关联启来呢?
  Spring在启动时会注册Web环境相关的依赖对象publicabstractclassWebApplicationContextUtils{publicstaticvoidregisterWebApplicationScopes(ConfigurableListableBeanFactorybeanFactory,NullableServletContextsc){beanFactory。registerScope(WebApplicationContext。SCOPEREQUEST,newRequestScope());beanFactory。registerScope(WebApplicationContext。SCOPESESSION,newSessionScope());if(sc!null){ServletContextScopeappScopenewServletContextScope(sc);beanFactory。registerScope(WebApplicationContext。SCOPEAPPLICATION,appScope);RegisterasServletContextattribute,forContextCleanupListenertodetectit。sc。setAttribute(ServletContextScope。class。getName(),appScope);}ServletRequest类型对应ObjectFactory注册beanFactory。registerResolvableDependency(ServletRequest。class,newRequestObjectFactory());beanFactory。registerResolvableDependency(ServletResponse。class,newResponseObjectFactory());beanFactory。registerResolvableDependency(HttpSession。class,newSessionObjectFactory());beanFactory。registerResolvableDependency(WebRequest。class,newWebRequestObjectFactory());if(jsfPresent){FacesDependencyRegistrar。registerFacesDependencies(beanFactory);}}}
  可以看到:Spring为ServletRequest注入的是RequestObjectFactory类型,那再看看它的实现:publicabstractclassWebApplicationContextUtils{privatestaticclassRequestObjectFactoryimplementsObjectFactoryServletRequest,Serializable{OverridepublicServletRequestgetObject(){returncurrentRequestAttributes()。getRequest();}ReturnthecurrentRequestAttributesinstanceasServletRequestAttributes。seeRequestContextHoldercurrentRequestAttributes()privatestaticServletRequestAttributescurrentRequestAttributes(){RequestAttributesrequestAttrRequestContextHolder。currentRequestAttributes();if(!(requestAttrinstanceofServletRequestAttributes)){thrownewIllegalStateException(Currentrequestisnotaservletrequest);}return(ServletRequestAttributes)requestA}OverridepublicStringtoString(){returnCurrentHttpServletR}}}
  可以看到,和前面介绍的【静态方法】思路一样。
  以上就是3种在spring场景中,获取request的方法,get到了吗?
投诉 评论

新能源SUV销量50强ModelY夺销冠,埃安挤进前十一直以来,在车型细分市场中,SUV可以说最受关注。毕竟,空间、通过性方面的先天优势,成为了很多消费者的首选,也是车企最为看中的领域。因此,素有得SUV者得天下一说。在新能源车市……北京球迷卡塔尔世界杯夜宵,鸡爪花生小龙虾每场比赛都不同北京球迷:卡塔尔世界杯夜宵,鸡爪花生小龙虾每场比赛都不同,冬天看世界杯,也不能没有小零食和啤酒的加持。2022年卡塔尔世界杯开赛,帮大家查看了一下比赛时间,集中在北京时间……丁彦雨航或迎来新球队!山东男篮没有位置,小丁的条件太苛刻丁彦雨航或迎来新球队!山东男篮没有位置,小丁的条件太苛刻CBA比赛结束之后,球迷都知道,山东男篮虽然打进了季后赛,但是相对于之前的赛季来说,确实成绩差了太多了,而现在山东……大格局女生又美又飒,刷到就是上天在提醒你格局越大,破事越少。就像这段话所说的:站在1楼,有人骂你,你听到了很生气站在10楼,有人骂你你,听不清,还以为他在打招呼站在100楼,有人骂你,你放眼望去,只……如何亲自操盘一场四渡赤水式的战役,恐怕只有星际争霸能够做到星际争霸是我认为最接近于真实战争的一款游戏,虽然作为老一代游戏已经鲜有年轻人触碰,但其作为游戏鄙视链顶端的地位却一直未被动摇。今天带来的是一场新鲜出炉的比赛,考虑到游戏小众,我……哺乳期可以不用戴套?生完孩子多久需要避孕?避孕哪种办法最好?听说不来月经就是不排卵,而孕期和哺乳期会有很长一段时间处于闭经状态,很多人就认为无需避孕。尤其是哺乳期,很多人甚至认为只要在哺乳,就不会怀孕。于是,很多家庭迎来了意外的二……在三江交汇处,要搞一件大事在南海之滨有一个地方有浩瀚海洋,亦有潺潺河流有绵延山岭,亦有点点沙洲这里就是博鳌三江入海,独占鳌头博鳌处于万泉、九曲、龙滚三江汇合之处……Springweb开发之Request获取三种方式在开发JavaWeb项目中,我们经常使用HttpServletRequest获取请求参数、请求头等信息。在Spring项目,我们通常会使用Spring提供的注解获取参数,如Re……杨幂时髦清纯的穿搭优质内容我来评一直以来,明星的着装都代表着最新的潮流和时尚,受到了很多人的模仿和推崇。近日,有网友在自己的社交媒体上晒出了著名演员杨幂现身机场并返回剧组拍摄的视频。杨幂的……活动雅典娜皮肤最后一次返场,限定天幕?玉镖又开启了头条创作挑战赛大家好啊我是老柠萌,感谢大家阅读我的活动速报。【正式服11月24日将全服不停机更新】没想到返场的是神奇女侠,而不是梅西。。。。。。活动内容整理得……美媒华为的问题被逐个击破,断供的开始就是个错误头条创作挑战赛美国对华为的制裁是由于华为强大而引起的,但是现在美国似乎已经搬石头砸自己脚了。在美国断供之后,除对华为的手机业务造成打击之外。在5G网络布局,芯片研发……3。1Linux目录详细介绍1目录结构:根目录,一般根目录下只存放目录,不要存放文件,etc、bin、dev、lib、sbin应该和根目录放置在一个分区中bin:usrbin:可执行二进制文件……
秋天不要再喝奶茶了,这几种果饮让生活更健康秋冬季节,要多吃这5种水果,对人体大有好处,看完记得告诉家人生育率低并非年轻人自私,这2个问题不解决,开放四胎也白搭2022买手机眼光要放长远,这三款一步到位,轻松用四五年三款老旗舰骁龙888售价大幅下调最低价格才1999元有你喜欢菱智PLUS旅行版让你的生活更惬意笔记本台式机电脑显卡天梯图2022年8月最新排名,GPU性能星光都是很多年前发出的,为何我们看星星时感觉看到的是现在?原神大家开荒都用谁一路打过来的?专访爸爸写给女儿的书亲子阅读可以这样脑洞大开皮肤经常瘙痒怎么办好多年了小屏旗舰永不过时,VivoX90mini渲染图曝光,性能影像冬天怎么让宝宝爬冬天婴儿爬行的好处浅论信息化及西部大开发论文滑雪的高中作文推荐十大经典粤菜太美味了,馋得流口水了!ESPN巴黎与尼斯加尔蒂达协议,未来几天官宣新帅上任我的自画像作文300字越南战争中除了美国还有哪些国家参与了对越作战?误食干燥剂有危险吗柱上负荷开关(柱上开关电器的选择与使用)家居风水篇之别墅装修风水禁忌知识苦行皮裤怎么清洗皮裤正确清洗方法

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利