《经久不衰的Spring框架:SpringMVC 统括》
前言:经久不衰的Spring
这几年,前端技术更新换代速度之快,每一年“最火的前端技术”排行榜都会换一番场景,本当に信じかねる。是“只闻新人笑不见旧人哭”,还是“青山依旧在,几度夕阳红”,这些只有身处浪潮中才能慢慢体会。
跑偏了,赶紧回归正题。难道Java 相关技术没有变革?那肯定不是,这边说的只是Java 的企业级开发框架这块。记得笔者刚入职那年,就在使用SSH三大框架,时至今日,公司采用的SSM框架,这其中经久不衰的就是Spring了。常见的SSH三大框架,就是Spring、Struts、Hibernate,到后来半ORM框架ibatis 出现了,接着改名Mybatis,若将MVC框架替换为SpringMVC,即凑成了SSM框架(笔者目前在用的各框架版本是Spring 4.2.6、Hibernate 4.3.1、Mybatis 3.2.8)。
虽然是本人介绍Spring的第一篇文章,但这几大框架我不用多加介绍了,网上文章多如牛毛,我再描述,那就有点老生常谈的意味了。直接写一些开发工作中,遇到相关卡壳问题和经验总结,纯属记录,毕竟Java当前吃饭的饭碗。
SpringMVC 简介
SpringMVC是一种基于Java的实现了 Web MVC 设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将Web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发。它和Struts一样是一个MVC框架,它是Spring当中的一个子框架,和Spring无缝集成,和Struts2类似。
SpringMVC的前端控制器是DispatcherServlet;应用控制器其实拆为处理器映射器(Handler Mapping)进行处理器管理和视图解析器(View Resolver)进行视图管理;页面控制器/动作/处理器为Controller接口(仅包含ModelAndView handleRequest(request, response) 方法)的实现(也可以是任何的POJO类);支持本地化(Locale)解析、主题(Theme)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。
大概概述下 SpringMVC的步骤:
l 步骤1—— 对Http请求进行初步处理,查找与之对应的Controller处理类(方法) ——HandlerMapping
l 步骤2—— 调用相应的Controller处理类(方法)完成业务逻辑 ——HandlerAdapter
l 步骤3—— 对Controller处理类(方法)调用时可能发生的异常进行处理 ——HandlerExceptionResolver
l 步骤4—— 根据Controller处理类(方法)的调用结果,进行Http响应处理 ——ViewResolver
使用SpringMVC框架好处:进行更简洁的Web层的开发;天生与Spring框架集成(如IoC容器、AOP等);提供强大的约定大于配置的契约式编程支持;容易与其他视图技术集成;对静态资源的支持;支持Restful风格等等。
SpringMVC 与 Struts2
这边并不会去过多得对两大框架进行对比,以免引发两方阵营得争论,只是简单介绍一下Struts2框架,并继续列举认可SpringMVC的理由。
什么是Struts2?
为什么是SpringMVC?
SpringMVC 关键部分
废话不多说了,也该讲一些实际一点的东西了。
一、前端控制器 -- DispatcherServlet
※所有J2EE项目都是从web.xml启动,阅读或构建一个J2EE项目,都应该先找web.xml开始。
※任何MVC框架都需要一个入口,SpringMVC的入口是在web.xml文件中的核心分发DispatcherServlet;
※DispatcherServlet是前端控制器设计模式的实现,提供Spring Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得Spring的所有好处。DispatcherServlet默认使用WebApplicationContext作为上下文,Spring默认配置文件为/WEB-INF/[servlet名字]-servlet.xml;
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:mvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
二、最简注解映射配置
笔者使用的是SpringMVC4.x,不用像SpringMVC3.0 时代,配置一大堆的HandlerMapping、HandlerAdapter、Converter。
对,没有错,你仅仅需要配置一句话:<mvc:annotation-driven/>
<mvc:annotation-driven/>相当于注册了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter两个bean,配置一些messageconverter。即解决了@Controller注解的使用前提配置。
三、静态资源最优处理
如果你的DispatcherServlet拦截 *.do这样的URL,就不存在访问不到静态资源的问题,但是要多书写.do。
如果你的DispatcherServlet拦截“/”,拦截了所有的请求,同时对*.js,*.jpg的访问也就被拦截了。
当然,想要restful风格的话,就必须采用后者,那么就动手来解决一下静态资源问题。
方案一: 在Spring3.0.4以后版本提供了mvc:resources
mvc:resources 的使用方法:
<mvc:resources location="/images/" mapping="/images/**"/> <mvc:resources location="/js/" mapping="/js/**"/> <mvc:resources location="/css/" mapping="/css/**"/>
说明:/images/**映射到 ResourceHttpRequestHandler进行处理,location指定静态资源的位置.可以是web application根目录下、jar包里面,这样可以把静态资源压缩到jar包中。cache-period 可以使得静态资源进行web cache
方案二 ,使用<mvc:default-servlet-handler/>
说明:<mvc:default-servlet-handler/> 会把"/**" url,注册到SimpleUrlHandlerMapping的urlMap中,把对静态资源的访问由HandlerMapping转到 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler 处理并返回。
DefaultServletHttpRequestHandler使用就是各个Servlet容器自己的默认Servlet。
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
<url-pattern>*.gif</url-pattern>
<url-pattern>*.png</url-pattern>
<url-pattern>*.js</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
说明:本人采用这种方式,Tomcat直接处理静态资源效率较高。缺点就是需要配置多个,每种文件配置一个,并且要写在DispatcherServlet的前面,让defaultServlet先拦截。
四、视图映射配置
这点没什么好说的,多种配置方式,直接上一种配置代码:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/project/" p:suffix=".jsp" />
五、文件上传解析器
SpringMVC实现多文件上传的方式有两种,一种是我们经常使用的以字节流的方式进行文件上传,另外一种是使用SpringMVC包装好的解析器进行上传,这两种方式对于实现多文件上传效率上却有着很大的差距,建议采用后者。
部分配置如下:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="10485760000"></property>
<property name="maxInMemorySize" value="40960"></property>
</bean>
说明:这边不是文件上传专栏,不详细介绍。
六、控制器扫描
这部分其实应该归纳在Spring部分,但是SpringMVC也是基于Bean去操作的,需要扫描一下控制器Bean。
配置代码如下:
<context:component-scan base-package="com.demo" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
说明:这样配置的意思是只扫描com.demo 包下@Controller 注解标注的类,use-default-filters属性配置为false 是必须的。
编后语
SpringMVC可以介绍的功能和内容无论从深度还是广度上,都远远不止本文提到的这些内容,这些只不过是最基础的部分。
SpringMVC为Web开发提供了相当得便捷,但在用的过程中还是要理解它的实现原理和思路,再往深一层来说,它毕竟只是框架,它适合做什么、能够做什么、怎么做,这些都应该由你自己做主,不能被框架左右。
后续的博文会书写Spring相关的一些技术点总结以及经验之谈,敬请关注。
“风萧萧兮易水寒 壮士一去兮不复还”
《经久不衰的Spring框架:SpringMVC 统括》的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- Docker 命令(二)
Docker 入门 启动docker systemctl start docker 帮助命令 docker --help docker [Commands] --help 例:docker run ...
- 6、手把手教你Extjs5(六)继承自定义一个控件
Extjs的开发都可以遵循OOP的原则,其对类的封装也很完善了.自定义一个控件最简单的办法就是继承一个已有的控件.根据上一节的需要,我做了一个Button的子类.首先根据目录结构,在app目录下建立一 ...
- MapReduce 简单的全文搜索
上一个已经实现了反向索引,那么为什么不尝试下全文搜索呢.例如有了 Hello file3.txt:1; MapReduce file3.txt:2;fil1.txt:1;fil2.tx ...
- Docker学习小计
1.自动下载并且创建容器 Now verify that the installation has worked by downloading the ubuntu image and launchi ...
- Scott用户的四张表:
Scott用户的四张表: 转载:http://www.cnblogs.com/mchina/archive/2012/09/06/2649951.html 在Oracle的学习之中,重点使用的是SQL ...
- Django performance
Reference: https://impythonist.wordpress.com/2016/02/21/building-high-performance-django-systems/ Th ...
- pandas 按照列A分组,将同一组的列B求和,生成新的Dataframe
对于pandas中的Dataframe,如果需要按照列A进行分组,将同一组的列B求和,可以通过下述操作完成: df = df.groupby(by=['column_A'])['column_B']. ...
- UVa 270 & POJ 1118 - Lining Up
题目大意:给一些点,找出一条直线使尽可能多的点在这条直线上,求这条直线上点的个数. 以每一个点为原点进行枚举,求其它点的斜率,斜率相同则说明在一条直线上.对斜率排序,找出斜率连续相等的最大长度. #i ...
- 12.TCP的成块数据流
1.滑动窗口协议 TCP滑动窗口的可视化表示 我们将字节从1到11进行标号,接收方通告的窗口称为提供的窗口,它覆盖了第4字节到第9字节的数据,且通告窗口大小为6.发 ...
- 史上最全的css hack(ie6-9,firefox,chrome,opera,safari)
<!DOCTYPE html> <html> <head> <title>Css Hack</title> <style> #t ...