SpringMVC架构设计

MVC是一种架构模式,它把业务的实现和展示相分离。

SpringMVC与struts2的区别

  1. Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上SpringMVC就容易实现restful url,而struts2的架构实现起来要费劲,因为Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。
  2. springmvc可以进行单例开发,并且建议使用单例开发,struts2通过类的成员变量接收参数,无法使用单例,只能使用多例。
  3. 由于Struts2需要针对每个request进行封装,把request,session等servlet生命周期的变量封装成一个一个Map,供给每个Action使用,并保证线程安全,所以在原则上,是比较耗费内存的。
  4. 拦截器实现机制上,Struts2有以自己的interceptor机制,SpringMVC用的是独立的AOP方式,这样导致Struts2的配置文件量还是比SpringMVC大。
  5. servlet和filter的区别了。
  6. SpringMVC集成了Ajax,使用非常方便,只需一个注解@ResponseBody就可以实现,然后直接返回响应文本即可,而Struts2拦截器集成了Ajax,在Action中处理时一般必须安装插件或者自己写代码集成进去,使用起来也相对不方便。
  7. SpringMVC验证支持JSR303,处理起来相对更加灵活方便,而Struts2验证比较繁琐,感觉太烦乱。
  8. spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高(当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少)。
  9. 设计思想上,Struts2更加符合OOP的编程思想, SpringMVC就比较谨慎,在servlet上扩展。
  10. SpringMVC开发效率和性能高于Struts2。
  11. SpringMVC可以认为已经100%零配置。

SpringAOP整合SpringMVC

spring容器不注册controller层组件,controller组件由springMVC容器单独注册。

// applicationContext.xml
<context:component-scan base-package="com.shuyun.channel">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController" />
<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
</context:component-scan> // springmvc-servlet.xml
<context:component-scan base-package="com.shuyun.channel" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController" />
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
</context:component-scan>

注意

关于<context:annotation-config /> <context:component-scan />:

component-scan会自动加上annotation-config功能,有了component-scan不用再写annotation-config了。参见spring官方reference

配置层次化Spring容器

参考 配置层次化Spring容器

我们知道,在开发基于spring的Web应用时,通常使用两个IoC容器,一个是由DispatchServlet初始化的WebApplicationContext,一个是由ContextLoaderListener初始化的ApplicationContext。对于Spring容器,Spring的官方参考手册详细地讲解了依赖注入的配置方式,对于容器本身的配置和多个容器之间的关系却不曾提及。于是,很多人以为在一个应用中只有一个全局的Spring容器,或者不了解MVC使用的WebApplicationContext和根ApplicationContext的关系。

通过查看Spring的源码和API,发现Spring可以配置为多个容器,容器之间可以配置为层级关系,一个根容器可以配置许多子容器,子容器还可以配置子容器,从而形成一个单根的层次化结构。对于该容器结构中的每个容器,在其中查找特定的bean时,会首先在本容器内查找,如果找到对应的bean,就返回该bean;如果没有找到,就会从直接父容器中去查找,依此类推,直到根容器为止。

从上面的示例中可以看到,从子容器中可以取得父容器中配置的bean,而父容器中不能够取得子容器中的bean。

在Spring MVC中WebApplicationContext配置为根ApplicationContext的子容器,所以,MVC使用的容器中能够取得根ApplicationContext中的bean。在一个web程序中可以配置多个DispatchSerlvet,每个Servlet对应一个容器,所有这些容器都作为根容器的子容器,这样,我们就可以把通用的bean放在根容器中,而针对特定DispatchServlet的bean,可以放在各自的子容器中。

文件上传

  • Controller的方法中需要接受一个Spring MVC提供的MultipartFile接口作为方法的参数,该参数接收前台表单type为file提交的对象,使用@RequestParam注解指明参数,那么Spring就会自动将表单传递过来的对象的类型转换为MultipartFile类型。

  • MultipartFile中提供了getName()、getSize()、getByte()

    getContentType()、isEmpty()、getInputStream()、getOriginalFilename()方法来访问文件。getOriginalFilename()方法是获取最初文件名,即本地文件名。

  • 在Controller方法中使用FileUtils下的copyInputStreamToFile(InputStream in,File file)方法来完成文件的拷贝.第一个参数是文件拷贝源的输入流,直接使用MultipartFile下的getInputStream()方法.第二个参数是文件将要保存的位置.

