SpringMVC处理请求

本文深入探讨了SpringMVC中HttpServletBean和FrameworkServlet的请求处理流程,重点解析了LocaleContextHolder和RequestAttributesHolder的作用,以及DispatchServlet的doService方法和publishRequestHandledEvent事件发布。文章详细分析了在Service层如何获取Locale和RequestAttributes,并介绍了SpringMVC的事件监听机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HttpServletBean

这里写图片描述
从HttpServletBean的结构中可知,其没有重写service,doXXX等处理请求方法,所以HttpServletBean没有具体处理请求

FrameworkServlet

这里写图片描述
FrameworkServlet重写了HttpServlet的这些方法
这里写图片描述
可以看到Service之中将除了PATCH方法的所有请求都集中到processRequest中进行处理。
这和HttpServlet将不同请求按类型分到不同的方法中正好相反。为什么要这么做?其实SpringMVC对不同类型的请求划分的很好,这里只是应该有其他的事情要做,并且将结构分得更为清晰。先看processRquest
这里写图片描述
这里写图片描述
核心的是doService()模板方法,这个方法在DispatchServlet中实现。在doService前后还做了一些事情,这个就是装饰器设计模式。
在doService()之前是将请求之前的LocaleContext和RequestAttribute保存,然后获取当期请求的LocaleContext和RequestAttribute并设置上,doService()处理之后在finally中使用resetContextHolder再进行恢复。
最后发送一个ServletRequestHandledEvent。

LocaleContextHolder、RequestAttributesHolder

LocaleContext中存放的是本地化信息
这里写图片描述
这里写图片描述
这里写图片描述
首先要提到的一点是LocaleContextHolder是个abstract类,其中的所有方法都是static方法,可以直接调用,而且没有父类也没有子类。也即是不能对其进行实例化,只能调用其中的方法,这种设计是值得学习的。(ps:我通常写Django代码的时候写了很多的工具函数,其实没有做过封装,是很不好的。)

在LocaleContextHolder中封装了两个属性
这里写图片描述
都是ThreadLocal类型的,第二个可以被子线程继承,关于ThreadLocal可以参考:

另外LocalContextHolder提供了get/setLocal方法
这里写图片描述

举个例子程序中如果要使用到Locale的时候首先可以从request中获取,request.getLocale(),但是如果是在Service层中的话就没有request对象了,需要Controller将request传进来。这个就太麻烦了,而且需要修改Service层的接口。这个时候可以直接使用LocaleContextHolder.getLocale()获取Locale对象

RequestAttributes是Spring的一个接口
这里写图片描述
通过RequestAttributes可以get/set/removeAttributes,根据scope参数判定是操作的reques还是session
FrameworkServlet使用的是ServletRequestAttributes,看下其set方式(get/remove类似)
这里写图片描述
这里判定了一个属性isRequestActive(),当调用了requestComplete()方法后request的requestActive就变成了false,可以参看FrameworkServlet中finally中的调用。其实很容易立即,request执行完毕之后就是非active的了。
这里提出一个问题:我想Attributes应该是个Map属性,用来设置key-value,但是一直没有找到这个属性,在HttpServletRequest中没有找到,具体存储在哪里现在还不知道。。
这里写图片描述

在说一下RequestAttributesHolder,其和LocaleContextHolder的设计类似:
这里写图片描述
这里写图片描述
同样的可以在Service层中通过RequestAttributesHolder获取Request

HttpServletRequest req = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
HttpServletResponse resp = ((ServletWebRequest)RequestContextHolder.getRequestAttributes()).getResponse();

可以参考Spring MVC 中几种获取request和response的方式

publishRequestHandledEvent

在FrameworkServlet中的finally中调用了:
这里写图片描述
这里写图片描述
当publishEvent为true的时候就发送消息,在web.xml中publishEvent的配置默认为true。
对于监听这个消息值需要继承ApplicationListener接口,并实现onApplicationEvent方法
对于使用参考下这篇文章:利用spring的ApplicationListener监听某一类事件的发生

DispatchServlet

DispatchServelet是SpringMVC的核心类,所有的顶层设计都在这里。
通过之前的分析可以知道DispatchServlet中执行处理方法的入口是doService
这里写图片描述
设置属性中前面4个和Handler/View有关,后面的三个属性和flashMap有关,主要用与Redirect转发时参数的传递。具体之后研究

由上述代码可知doService()将具体的工作转发给了doDispatch()

这里写图片描述
这里写图片描述

SpringMVC是一个用于构建Web应用程序的Java框架。在SpringMVC中,处理请求和响应是通过使用控制器方法来实现的。控制器方法使用@RequestMapping注解来映射请求的URL,并通过方法参数来获取请求参数和响应对象。 在处理请求时,可以使用@RequestParam注解来获取请求参数的值。例如,可以在方法参数上使用@RequestParam注解来获取请求中的特定参数值。另外,也可以使用@PathVariable注解来获取URL中的路径参数。 在处理响应时,可以使用@ResponseBody注解将方法的返回值直接写入HTTP响应体中,而不是进行视图跳转。这样可以直接返回字符串、JSON格式的数据或其他类型的数据。 另外,在SpringMVC中,还有一些核心组件,如处理器映射器、处理器适配器和视图解析器。处理器映射器负责将请求映射到相应的控制器方法,处理器适配器负责将请求参数绑定到方法参数,并调用相应的控制器方法,视图解析器负责将方法的返回值解析为视图。 总结起来,SpringMVC通过控制器方法、注解和核心组件来处理请求和响应,使得开发者可以方便地构建Web应用程序。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [springMVC请求和响应](https://blog.csdn.net/weixin_38088097/article/details/105840310)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [SpringMVC请求和响应](https://blog.csdn.net/weixin_51146329/article/details/123166475)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值