Java Web 学习(4) —— Spring MVC 概览
Spring MVC 概览
一、 Spring MVC
Spring MVC 是一个包含了 Dispatcher Servlet 的 MVC 框架。
Dispatcher Servlet 实现了 :
- 根据 Uri 调用相应的 action
- 实例化正确的控制器类
- 根据请求参数值来构造表单 bean
- 调用控制器对象的相应方法
- 转向一个 JSP 页面
使用 Spring MVC 的好处:
- Spring MVC 提供了一个Dispatcher Servlet,无需额外开发。
- Spring MVC 使用基于XML的配置文件,可以编辑,而无需重新编译应用程序。
- Spring MVC 实例化控制器,并根据用户输入来构造bean。
- Spring MVC 可以自动绑定用户输入,并正确地转换数据类型。
- Spring MVC 可以校验用户输入,若校验不通过,则重定向回输入表单。
- Spring MVC 是Spring 框架的一部分,可以利用 Spring 提供的其他能力。
- Spring MVC 支持国际化和本地化,支持根据用户区域显示多国语言。
- Spring MVC 支持多种视图技术。
二、 DispatcherServlet
在 Spring MVC 中,org.springframework.web.servlet.Dispatcher
扮演一个调度员的角色。
- 在请求离开浏览器时,会带有用户所请求内容的信息,至少会包含请求的 URL,但是还可能带有其他的信息,例如用户提交的表单信息。请求首先通过 DispatcherServlet。DispatcherServlet 作为前端控制器(front controller)处理所有请求,将请求发送给控制器。
- DispatcherServlet 需要确定将请求发送给哪个控制器,因此它会查询一个或多个处理器映射(handler mapping)。处理器映射会根据请求携带的URL信息进行决策。
- DispatcherServlet 将请求发送给目标控制器,卸下用户提交的信息,等待控制器(中的服务对象)处理业务逻辑。控制器完成逻辑处理后,通常会产生一些信息,需要返回给用户并在浏览器上显示。这些信息被称为模型(model)。信息需要发送给一个视图(view),比如 JSP。
- 控制器所做的最后一件事就是将模型数据打包,并且标示出用于渲染输出的视图名。它会将请求连同模型和视图名发送回 DispatcherServlet。
- 这样,控制器就不会与特定的视图相耦合,它仅仅传递了一个逻辑名称。DispatcherServlet 将会使用视图解析器(View Resolver)来将逻辑视图名匹配为一个特定的视图实现。
- DispatcherServlet 将模型数据交付给视图。视图将使用模型数据渲染输出,这个输出会通过响应对象传递给客户端。
要使用这个 Servlet,需要在部署描述符(web.xml)中配置。
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!-- Spring MVC 配置文件位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/springmvc.xml</param-value>
</init-param>
<1oad-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
注意:Dispatcher Servlet 默认配置文件为 WEB-INF 路径下的 servletName-servlet.xml。可以通过contextConfigLocation
可以修改配置文件路径。
三、 Controller
组件扫描
在 Spring MVC 配置文件中配置<componet-scan>
元素,Spring 会扫描基本包,找到组件。
<context:component-scan base-package="basePackage"/>
请求处理
@Controller // 声明为一个控制器
public class ProductController {
// 处理对"/input-product"的 get 和 post 请求
@RequestMapping(value = "/input-product", method = {RequestMethod.POST, RequestMethod.GET})
public String inputProduct () {
return "ProductForm"; // 返回名为 "ProductForm" 的视图
}
}
@Controller
@RequestMapping("/product")
public class ProductController {
// http://domain/context/product/input 将会映射为该方法
@RequestMapping(value = "/input", method = RequestMethod.GET)
public String inputProduct () {
return "ProductForm";
}
}
在请求处理方法中可以出现的参数类型:
- javax.servlet.ServletRequest 或 javax.servlet.http.HttpServletRequest
- javax.servlet.ServletResponse 或 javax.servlet.http.HtpServletResponse
- javax.servlet.http.HttpSession
- org.springframework.web.context.request.WebRequest
- org.springframework.web.context.request.NativeWebRequest
- java.util.Locale
- java.io.InputStream 或 java.io.Reader
- java.io.OutputStream 或 java.io.Writer。
- java.security.Principal
- HttpEntity<?>paramters
- java.util.Map 或 org.springframework.ui.Model
- org.springframework.ui.ModelMap
- org.springframework.web.servlet.mvc.support.RedirectAttributes
- org.springframework.validation.Errors
- org.springframework.validation.BindingResult
- 命令或表单对象。
- org.springframework.web.bind.support.SessionStatus
- org.springframework.web.util.UriComponentsBuilder
- @PathVariable @MatrixVariable @RequestParam @RequestHeader @RequestBody @RequestPart 注释的对象
在请求处理方法中可以返回的对象类型:
- ModelAndView
- Model
- 包含模型的属性的 Map
- View
- 代表逻辑视图名的 String
- void
- 提供对Servlet的访问,以响应HTTP头部和内容 HttpEntity 或 ResponseEntity 对象
- Callable
- DeferredResult
- 其他任意类型,Spring 将其视作输出给 View 的对象模型
请求参数和路径变量
请求参数和路径变量都可用于发送值给服务器。二者都是 URL 的一部分。
请求参数采用key=value
的形式,用&
分隔。在 Spring MVC 中用@RequestParam
获取。
http://localhost:8080/test/view-product?productId=3
public void sendProduct (@RequestParam int productId) {}
路径变量类似请求参数,但没有key
部分。在 Spring MVC 中用@PathVariable
获取。
http://localhost:8080/test/view-product/3
@RequestMapping(value="/view-product/{id}")
public String viewProduct(@PathVariable Long id, Model model) {}
传递模型
Spring MVC 在每次调用请求处理方法时,都会创建 Model 类型的一个实例。
Model 实际上就是一个 Map,它会作为请求(request)属性传递给视图,这样数据就可以渲染到客户端了。
@RequestMapping(value="/input-product")
public String inputProduct(Model model){
model.addAttribute("book", new Book());
return "BookAddForm";
}
当addAttribute
方法不指定 key 时,key 会根据 value 的类型推断。
当请求处理方法返回值是其他类型时,返回值会被放到模型中,逻辑视图名称会根据请求路径推断。
@RequestMapping(value="/input") // 逻辑视图名为 input
public String inputProduct(Model model){
return new Book();
}
Spring MVC 会在调用请求处理方法之前调用带 @ModelAtribute
注解的方法。带@ModelAttribute
注解的方法可以返回一个对象或一个 void 类型。
如果返回一个对象,则返回对象会自动添加到 Model 中。
如果方法返回void,则必须添加一个 Model 类型的参数,并自行将实例添加到Model中。
@ModelAttribute
public Product addProduct(GRequestParam String productId){
return productService. get(productId);
}
@ModelAttribute
public void populateModel(@RequestParam String id, Model model) {
model.addAttribute(new Account(id));
}
用在方法参数上的@ModelAttribute
注解指示了参数应该从模型(Model)中获取。
如果模型中不存在,参数会首先被实例化,然后添加到模型中。
如果模型中存在,这个参数的字段会被所有的名字匹配的请求参数所填充,即数据绑定。
四、 ViewResolver
ViewResolver 是视图解析器。ViewResolver 通过解析 ModelAndView,将 ModelAndView 转换成一个真正的 View 对象,并取出 Model。View 再对 Model 进行渲染,将渲染后的视图展示给用户。
Spring MVC 提供了13个视图解析器,如 BeanNameViewResolver,ResourceBundleViewResolver,UrlBasedViewResolver等。
InternalResourceViewResolver 是最常用的之一。
InternalResourceViewResolver 继承 UrlBasedViewResolver 继承 AbstractCachingViewResolver,实现了 ViewResolver 接口。
InternalResourceViewResolver 一般用于将视图名解析为 JSP 文件。
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="100"/>
</bean>
当控制器返回"index"时,解析器会自动添加前后缀,寻找"/WEB-INF/jsp/index.jsp"
order 代表视图解析器优先级。当配置多个视图解析器时,控制器返回的逻辑视图(return String)会经过视图解析器链。前面的解析失败后,会由后面的解析器解析。
而 InternalResourceViewResolver 无论资源是否存在,都会尝试解析,即永远返回非空 View 对象,后面的解析器不会起作用。因此它的优先级必须设置为最低,即 order 最大。
如果没有配置视图解析器,Spring 默认会使用 BeanNameViewResolver,这个视图解析器会查找 ID 与视图名称匹配的 bean,并且查找的 bean 要实现 View 接口。
参考资料:《Spring MVC 学习指南》 Paul Deck 著
《Spring 实战》 Craig Walls 著
Java Web 学习(4) —— Spring MVC 概览的更多相关文章
- Java Web 学习(7) —— Spring MVC 之国际化
Spring MVC 之国际化 i18n 与 l10n internationalization:国际化,以 i 开头,以 n 结尾,中间 18 个字母,简称 i18n. localization:本 ...
- Java Web 学习(8) —— Spring MVC 之文件上传与下载
Spring MVC 之文件上传与下载 上传文件 表单: <form action="upload" enctype="multipart/form-data&qu ...
- Java Web 学习(6) —— Spring MVC 之校验器
Spring MVC 之校验器 数据验证 一个典型的 Spring MVC 应用会同时应用到 formatters/converters 和 validators. 在调用 controller 期间 ...
- Java Web 学习(5) —— Spring MVC 之数据绑定
Spring MVC 之数据绑定 数据绑定是将用户输入绑定到领域模型的一种特性. Http 请求传递的数据为 String 类型,通过数据绑定,可以将数据填充为不同类型的对象属性. 基本类型绑定 @R ...
- Java Web系列:Spring MVC基础
1.Web MVC基础 MVC的本质是表现层模式,我们以视图模型为中心,将视图和控制器分离出来.就如同分层模式一样,我们以业务逻辑为中心,把表现层和数据访问层代码分离出来是一样的方法.框架只能在技术层 ...
- 【Java Web开发学习】Spring MVC 使用HTTP信息转换器
[Java Web开发学习]Spring MVC 使用HTTP信息转换器 转载:https://www.cnblogs.com/yangchongxing/p/10186429.html @Respo ...
- 【Java Web开发学习】Spring MVC添加自定义Servlet、Filter、Listener
[Java Web开发学习]Spring MVC添加自定义Servlet.Filter.Listener 转载:https://www.cnblogs.com/yangchongxing/p/9968 ...
- 【Java Web开发学习】Spring MVC 拦截器HandlerInterceptor
[Java Web开发学习]Spring MVC 拦截器HandlerInterceptor 转载:https://www.cnblogs.com/yangchongxing/p/9324119.ht ...
- 【Java Web开发学习】Spring MVC文件上传
[Java Web开发学习]Spring MVC文件上传 转载:https://www.cnblogs.com/yangchongxing/p/9290489.html 文件上传有两种实现方式,都比较 ...
随机推荐
- Dynamics 365客户端编程示例:两个选项集字段的联动
我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...
- 与用户xxx一起提供的密码不正确。请确认输入的密码正确并重试
环境: SharePoint 2010 / 2013 以系统账户身份登录管理中心,然后创建Web Application,报: 与用户xxx一起提供的密码不正确.请确认输入的密码正确并重试 明明都已经 ...
- You don't have permission to access / on this server,Forbidden
wampserver配置虚拟主机Forbidden,apache You don't have permission to access 找到httpd.conf文件(通常在安装apache的conf ...
- Codeforces 547C/548E - Mike and Foam 题解
目录 Codeforces 547C/548E - Mike and Foam 题解 前置芝士 - 容斥原理 题意 想法(口胡) 做法 程序 感谢 Codeforces 547C/548E - Mik ...
- 05-Node.js学习笔记-第三方模块
5.1什么是第三方模块 别人写好的,具有特定功能的,我们能直接使用的模块即第三方模块,由于第三方模块通常都是由多个文件组成并且被放置在一个文件夹中,所以又名包. 第三方模块有两种存在形式 以js文件的 ...
- Jmeter脚本录制攻略
基于Apache JMeter(5.2.1) 首先在TestPlan里添加一个HTTP代理服务武器: 设置端口,在目标控制器里选择线程组. 在Chrome浏览器里设置代理: 点击启动按钮后,在浏览器登 ...
- DDL--DML
DDL 数据定义语言 DDL是基于数据表级别的操作的统称,对数据表的 创建 删 改 删除 drop -- 删除表,记录日志 truncate -- 删除表中的全部数据,不删除表,不记录日志 修改 al ...
- golang中,new和make的区别
在golang中,make和new都是分配内存的,但是它们之间还是有些区别的,只有理解了它们之间的不同,才能在合适的场合使用. 简单来说,new只是分配内存,不初始化内存: 而make即分配又初始化内 ...
- 资深架构师教你String 常量池、 String.itern()
什么是常量 用final修饰的成员变量表示常量,值一旦给定就无法改变! final修饰的变量有三种:静态变量.实例变量和局部变量,分别表示三种类型的常量. Class文件中的常量池 在Class文件结 ...
- 【Visio流程图】借助redis来实现数据即时刷新
[需求:]数据从竞品网站爬过来,经过分析处理之后,把结果通过网页实时反馈给业务人员. [应用:]2个应用: 一个是爬取数据的应用:不断从竞品网站爬数据,每次爬到的数据为一批.然后,对每一批爬到的数据进 ...