@RequestMapping("/doUpload")
public Result doUpload(@RequestParam("file") MultipartFile file) throws IOException {
if (!file.isEmpty()) {
FileUtils.copyInputStreamToFile(file.getInputStream(), new File("E://", file.getOriginalFilename()));
}
return ResultUtil.SUCCESS_RESULT;
}

Jackson

SpringMVC拦截器

拦截器好比你要去取经,那么,你就必须经过九九八十一关,主要用来解决请求的共性问题,如:乱码问题、权限验证问题等

实现SpringMVC拦截器的三个步骤

  1. 创建一个实现HandlerInterceptor接口,并实现接口的方法的类
  2. 将创建的拦截器注册到SpringMVC的配置文件中实现注册
    <mvc:interceptors>
    <bean class="路径下的类">
    </mvc:interceptors>
  3. 配置拦截器的拦截规则:
    <mvc:interceptors>
    <mvc:interceptor>
    <mvc:mapping path="拦截的action">
    <bean class="路径下的类">
    </mvc:interceptor>
    </mvc:interceptors>

拦截器中三个方法的介绍:

  1. preHandle()方法是否将当前请求拦截下来。(返回true请求继续运行,返回false请求终止(包括action层也会终止),Object arg代表被拦截的目标对象。)
  2. postHandle()方法的ModelAndView对象可以改变发往的视图或修改发往视图的信息。
  3. afterCompletion()方法表示视图显示之后在执行该方法。(一般用于资源的销毁)

拦截器和过滤器

共同:他们都是用来检查程序的共同场景,只不过拦截器是面向Action的,过滤器是面向整个web应用的。

  1. 解决权限验证问题
  2. 解决乱码问题

拦截器和过滤器的区别:

  1. 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
  2. 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  3. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  4. 拦截器可以访问action上下文、值栈 里的对象,而过滤器不能访问。
  5. 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
  6. 拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑

拦截器方法的作用顺序

拦截器的其它实现方式:

  1. 拦截器的类还可以通过实现WebRequestInterceptor(HandlerInterceptor)接口来编写。
  2. 向SpringMVC框架注册的写法不变。
  3. 弊端:preHandler方法没有返回值,不能终止请求。

Ps:建议使用功能更强大的实现方式,实现HandlerInterceptor接口。

Spring4增加功能

Spring4主要在Web服务方面有下面两个方面提升:

  1. 控制器使用@ResponseBody@RestController
  2. 异步调用。

Spring整合Struts2

Spring默认是单例,Struts2默认是多实例的。

如果是spring配置文件中的 bean的名字的话就是spring创建,那么单实例还是多实例就由spring的action Bean中的业务逻辑控制器类是否配置为scope=”prototype”,有就是多实例的,没有就是单实例的,顺序是先从spring中找,找不到再从struts配置文件中找。

  1. 对于无Spring插件(Struts2-spring-plugin-XXX.jar)的整合方式,需要在spring的action Bean中加业务逻辑控制器类配scope="prototype"。
    <bean id="user" class="modle.User" scope="prototype"/>
  2. 对于有Spring插件(Struts2-spring-plugin-XXX.jar)的整合方式:反编译StrutsSpringObjectFactory以及相关的代码才发现,如果在struts action的配置文件 <action name=".." class=".."/> 中class写的如果是完整的包名和类名的话就是struts创建action对象,也就是多实例的;

参考文档

  1. 史上最全最强SpringMVC详细示例实战教程
  2. Spring MVC快速入门
  3. Web MVC framework - Part VI. The Web
  4. Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable
  5. SpringMVC4.1之Controller层最佳实践

