Spring MVC 基础
Spring MVC 基础
1.Web MVC基础
MVC的本质是表现层模式,我们以视图模型为中心,将视图和控制器分离出来。就如同分层模式一样,我们以业务逻辑为中心,把表现层和数据访问层代码分离出来是一样的方法。框架只能在技术层面上给我们帮助,无法在思考和过程上帮助我们,而我们很多人都不喜欢思考和尝试。

2.实现Web MVC的基础
实现Web MVC基础可以概括为1个前段控制器和2个映射。
(1)前端控制器FrontController
ASP.NET和JSP都是以Page路径和URL一一对应,Web MVC要通过URL映射Controller和View,就需要一个前端控制器统一接收和解析请求,再根据的URL将请求分发到Controller。由于ASP.NET和Java分别以IHttpHandler和Servlet作为核心,因此ASP.NET MVC和Spring MVC分别使用实现了对应接口的MvcHandler和DispatcherServlet作为前段控制器。

ASP.NET中通过HttpModule的实现类处理URL映射,UrlRoutingModule根据URL将请求转发给前端控制器MvcHandler。Spring MVC中,则根据URL的配置,直接将请求转发给前端控制器DispatcherServlet。
(2)URL和Contrller的映射
ASP.NET MVC将URL和Controller的映射规则存储在RouteCollection中,前端控制器MvcHandler通过IController接口查找控制器。Spring MVC则通过RequestMapping和Controller注解标识映射规则,无需通过接口依赖实现控制i器。
(3)URL和View的映射
ASP.NET MVC 默认通过RazorViewEngine来根据URL和视图名称查找视图,核心接口是IViewEngine。Spring MVC 通过internalResourceViewResolver根据URL和视图名称查找视图,核心接口是ViewResolver。
3.Spring MVC快速上手
(1)Spring MVC初始化
ASP.NET MVC初始化需要我们在HttpApplication.Application_Start方法中注册默认的URL和Controller规则,Spring MVC由于采用注解映射URL和Controller,因此没有对应的步骤。ASP.NET在根web.config中配置了UrlRoutingModule可以将请求转发给MvcHandler,Spring MVC我们需要我们配置DispatcherServlet以及其对应的URL来达到接管所有请求的目的,Spring已经利用Servlet3.0定义的ServletContainerInitializer机制,为我们提供了默认的AbstractAnnotationConfigDispatcherServletInitializer,只要只需要像继承HttpApplication的MvcApplication一样,写一个MyWebApplicationInitializer。
(2)URL和View的映射
ASP.NET的RazorViewEngine内置了View的Path和扩展名.cshtml的规则。Spring MVC的internalResourceViewResolver没有提供默认值,因此如果我们如果不定义Path和扩展名,只需要MyWebApplicationInitializer即可。一般我们会指定将View放置在统一的视图目录中,使用特定的扩展名。Spring同样提供了DelegatingWebMvcConfiguration,我们只需写一个自己的AppConfig继承它,重写configureViewResolvers方法即可。完整的代码如下:

package s4s; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import org.springframework.web.servlet.view.InternalResourceViewResolver; public class MyWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
} @Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { AppConfig.class };
} @Override
protected String[] getServletMappings() {
return new String[] { "/" };
} } @Configuration
@ComponentScan
class AppConfig extends DelegatingWebMvcConfiguration { @Override
protected void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
registry.viewResolver(viewResolver);
}
}

(3)URL和Controller的映射
上文提到过Spring MVC和ASP.NET MVC的不同,不通过IController接口标识Controller,也不通过RouteCollection定义URL和Controller,取而代之的是两个注解:Controller和RequestMapping。我们简单的定义一个POJO MyController以及其简单的Home方法。并应用上述注解:

package s4s; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class MyController { @RequestMapping("/")
public String Home() {
return "home";
}
}

添加/WEB-INF/views/home.jsp视图文件,就完成了最简单的示例。无需web.xml的任何配置。
(4)使用Model
ASP.NET将视图最终编译为WebViewPage<object>,View和Model是一一对应并且类型匹配的,Model可以是任意的POCO。Spring MVC中View和Model是一对多的,提供了ModelMap和其子类ModelAndView提供类似ASP.NET MVC中ViewResult的功能。ModelMap的基类是LinkedHashMap<String, Object>。
我们修改MyController的代码,使用ModelAndView来传递一个简单UserModel模型,作为参数的UserModel对象model和ASP.NET MVC中一样,会自动将请求参数映射到model的属性。返回值ModelAndView时和ASP.NET MVC的return View(viewName,model)类似。只不过因为Spring MVC模型是多个模型的列表,我们还需要指定返回模型的Name。

