这篇文章给大家介绍 springMVC 原理中 servlet 与 filter 区别是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
最近做项目用到了 struts2,之前一直是用 struts1 和 springMVC。感觉到了 struts2 从很大程度上和这两个还是有很大区别的,所以今天搜集了些资料,给他们做一下对比。
Struts1 官方已经停止更新,现在用的也比较少,这里主要讲一下 struts2 和 struts1 比较都有哪些不同和进步。Struts2 可以说不是完全从 struts1 改进来的,因为 struts2 原本就是举世闻名的 Webwork2,在经历几年的发展之后,struts 和 WebWork 社区决定合二为一,也就是今天的 struts2.
Struts2 与 struts1 比较的新特性:
Action 类:
• Struts1 要求 Action 类继承一个抽象基类。Struts1 的一个普遍问题是使用抽象类编程而不是接口。
• Struts 2 Action 类可以实现一个 Action 接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2 提供一个 ActionSupport 基类去实现常用的接口。Action 接口不是必须的,任何有 execute 标识的 POJO 对象都可以用作 Struts2 的 Action 对象。
线程模式:
• Struts1 Action 是单例模式并且必须是线程安全的,因为仅有 Action 的一个实例来处理所有的请求。单例策略限制了 Struts1 Action 能作的事,并且要在开发时特别小心。Action 资源必须是线程安全的或同步的。
• Struts2 Action 对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet 容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)
Servlet 依赖:
• Struts1 Action 依赖于 ServletAPI , 因为当一个 Action 被调用时 HttpServletRequest 和 HttpServletResponse 被传递给 execute 方法。
• Struts 2 Action 不依赖于容器,允许 Action 脱离容器单独被测试。如果需要,Struts2 Action 仍然可以访问初始的 request 和 response。但是,其他的元素减少或者消除了直接访问 HttpServetRequest 和 HttpServletResponse 的必要性。
可测性:
• 测试 Struts1Action 的一个主要问题是 execute 方法暴露了 servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套 Struts1 的模拟对象(来进行测试)。
• Struts 2 Action 可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。
捕获输入:
• Struts1 使用 ActionForm 对象捕获输入。所有的 ActionForm 必须继承一个基类。因为其他 JavaBean 不能用作 ActionForm,开发者经常创建多余的类捕获输入。动态 Bean(DynaBeans)可以作为创建传统 ActionForm 的选择,但是,开发者可能是在重新描述 (创建) 已经存在的 JavaBean(仍然会导致有冗余的 javabean)。
• Struts 2 直接使用 Action 属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己 (子) 属性的 rich 对象类型。Action 属性能够通过 web 页面上的 taglibs 访问。Struts2 也支持 ActionForm 模式。rich 对象类型,包括业务对象,能够用作输入 / 输出对象。这种 ModelDriven 特性简化了 taglib 对 POJO 输入对象的引用。
表达式语言:
• Struts1 整合了 JSTL,因此使用 JSTL EL。这种 EL 有基本对象图遍历,但是对集合和索引属性的支持很弱。
• Struts2 可以使用 JSTL,但是也支持一个更强大和灵活的表达式语言-- Object Graph Notation Language (OGNL).
绑定值到页面(view):
• Struts 1 使用标准 JSP 机制把对象绑定到页面中来访问。
• Struts 2 使用 ValueStack 技术,使 taglib 能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack 策略允许通过一系列名称相同但类型不同的属性重用页面(view)。
类型转换:
• Struts 1 ActionForm 属性通常都是 String 类型。Struts1 使用 Commons-Beanutils 进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。
• Struts2 使用 OGNL 进行类型转换。提供基本和常用对象的转换器。
校验:
• Struts 1 支持在 ActionForm 的 validate 方法中手动校验,或者通过 Commons Validator 的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。
• Struts2 支持通过 validate 方法和 XWork 校验框架来进行校验。XWork 校验框架使用为属性类类型定义的校验和内容校验,来支持 chain 校验子属性
Action 执行的控制:
• Struts1 支持每一个模块有单独的 Request Processors(生命周期),但是模块中的所有 Action 必须共享相同的生命周期。
• Struts2 支持通过拦截器堆栈(Interceptor Stacks)为每一个 Action 创建不同的生命周期。堆栈能够根据需要和不同的 Action 一起使用。
SpringMVC 与 Struts2 的比较:
机制:
spring mvc 的入口是 servlet,而 struts2 是 filter(这里要指出,filter 和 servlet 是不同的。以前认为 filter 是 servlet 的一种特殊),这样就导致了二者的机制不同,这里就牵涉到 servlet 和 filter 的区别了。
性能:
spring 会稍微比 struts 快。spring mvc 是基于方法的设计,而 sturts 是基于类,每次发一次请求都会实例一个 action,每个 action 都会被注入属性,而 spring 基于方法,粒度更细,但要小心把握像在 servlet 控制数据一样。spring3 mvc 是方法级别的拦截,拦截到方法后根据参数上的注解,把 request 数据注入进去,在 spring3 mvc 中,一个方法对应一个 request 上下文。而 struts2 框架是类级别的拦截,每次来了请求就创建一个 Action,然后调用 setter getter 方法把 request 中的数据注入;struts2 实际上是通过 setter getter 方法与 request 打交道的;struts2 中,一个 Action 对象对应一个 request 上下文。
参数传递:
struts 是在接受参数的时候,可以用属性来接受参数,这就说明参数是让多个方法共享的。
设计思想上:
struts 更加符合 oop 的编程思想,spring 就比较谨慎,在 servlet 上扩展。
intercepter 的实现机制:
有以自己的 interceptor 机制,spring mvc 用的是独立的 AOP 方式。这样导致 struts 的配置文件量还是比 spring mvc 大,虽然 struts 的配置能继承,所以我觉得论使用上来讲,spring mvc 使用更加简洁,开发效率 Spring MVC 确实比 struts2 高。spring mvc 是方法级别的拦截,一个方法对应一个 request 上下文,而方法同时又跟一个 url 对应,所以说从架构本身上 spring3 mvc 就容易实现 restful url。struts2 是类级别的拦截,一个类对应一个 request 上下文;实现 restful url 要费劲,因为 struts2 action 的一个方法可以对应一个 url;而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。spring3mvc 的方法之间基本上独立的,独享 request response 数据,请求数据通过参数获取,处理结果通过 ModelMap 交回给框架方法之间不共享变量,而 struts2 搞的就比较乱,虽然方法之间也是独立的,但其所有 Action 变量是共享的,这不会影响程序运行,却给我们编码,读程序时带来麻烦。
总结:
Strut1 目前已经很少再用,个人感觉 springMVC 在易用性上要优于 struts2.struts2 和 springMVC 在性能方面是不分伯仲,每个阵营都有自己的测试数据,很难说哪一个更优秀。以上资料部分摘自网络,尊重原作者版权,分享给更多的读者。
附:servlet 与 filter 区别:
一、概念:
1、servlet:servlet 是一种运行服务器端的 java 应用程序,具有独立于平台和协议的特性,并且可以动态的生成 web 页面,它工作在客户端请求与服务器响应的中间层。
2、filter:filter 是一个可以复用的代码片段,可以用来转换 HTTP 请求、响应和头信息。Filter 不像 Servlet,它不能产生一个请求或者响应,它只是修改对某一资源的请求,或者修改从某一的响应。
二、生命周期:
1、servlet:servlet 的生命周期始于它被装入 web 服务器的内存时,并在 web 服务器终止或重新装入 servlet 时结束。servlet 一旦被装入 web 服务器,一般不会从 web 服务器内存中删除,直至 web 服务器关闭或重新结束。
(1)、装入:启动服务器时加载 Servlet 的实例;
(2)、初始化:web 服务器启动时或 web 服务器接收到请求时,或者两者之间的某个时刻启动。初始化工作有 init()方法负责执行完成;
(3)、调用:从第一次到以后的多次访问,都是只调用 doGet()或 doPost()方法;
(4)、销毁:停止服务器时调用 destroy()方法,销毁实例。
2、filter:(一定要实现 javax.servlet 包的 Filter 接口的三个方法 init()、doFilter()、destroy(),空实现也行)
(1)、启动服务器时加载过滤器的实例,并调用 init()方法来初始化实例;
(2)、每一次请求时都只调用方法 doFilter()进行处理;
(3)、停止服务器时调用 destroy()方法,销毁实例。
三、职责
1、servlet:
创建并返回一个包含基于客户请求性质的动态内容的完整的 html 页面;
创建可嵌入到现有的 html 页面中的一部分 html 页面(html 片段);
读取客户端发来的隐藏数据;
读取客户端发来的显示数据;
与其他服务器资源(包括数据库和 java 的应用程序)进行通信;
通过状态代码和响应头向客户端发送隐藏数据。
2、filter:
filter 能够在一个请求到达 servlet 之前预处理用户请求,也可以在离开 servlet 时处理 http 响应:
在执行 servlet 之前,首先执行 filter 程序,并为之做一些预处理工作;
根据程序需要修改请求和响应;
在 servlet 被调用之后截获 servlet 的执行
四、区别:
1,servlet 流程是短的,url 传来之后,就对其进行处理,之后返回或转向到某一自己指定的页面。它主要用来在 业务处理之前进行控制.
2,filter 流程是线性的,url 传来之后,检查之后,可保持原来的流程继续向下执行,被下一个 filter, servlet 接收等,而 servlet 处理之后,不会继续向下传递。filter 功能可用来保持流程继续按照原来的方式进行下去,或者主导流程,而 servlet 的功能主要用来主导流程。
filter 可用来进行字符编码的过滤,检测用户是否登陆的过滤,禁止页面缓存等。
关于 springMVC 原理中 servlet 与 filter 区别是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。