SpringMVC 知识整理的更多相关文章

  1. 二:SpringMVC知识整理

    springmvc复习: 1.SpringMVC介绍 2.SpringMVC入门程序 1)创建web工程 2)导入jar包 3)在web.xml中配置前端控制器(指定上下文件的路径 classpath ...

  2. js事件(Event)知识整理

    事件(Event)知识整理,本文由网上资料整理而来,需要的朋友可以参考下   鼠标事件 鼠标移动到目标元素上的那一刻,首先触发mouseover 之后如果光标继续在元素上移动,则不断触发mousemo ...

  3. Kali Linux渗透基础知识整理(四):维持访问

    Kali Linux渗透基础知识整理系列文章回顾 维持访问 在获得了目标系统的访问权之后,攻击者需要进一步维持这一访问权限.使用木马程序.后门程序和rootkit来达到这一目的.维持访问是一种艺术形式 ...

  4. Kali Linux渗透基础知识整理(二)漏洞扫描

    Kali Linux渗透基础知识整理系列文章回顾 漏洞扫描 网络流量 Nmap Hping3 Nessus whatweb DirBuster joomscan WPScan 网络流量 网络流量就是网 ...

  5. wifi基础知识整理

    转自 :http://blog.chinaunix.net/uid-9525959-id-3326047.html WIFI基本知识整理 这里对wifi的802.11协议中比较常见的知识做一个基本的总 ...

  6. 数据库知识整理<一>

    关系型数据库知识整理: 一,关系型数据库管理系统简介: 1.1使用数据库的原因: 降低存储数据的冗余度 提高数据的一致性 可以建立数据库所遵循的标准 储存数据可以共享 便于维护数据的完整性 能够实现数 ...

  7. 【转载】UML类图知识整理

    原文:UML类图知识整理 UML类图 UML,进阶必备专业技能,看不懂UML就会看不懂那些优秀的资料. 这里简单整理 类之间的关系 泛化关系(generalization) 泛化(generalize ...

  8. Linux进程管理知识整理

    Linux进程管理知识整理 1.进程有哪些状态?什么是进程的可中断等待状态?进程退出后为什么要等待调度器删除其task_struct结构?进程的退出状态有哪些? TASK_RUNNING(可运行状态) ...

  9. js事件(Event)知识整理[转]

    事件注册 平常我们绑定事件的时候用dom.onxxxx=function(){}的形式 这种方式是给元素的onxxxx属性赋值,只能绑定有一个处理句柄. 但很多时候我们需要绑定多个处理句柄到一个事件上 ...

随机推荐

  1. 个人整理方幂和公式(∑i^k 公式)

    有个Oier小学妹问了我一个Σi^k,i<=1e8 ,k<=1e6的问题,我认为这个用伯努利数列可能可以解决他的问题,所以整理了以下文章,给学弟学习学习~~~本人水平有限,也只能帮到这里了 ...

  2. poj 3294

    Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 12688   Accepted: 3552 Descr ...

  3. bzoj:1666: [Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏

    Description 奶牛们又在玩一种无聊的数字游戏.输得很郁闷的贝茜想请你写个程序来帮她在开局时预测结果.在游戏的开始,每头牛都会得到一个数N(1<=N<=1,000,000).此时奶 ...

  4. ubuntu下使用nginx搭建流媒体服务器,实现视频点播

    首先我们看如何实现视频点播,视频点播支持flv文件及H264编码视频,ACC编码音频的mp4文件: 第一步,创建单独的目录(因为软件较多,容易混乱),下载需要的软件: 我们需要下载nginx,pcre ...

  5. Nginx安装手册

    前提是搭建yum安装环境,见前面的教程资料 Nginx安装手册1 nginx安装环境 nginx是C语言开发,建议在linux上运行,本教程使用Centos6.5作为安装环境. gcc 安装ngin ...

  6. java 跳出多层循环

    lableB: for(int i=0;i<10;i++){ lableA: for(int j=0;j<10;j++){ System.out.println(j); if(j==1){ ...

  7. 为什么ios手机安装好fiddler证书/charles证书还是抓不到https请求?

    为什么ios手机安装好fiddler证书/charles证书还是抓不到https请求? 最近有不少人有此困惑, 因为你的ios系统应该是10.0以上的系统, 在手机系统设置---关于手机----证书信 ...

  8. 关于atom

    以前老听别人说atom这款编辑器如何如何的好用,今天特地试了下,结果一不小心将顶部的工具栏给隐藏了,弄了半天都没弄出来.后来就在网上到处寻找帮助,试试这个试试那个,终于弄好了,其实是这样的. 首先在任 ...

  9. C#采用rabbitMQ搭建分布式日志系统

    网上对于java有很多开源的组件可以搭建分布式日志系统,我参考一些组件自己开发一套简单的分布式日志系 全部使用采用.NET进行开发,所用技术:MVC.EF.RabbitMq.MySql.Autofac ...

  10. 宝塔linux面板.txt

    安装命令: yum -y install screen wget && screen -S bt wget -O install.sh http://103.224.251.79:58 ...