package s4s; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView; @Controller
public class MyController {
@RequestMapping("/")
public ModelAndView Home(@ModelAttribute UserModel model) {
model.setUserName(model.getUserName() + "~");
return new ModelAndView("home", "model", model);
}
} class UserModel {
String userName = ""; public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
}
}

(5)使用View
修改home.jsp,添加jstl和spring的tag支持。由于Spring MVC中的View和ASP.NET MVC中的区别较大,没有办法指定View持有的Model类型也就没有了智能提示和错误检测的优势,一切回归到了脚本语言的时代。

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h2>spring form tag</h2>
<form:form modelAttribute="model" method="get">
<form:input path="userName" />
<input type="submit" value="submit">
</form:form>
</html>

附上pom.xml。其中junit是可选的,jstl是View中使用jstl语法需要引入的。
4.Spring MVC的初始化机制
(1)应用初始化:
Spring实现了Servlet 3.0规范定义的javax.servlet.ServletContainerInitializer接口并通过javax.servlet.annotation.HandlesTypes注解引用了WebApplicationInitializer接口。因此在Servlet容器初始化时,在当前class path路径下的WebApplicationInitializer实现类的onStartup方法会自动执行(这和ASP.NET的Application_Start作用类似,在系列中的Java Web基础时曾经提到过)。
(2)依赖注入的初始化:
ASP.NET中我们在Application_Start中初始化依赖注入容器。在Spring MVC中,我们实现WebApplicationInitializer接口同样可以执行依赖注入的初始化。在Web环境中,我们使用的ApplicationContext接口的实现类为基于注解的AnnotationConfigWebApplicationContext(在系列中的Spring依赖注入基础中曾经提到过),但我们无需直接实现WebApplicationInitializer并手动初始化AnnotationConfigWebApplicationContext对象,因为Spring已经定义了AbstractAnnotationConfigDispatcherServletInitializer作为WebApplicationInitializer接口的实现类,已经包含了AnnotationConfigWebApplicationContext的初始化。
(3)依赖注入配置:
采用基于Annotation注解时可以通过@Configurateion指定POJO来替代web.xml配置依赖注入。同样,@ComponentScan可以替代web.xml中的扫描配置功能,使用ComponentScan配合Configurateion可以达到0xml配置的方式。上文中提到的Contrller相关的注解,都是启用ComponentScan后才会被扫描生效。
(4)DispatcherServlet的初始化:
AbstractAnnotationConfigDispatcherServletInitializer类的父类AbstractDispatcherServletInitializer中已经包含DispatcherServlet的初始化。相关类图如下:

