Spring MVC基础篇
Spring MVC基本概念
MVC的基本概念
MVC是一种开发Web应用程序的通用架构方式,在SmallTalk、Python、Java中都有这种概念。
MVC的本质,及其核心思想就是业务数据抽取同业务数据呈现相分离
MVC(Model-View-Controller)
View视图层:为用户提供UI,重点关注数据的呈现,负责布局问题;
Model模型层:业务数据的信息标识,关注支撑业务的信息构成,通常是多个业务实体的组合;负责需要将什么信息展示给用户。
Controller控制层:通过调用业务逻辑产生合适的数据Model,传递数据给视图层用于呈现,负责调用哪些业务逻辑。
MVC是一种架构模式,使得程序分层,分工合作,既相互独立,又协同工作。
Spring MVC基本概念
Spring MVC可以实现MVC的这些概念。
先说几个概念
DispatcherServlet:是一种前控制器,MVC实现业务逻辑和业务数据的分离,实际上就是通过DispatcherServlet实现的。
HandlerAdapter(适配器模式)是DispatcherServlet内部使用的一个类,是Controller的一个表现形式,是为了实现Controller引入的。
HandlerInterceptor:接口,是一个拦截器,在Controller调用Handler之前之间之后都可以使用完成很多事情
HandlerMapping:Help D to get the rightcontroller;Wrap包围 controllerwith HandlerInterceptor.
HandlerExecutionChain:执行链条,通过HM返回了HI包围的Controller,构成一个执行链条
ModelAndView: 不管是Model还是Map都会转换成ModelAndView来实现。
ViewResolver:视图解析器,根据配置找出需要的视图对象,通知DispatcherServlet需要通过哪个视图来呈现。
View (in MVC):负责呈现页面。
概念动态图:
原理过程
D拦截到一个R,然后通过HM来代理,根据自己的配置找到自己需要的Controller然后找到对应的HI,得到Handler/HandlerAdapter,形成一个适配器执行链条,然后DS开始调用H或者HA来生成模型ModelAndView,返回给DS,为页面呈现做准备,然后开始显示工作,DS通过调用VR来生成View返回个DS,然后通过MAV呈现View,此时Response呈现出页面。
下面是一个更加详细的过程图:
使用Maven管理Spring MVC项目模块
Maven是构建SpringMVC项目搭建环境的依赖管理工具,其中核心文件为pom.xml;
POM(Project Object Model),是一个XML文件,包含很多依赖信息,如developers、organization、licenses……等;
简单的解释
(具体了解可参考Maven详解学习篇和pom文件解析篇)。
Maven用来管理各种项目,可以平衡管理个项目模块,将项目中所需要依赖的插件、jar包等资源的地址坐标和其他用到的信息写进pom.xml中,通过这个文件将这些资源从中央仓库或者镜像仓库中下载下来,存放在本地用户下所建的本地仓库,(如果本地仓库中没有新导入的项目中pom文件描述的所需依赖资源,则会重新花时间下载)。
平时建立项目之后,一般通过手动导入jar包,然后BuildPath,这样除了导入自己所需要的包,还附带了很多不需要的包,导致一个稍微有规模的项目还没有正式工作,就引入了一堆东西,使得项目变得臃肿庞大,难以加载启动。
但是,利用Maven管理项目一个明显的优点就是避免了上述情况,管理工具只下载pom文件描述的依赖项,不会下载多余的资源,从某种程度上来说,大大的为项目减负,轻量化了项目。
Pom.xml中的依赖
Dependency依赖,是指项目之间的依赖,有直接依赖和间接依赖关系,通常使用Jar包来包含起来的,彼此之间相互依赖,比如./WEB-INF/lib之间的Jar包之间存在很多依赖。如果我们在项目进行中,突然遇到缺失的jar包,那就有点儿尴尬了,需要花很多时间在这些不必要的工作上,但是,有了Maven,我们可以凭借这个依赖管理工具来建立依赖映射关系,不仅可以建立直接依赖关系,而且还可以传递间接依赖关系,这个过程都是透明化的。
但是,Maven是如何实现自动载入的呢?这个就使用到坐标关系了。
Coordinates 坐标
含有四个属性:groupId、artifactId、version、packaging,这四个属性构成了唯一标识,起到定位作用,其中Packaging可以缺省,因为它默认依赖于Jar包。
一个依赖spring包的示例:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Spring MVC项目搭建
此处使用Maven项目管理工具来管理SpringMVC项目。
详细Spring MVC项目搭建过程见链接:http://blog.csdn.net/csdn_terence/article/details/53841554
第一步:Maven安装和项目搭建
详细步骤见Maven篇:http://blog.csdn.net/csdn_terence/article/details/53517287
第二步:Spring MVC项目
用Spring MVC进行开发
WebApplicationContext公共上下文
(Controller响应,数据绑定,文件上传)
Spring MVC的上下文层级
多个DispatcherServlet使用同一个公共的上下文
为什么会出现多个DS?同一个网站会提供不同类型的服务,为了更加方便,使用不同的DispatcherServlet做不同的分发,为不同类型的请求提供不同的服务,这样更加方便快捷。
Controller总结
在Controller中,需要掌握的东西
1、@Controller :用类级别注解声明这是一个Controller,可被Spring的DispatcherServlet的上下文所管理,并且完成依赖注入。
2、@RequestMapping(“/**”) :通过类级别注解声明访问路径根目录的形式,表示此类url将被这个Controller所拦截。
3、@RequestMapping(value=”/**/**”,method=RequestMethod.GET/POST) :通过方法级别的注解声明访问的方法,携带路参。
4、URL template(@RequestParam and @PathVariable)
掌握路参绑定方式,例如:
public StringviewCourse2(@PathVariable("courseId")IntegercourseId,Map<String,Object> model) {}
5、HttpServletRequest and/or HttpSession 通过这两种对象完成页面请求和返回,注意需要配置依赖项servlet-api和spring-session。
Binding
数据绑定:将请求中的字段按照名字匹配的原则填入模型对象,所有字段共同构成表单数据,后台则是由模型对象代表现实世界,数据绑定则是将两者联系起来。
请求重定向与请求转发(面试常问的问题)DispatcherServlet
redirect/forward
@ModelAttribute通过方法参数级别的注解Annotation来绑定路参。
FileUpload
单文件上传
SpringMVC提供了文件上传的内置支持,只需要完成一定量正确的配置和编码工作,就可以通过接口完成文件上传功能。
第一步:需要在配置文件web.xml中配置上传的文件对应的bean
<!-- 200*1024*1024即200M的上传大小 resolvelazily属性启用是为了推迟文件解析,以便扑获文件大小异常
需要在依赖管理中引入阿帕奇的依赖包
-->
<beanid="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<propertyname="maxUploadSize"value="209715200"/>
<propertyname="defaultEncoding"value="UTF-8"/>
<propertyname="resolverLazily"value="true"/>
</bean>
第二步:需要配置依赖包
<dependency>
<!-- 此依赖中含有编码时要用都的对文件编码的IO包,所以不用显式的再引入了 -->
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
第三步:在Controller中Annotation注解声明方法请求指定的文件上传页面。
第四步:在文件上传页面递交的表单中需要加入文件上传的属性enctype,如:
<formmethod="post"action="/courses/doUpload"enctype="multipart/form-data">
<inputtype="file"name="file"/>
<inputtype="submit"/>
</form>
第五步:在controller中的方法中递交上传文件
//递交上传文件,并且跳到上传后的提示页面
//通过绑定路参,将递交的MultipartFile类型的文件file上传到服务器中
//无损传输单个文件
@RequestMapping(value="/doUpload",method=RequestMethod.POST)
public StringdoUploadFile(@RequestParam("file") MultipartFile file)throwsIOException
{
if(!file.isEmpty())
{
log.debug("Processfile:{}",file.getOriginalFilename());
FileUtils.copyInputStreamToFile(file.getInputStream(),new File("C:\\Users\\Terence\\workspace\\DOCUMENTS",System.currentTimeMillis()+"_"+file.getOriginalFilename()));
}
return"success";
}
Json在Spring MVC中的应用
Json是程序界的新星,运行很流行,使得开发方式发生很大的变化,使得前端和后端的分离更加彻底,使得越来越多的系统采用单页面开发模式。
JSON -----JavaScript Object Notation is a lightweightdatainterchange format,一种轻量级的数据交换格式。
Example:
{“employees”:[
{“firstName”:”John”,”lastName”:” Doe” },
{“firstName”:”Anna”,”lastName”:” Smith” },
{“firstName”:”Peter”,”lastName”:” Jones” },
] }
这种以JSON来呈现的数据模型就像HTML一样,可以呈现不通的表现方式,更加简洁易懂。
RestfulWeb Service 逐渐取代了厚重的soap???????
SpringMVC则是利用contentNegotiatingViewResolver来处理相同模型不通格式的JSON;
比如,人类用户需要的则是HTML的格式,对应需要JSPView,如果是机器用户,则需要JSON的格式,对应需要JsonView,
将相同格式的数据分化到不停格式数据的请求
编码实现步骤:
第一步:在SpringMVCDispatherServlet.xml中需要配置一个ViewRsolver,帮助SpringMVC将相同的数据呈现出不同的表现形式:
<beanclass="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<propertyname="order"value="1"/>
<propertyname="mediaTypes">
<map>
<entrykey="json"value="application/json"/>
<entrykey="xml"value="application/xml"/>
<entrykey="htm"value="text/html"/>
</map>
</property>
<propertyname="defaultViews">
<list>
<!-- JSON View 使用Jack2son类库,将数据模型转换成Json格式-->
<beanclass="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
</bean>
</list>
</property>
<propertyname="ignoreAcceptHeader"value="true"/>
</bean>
第二步:为SpringMVC中的JSON引入依赖包:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.4</version>
</dependency>
第三步:在controller中写一个支持json的方法:
技术亮点:
如果一个页面需要两种身份的对象,则可以用此方式将其分离,异步获取两种信息,动态的处理页面。(使用Ajax)
云图