参考:编程帮
**Spring MVC **框架是一个开源的 Java 平台,为开发强大的基于 Java 的 Web 应用程序提供全面的基础架构支持非常容易和非常快速。
Spring web MVC框架提供了MVC(模型 - 视图 - 控制器)架构和用于开发灵活和松散耦合的Web应用程序的组件。
MVC模式导致应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离,同时提供这些元素之间的松散耦合。
MVC 设计模式一般指 MVC 框架,M(Model)指数据模型层,V(View)指视图层,C(Controller)指控制层。使用 MVC 的目的是将 M 和 V 的实现代码分离,使同一个程序可以有不同的表现形式。
其中,View 的定义比较清晰,就是用户界面。
在 Web 项目的开发中,能够及时、正确地响应用户的请求是非常重要的。用户在网页上单击一个 URL 路径,这对 Web 服务器来说,相当于用户发送了一个请求。而获取请求后如何解析用户的输入,并执行相关处理逻辑,最终跳转至正确的页面显示反馈结果,这些工作往往是控制层(Controller)来完成的。
在请求的过程中,用户的信息被封装在 User 实体类中,该实体类在 Web 项目中属于数据模型层(Model)。
在请求显示阶段,跳转的结果网页就属于视图层(View)。
视图层(View):负责格式化数据并把它们呈现给用户,包括数据展示、用户交互、数据验证、界面设计等功能。
具体的页面展示
控制层(Controller):负责接收并转发请求,对请求进行处理后,指定视图并将响应结果发送给客户端。
数据接收与处理
数据模型层(Model):模型对象拥有最多的处理任务,是应用程序的主体部分,它负责数据逻辑(业务规则)的处理和实现数据操作(即在数据库中存取数据)。
业务处理
总之,我们通过 MVC 设计模式最终可以打造出一个松耦合+高可重用性+高可适用性的完美架构。
结合 Spring 框架使用。
Spring MVC主要由DispatcherServlet(前端控制器)、HandlerMapping(处理器映射器)、HandlerAdapter(处理器适配器)、Handler(处理器)、ViewResolver(视图解析器)和 View(视图)组成。它的两个核心是两个核心:
通过以上两点,Spring MVC保证了如何选择控制处理请求和如何选择视图展现输出之间的松耦合。
发送请求
用户点击某个请求路径,发起一个 HTTP request 请求,该请求会被提交到 DispatcherServlet(前端控制器)
由 DispatcherServlet 请求一个或多个 HandlerMapping(处理器映射器),并返回一个执行链(HandlerExecutionChain)
遍历容器中存在的 HandlerMapping 找寻能够处理的 Handler
![]()
DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器)
适配器模式,并不会找寻具体的 Handler 而是找寻对象 HandlerAdapter 这样的好处在于可以解耦合,对接口负责,便于添加新的 Handler
HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(常称为 Controller)
Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC的底层对象,包括 Model 数据模型和 View 视图信息)
所有的提交信息都会被封装到这个 ModelAndView 中
HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet
DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析
ViewResolver 根据 View 信息匹配到相应的视图结果,并返回给 DispatcherServlet
DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图)
视图负责将结果显示到浏览器(客户端)
DispatcherServlet 是前端控制器,从图 1 可以看出,Spring MVC 的所有请求都要经过 DispatcherServlet 来统一分发。DispatcherServlet 相当于一个转发器或中央处理器,控制整个流程的执行,对各个组件进行统一调度,以降低组件之间的耦合性,有利于组件之间的拓展。
HandlerMapping 是处理器映射器,其作用是根据请求的 URL 路径,通过注解或者 XML 配置,寻找匹配的处理器(Handler)信息。
HandlerAdapter 是处理器适配器,其作用是根据映射器找到的处理器(Handler)信息,按照特定规则执行相关的处理器(Handler)。
Handler 是处理器,和 Java Servlet 扮演的角色一致。其作用是执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装至 ModelAndView 对象中。
View Resolver 是视图解析器,其作用是进行解析操作,通过 ModelAndView 对象中的 View 信息将逻辑视图名解析成真正的视图 View(如通过一个 JSP 路径返回一个真正的 JSP 页面)视图渲染。
View 是视图,其本身是一个接口,实现类支持不同的 View 类型(JSP、FreeMarker、Excel 等)。
以上组件中,需要开发人员进行开发的是处理器(Handler,常称Controller)和视图(View)。通俗的说,要开发处理该请求的具体代码逻辑,以及最终展示给用户的界面。
控制器采用单例模式,在进行多线程访问的时候有线程安全问题,不建议使用同步方法,会有性能问题。
声明该类时一个控制器。
@Controller
public class IndexController {
// 处理请求的方法
}
Spring MVC 使用扫描机制找到应用中所有基于注解的控制器类,所以,为了让控制器类被 Spring MVC 框架扫描到,需要在配置文件中声明 spring-context,并使用
元素指定控制器类的基本包(请确保所有控制器类都在基本包及其子包下)。
<!-- 使用扫描机制扫描控制器类,扫描指定路径包及其子包下 -->
<context:component-scan base-package="xx.xx" />
一个控制器内有多个处理请求的方法,如 UserController 里通常有增加用户、修改用户信息、删除指定用户、根据条件获取用户列表等。每个方法负责不同的请求操作,而 @RequestMapping 就负责将请求映射到对应的控制器方法上。
@RequestMapping 注解可用于类或方法上。用于类上,表示类中的所有响应请求的方法都以该地址作为父路径。
value:@RequestMapping 注解的默认属性,因此如果只有 value 属性时,可以省略该属性名,如果有其它属性,则必须写上 value 属性名称
@RequestMapping(value="toUser") // 多个属性
@RequestMapping("toUser") // 默认 value
value 属性支持通配符匹配,如 @RequestMapping(value=“toUser/*”) 表示 http://localhost:8080/toUser/1 或 http://localhost:8080/toUser/hahaha 都能够正常访问。
path:path 属性和 value 属性都用来作为映射使用
name:name属性相当于方法的注释,使方法更易理解。如 @RequestMapping(value = “toUser”,name = “获取用户信息”)
method:用于表示该方法支持哪些 HTTP 请求。如果省略 method 属性,则说明该方法支持全部的 HTTP 请求
@RequestMapping(value = “toUser”,method = RequestMethod.GET) 表示该方法只支持 GET 请求。也可指定多个 HTTP 请求,如 @RequestMapping(value = “toUser”,method = {RequestMethod.GET,RequestMethod.POST}),说明该方法同时支持 GET 和 POST 请求。
params:用于指定请求中规定的参数,在访问具体路径时需要携带以 params 的参数
@RequestMapping(value = "toUser",params = "type") public String toUser() { return "showUser"; }
以上代码表示请求中必须包含 type 参数时才能执行该请求。即 http://localhost:8080/toUser?type=xxx 能够正常访问 toUser() 方法,而 http://localhost:8080/toUser 则不能正常访问 toUser() 方法。
header:表示请求中必须包含某些指定的 header 值
consumers:用于指定处理请求的提交内容类型(Content-Type)
// 指定数据的提交类型为 json,否则无法正确接收
@RequestMapping(value = "toUser",consumes = "application/json")
produces:用于指定返回的内容类型,返回的内容类型必须是 request 请求头(Accept)中所包含的类型
如:@RequestMapping(value = “toUser”,produces = “application/json”)。
除此之外,produces 属性还可以指定返回值的编码。如 @RequestMapping(value = “toUser”,produces = “application/json,charset=utf-8”),表示返回 utf-8 编码。
数据响应式,返回数据。
希望在多个请求之间共用数据,则可以在控制器类上标注一个 @SessionAttributes,配置需要在session中存放的数据范围,Spring MVC将存放在model中对应的数据暂存到HttpSession 中。
只能使用在类定义上。
@SessionAttributes 除了可以通过属性名指定需要放到会 话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中。
Spring MVC Controller 接收请求参数的方式有很多种,有的适合 get 请求方式,有的适合 post 请求方式,有的两者都适合。主要有以下几种方式:
实体 Bean 接收请求参数适用于 get 和 post 提交请求方式。需要注意,Bean 的属性名称必须与请求参数名称相同。
Spring MVC 会将接收到的属性和值封装到 Bean 中。
@RequestMapping("/login")
public String login(User user, Model model) {
// 获取封装后的值
if ("xxx".equals(user.getName())
&& "123456".equals(user.getPwd())) {
// 将业务处理后的结果封装到 Attribute 中,也就是封装到响应中
// 前端也可以获取到相应的信息
model.addAttribute("message", "登录成功");
// 登录成功,跳转到 main.jsp
return "main";
} else {
model.addAttribute("message", "用户名或密码错误");
return "login";
}
}
形参名称与请求参数名称完全相同。该接收参数方式适用于 get 和 post 提交请求方式。
@RequestMapping("/login")
// 按顺序赋值
public String login(String name, String pwd, Model model) {
if ("xxx".equals(user.getName())
&& "123456".equals<