5.Spring MVC的Action Filter
.NET MVC提供了众多Filter接口和一个ActionFilterAttribute抽象类作为Filter的基础,其中以实现了IAuthorizationFilter接口的AuthorizeAttribute拦截器最为我们熟知。Spring MVC则提供了基于HandlerInterceptor接口的众多接口、抽象类和实现类,其中也有和.NET MVC类似的权限验证UserRoleAuthorizationInterceptor拦截器。内置的拦截器可以满足大部分需求,为了省事图就画在一张上了,上面是Spring MVC的,下面是.NET MVC的。
关于模型验证和权限验证的部分以后再续。
总结
(1)MVC实现的要点是前端控制器、URL和Controller的映射、URL和View的映射
(2)MvcHandler和DispatcherServlet
(3)ServletContainerInitializer和HttpApplication.Application_Start
(4)RazorViewEngine和internalResourceViewResolver
(5)IMvcFilter和HandlerInterceptor
参考:
(1)http://www.ibm.com/developerworks/cn/java/j-lo-jsr303/index.html
(2)http://spring.oschina.mopaas.com/validation.html#validation-binder
(3)http://www.mkyong.com/spring-mvc/spring-3-mvc-and-jsr303-valid-example/
Spring MVC 基础的更多相关文章
- Spring MVC基础
1.Web MVC基础 MVC的本质是表现层模式,我们以视图模型为中心,将视图和控制器分离出来.就如同分层模式一样,我们以业务逻辑为中心,把表现层和数据访问层代码分离出来是一样的方法.框架只能在技术层 ...
- Spring MVC基础知识整理➣环境搭建和Hello World
概述 Spring MVC属于SpringFrameWork的产品,采用Model-View-Controller进行数据交互,已经融合在Spring Web Flow里面.Spring 框架提供了构 ...
- Java Web系列:Spring MVC基础
1.Web MVC基础 MVC的本质是表现层模式,我们以视图模型为中心,将视图和控制器分离出来.就如同分层模式一样,我们以业务逻辑为中心,把表现层和数据访问层代码分离出来是一样的方法.框架只能在技术层 ...
- Spring MVC基础了解
参考网址:https://www.yiibai.com/spring_mvc/springmvc_overview.html Spring框架相关 Spring Security 一个灵活强大的身份验 ...
- Spring MVC基础入门
Spring MVC简介 Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱 ...
- spring mvc基础配置
web.xml 配置: <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class> ...
- Spring MVC 基础注解之@RequestMapping、@Controller、(二)
我现在学的是spring4.2 今天主要学习了Spring MVC注解 引入注解可以减少我们的代码量,优化我们的代码. @Controller:用于标识是处理器类: @RequestMapping:请 ...
- Spring MVC 基础笔记
spring mvc功能: 以Controller为中心完成对系统流程的控制管理 从请求中搜集数据 对传入的参数进行验证 将结果返回给视图 针对不同的视图提供不同的解决方案 针对jsp视图技术提供标签 ...
- Spring MVC基础学习
SpringMVC是Spring框架的一个模块,无需通过中间层整合在一起.SpringMVC是一个基于MVC设计模式web框架,MVC-model-view-controller:MVC将服务器端分为 ...
随机推荐
- Python编程中常用的12种基础知识总结
原地址:http://blog.jobbole.com/48541/ Python编程中常用的12种基础知识总结:正则表达式替换,遍历目录方法,列表按列排序.去重,字典排序,字典.列表.字符串互转,时 ...
- 最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)(转)
一,问题描述 在英文单词表中,有一些单词非常相似,它们可以通过只变换一个字符而得到另一个单词.比如:hive-->five:wine-->line:line-->nine:nine- ...
- Codeforce 57C Array
C. Array time limit per test 2 seconds memory limit per test 256 megabytes input standard input outp ...
- C语言实现通讯录
<span style="font-size:18px;">#include<stdio.h> #include<string.h> #incl ...
- python语言学习8——字符串和编码
Unicode编码 计算机只能处理数字,如果要处理文本,就必须把文本转化为数字才能处理 有许多编码标准,但是不同的编码标准有时候会混乱,所以Unicode应运而生 Unicode把所有语言统一到一套编 ...
- 基于Cocos2dx开发卡牌游戏Demo_放开那三国 2.0
PS:下载地址在最以下 1.登录 2.副本选择 3.地图 4. 选择敌人 5. 战斗 6. 战斗结算 7. 地图拓展 8. 武将拓展 9. 下载地址: 点击打开链接
- 通过Camera进行拍照
Android通过Camera来控制拍照,使用Camera比较简单,按步骤进行即可: 下面用一个示例来演示: Activity: package com.home.activity; import j ...
- Effective C++ -- 构造析构赋值运算
05.了解C++默默编写并调用哪些函数 编译产生的析构函数时non-virtual,除非这个类的基类析构函数为virtual 成员变量中有引用和const成员时,无法自己主动生成copy assign ...
- cpe移植framework后,。解决问题的现有数据库
最近,该公司的业务需求,原始订单apk的形式CPE.渗透framework层.这被剥离cpe,从事相当长的一段,终于有时间来写博客,记下遇到的问题,未来. 第一个问题是,原来的apk有些事情,移植fr ...
- 【译】ASP.NET MVC 5 教程 - 5:使用 SQL 服务器 LocalDB 创建连接字符串
原文:[译]ASP.NET MVC 5 教程 - 5:使用 SQL 服务器 LocalDB 创建连接字符串 在上一节中,我们创建了MovieDBContext 类来连接数据库.处理Movie 对象和数 ...