Struts1、Struts2、SpringMVC比较

2024-06-14 07:08

本文主要是介绍Struts1、Struts2、SpringMVC比较,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


-----------------------------本文转载自 http://blog.csdn.net/liu765023051/article/details/40376343---------------------------------

前段框架用了不少,今天就来做个总结。网上关于Struts1、Struts2、SpringMVC的文章有很多,这里的内容就是基于它们,来做个比较。

这三个框架是按照上面的顺序,依次出现的,它们都是对MVC模式的实现。为什么会出现这三个、甚至更多的MVC框架呢?他们都是为了将URL世界映射到Java世界。尽管它们它们内部的实现思路不同,有着各自的优缺点,但是它们都做到了个自己的使用目的。



历史介绍

大多Web应用程序,都是运行在HTTP上的。HTTP协议是一系列无状态的文本传输协议。无状态的协议不记录收到的多个请求之间的关系,也就是说服务器与相应客户端如何对应起来,是一个问题。此外,HTTP是基于文本的。如何将基于文本的技术与强类型的Java匹配起来,这需要大量的数据绑定工作。


HTTP协议原本就不是为了满足Web应用程序开发人员的需求而设计的,它们是为请求和处理静态HTML文档而设计的。

Java Servlet API能够解决这些问题,Servlet通过一套面向对象的抽象直接封装客户/服务器交互的细节。我们不用自己解析HTTP请求,而是处理一个包装好的Java对象。

ava程序员可以根据HTTP客户/服务器通信以直观的面向对象的抽象方式,编写HTTP服务器代码。Servlet API的核心对象是Servlet、请求和相应。Servlet是一个单例的Java对象。

但是使用Servlet编程,就需要我们大量的“重复创新的轮子”。比如请求参数到Java类型的数据绑定、数据验证、界面渲染等,都需要手动编写。

这三个框架,就基于此,做了封装,简化开发。下面我们就来看看它们的区别。


struts1


现在Strut1使用的越来越少了,不过还是有一些老项目在使用struts1,由于我也使用过该框架,也拿它来做个比较:



1、服务器启动,Web应用启动时就会加载web.xml初始化actionServlet和记载struts配置文件(struts-config.xml),读配置信息到内存中,供以后action调用

2、用户通过客户端向服务器发出一个请求,http://localhost:8080/struts_login/login.do 

3、tomcat会创建出HttpRequest和HttpResponse实例,并根据用户的Method请求方式,调用中央控制器的doGet或者doPost方法;

我们已经在web.xml配置了所有符合某特定格式的请求都将由struts指定的Servlet来处理。比如:只要是以.do结尾的请求(*.do)都由 org.apache.struts.action.ActionServlet来对其进行处理.ActionServlet会拿到用户的请求,并且去分析这个URL,ActionServlet中央控制器会截下 /login. 截下来之后,它是为了去struts-config.xml这个配置文件里面找<action>标签path属性的值等于所截部分的那个 Action,将Action标签里面的信息放在ActionMapping里面。

4、根据ActionMapping中的name名称查找ActionForm,如果配置了ActionForm,那么就到request或session中查找,如果在request或session中存在已经创建的ActionForm,那么将返回;如果不存在,那么会根据ActionForm的完成路径采用反射进行创建,再将创建好的ActionForm放到reqeust或session中

5、首先执行ActionForm中的reset方法进行重置,然后得到表单中所有输入域的name名称,再调用request.getParameterValues(),根据name名称得到相应的值,最后将表单中的数据全部放到一个map中,map中的key为表单输入域的名称,map的value位表单输入域的值(字符串数组),接下来调用一个第三方组件BeanUtils,将Map中的值,根据ActionForm中的setter方法设置到ActionForm上。

6、根据Action的完成类名称到Map中查找,如果存在就在返回Action对象,否则根据Action类的完整名称采用反射去创建,再将创建好的Action放到Map中。所以struts1的Action是单实例的,存在线程安全问题。

找到对应的action之后,ActionServlet会把表单提交的数据给存放(生成对应调用 set/get方法)到struts-config中相应的action标签的name属性值指定的actionform类中(若有, [actionform的子类,并且在form-bean标签中配置了,若要进行数据验证可以在actionform中覆盖validate方法,推荐使用js,减轻服务器负担]).同时把actionform和当前HttpServletrequest 对象注入到代调用的action方法中.

7、执行用户自定义的Action中的Execute方法,将ActionMapping,ActionForm,request,response传递过去,将ActionForward返回给ActionServlet。

8、根据返回的ActionForward完成转向,ActionForward对象根据此action配置的<forward>匹配name进而调转到对应path的jsp页面上。


struts2

是基于Filter拦截实现的,实现图如下:



访问过程如下:

1、Tomcat服务器启动,Web应用启动时,首先会加载web.xml文件,然后初始化Filter过滤器,初始化org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter监听程序。这时,会把Struts2的配置文件读到内存里面(如果是Struts2与Spring集成,会是Listner先启动,Spring完成Struts2的acion的创建,不耽误Struts2文件的初始化)供以后Action调用;

2、用户访问浏览器,发送请求,指向Servlet容器。

3、容器tomcat会创建出HttpRequest和HttpResponse实例;并通过web.xml文件映射请求,截取并获取控制器的名称。

4、然后容器调用StrutsPrePareAndExecutionFilter,StrutsPrepareAndExecuteFilter通过ActionMapper来决定获取Action的信息

5、如果ActionMapper决定需要调用某个Action,StrutsPrepareAndExecuteFilter把请求的处理交给Action的代理ActionProxy;

6、控制器调用ActionProxy

7、ActionProxy通过ConfigurationManager读取strut.xml配置文件来获取action和interceptor的信息,找到需要调用的Action类;

8、ActionProxy把request请求传递给ActionInvocation对象;

9、ActionInvocation实例使用命令模式来调用,依次调用action和interceptor;

10、根据action的配置信息,产生result,result信息返回给actionInvocation。

11、返回结果给客户端。


特点:

1、线程模式,每一次请求都会产生一个新的实例处理请求,多线程环境下没有数据同步问题;

2、引入数据的依赖注入【页面表单数据注入到Action的注入、实例对象的注入,通过set方法注入】

3、基于AOP的拦截器,可以在每次请求前后灵活控制;

4、配置文件支持表单式,基于约定大于配置,简化配置;

5、内置以插件形式支持ajax如dojo,支持多种末班展示jsp、freemarker,veiocity等。


SpringMVC

SpringMVC是基于Servlet拦截实现的,主要由前端控制器(DispatcherServlet)、映射处理器(HandlerMapping)、适配器(HandlerAdapter)、拦截器(HandlerInterceptor)、控制器(Controller)、视图解析器(ViewResolver)、视图(View)这几部分构成。下面看SpringMVC的工作流程。



1、Tomcat服务器启动,Web应用启动时,首先会加载web.xml文件,然后启动Listenr监听,初始化ContextLoaderListenr监听程序。这时,会加载Spring的一些配置,初始化Spring的配置到ApplicationContext中;

2、然后再初始化Servlet,初始化DispatcherServlet。这时会完成ServletContext的初始化,同时完成ServletContext中的WebApplicationContext的初始化,读去配置信息到内存中;

3、用户通过浏览器访问,发送请求。Tomcat容器根据请求,会创建出HttpRequest和HttpResponse实例,并根据用户的Method请求方式,调用中央控制器的doGet或者doPost方法

我们已经在web.xml配置了所有符合某特定格式的请求都将由SpringMVC指定的Servlet来处理。比如:只要是以.do结尾的请求(*.do)都由 org.springframework.web.servlet.DispatcherServlet来对其进行处理。SpringMVC的入口,也是核心所在。


4、DispatcherServlet,对请求的URL进行解析,得到请求资源标识符(URI)。然后根据URI,调用HandlerMapping获取该Handler配置的相关对象(包括Handler对象以及Handler对象对应的拦截器),然后以HandlerExccutionChain对象的形式返回;

HandlerMapping有以下两个实现:

a、SimpleUrlHandlerMapping,通过配置文件,把一个URL映射到Controller上

b、DefaultAnnotationHandlerMapping通过注解,把一个URL映射到Controller上


3、DispatcherServlet根据获得的Handler,选择一个合适的HandlerAdapter。(如果成功获得HandlerAdapter,则开始执行拦截器preHandler方法);

4、提取Request中的模型数据,填充Handler入参,开始执行Handler,即Controller,在填充Handler的过程中,根据你的配置,Spring将做一些工作:

HttpMessageConveter:将请求消息(如Json、XML)转换成一个对象,将对象转换为指定的相应信息;

数据转换:对请求消息进行数据转换。如Spring转换成Integer、Double等

数据格式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期

数据验证:验证数据的有效性(长度、格式等),验收结果存储到BindingResult或Error中


5、Controller进行业务业务调用后,向DispatcherServlet,会返回一个ModelAndView对象;

6、DispatcherServlet根据返回的ModelAndView,查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的试图对象;

7、将渲染结果返回给客户端。


特点:

线程模式:单例模式,效率好;

基于方法级别的拦截,而不是基于类。更细粒度的灵活控制;

通过注解简化了多配置,但同时在代码中增加了很多和业务不相干的代码。


比较

尽管旧版本的Struts2出现了安全了漏洞,但是Struts2,和SpringMVC仍然是非常流行的MVC框架,而Strut1尽管效率最高,但现在使用的越来越少。所以,我们来看看它们的异同。


这三个框架中,Struts1的效率仅次于JSP,三者当中效率最高。但是Struts1内部是面向抽象类编程,而不是面向接口编程的。Struts2提供了一个名为ActionSupport的基类,虽然不是必须的,但是要想使用Struts2的功能,基本上都会继承它。SpringMVC是面向接口编程,需要实现一个接口(配置文件时)。


Struts1的入口点是Servlet,Struts2的入口点是Filter,SpringMVC入口点是Servlet;


Struts2是类级别的拦截,每个请求创建一个action,然后通过调用setter方法把Request中的数据注入;SpringMVC是基于方法的拦截,一个方法对应一个Request上下文,而方法同时又跟一个URL对应;


Struts2的类属性被所有方法共享,这就无法用注解标识其所属方法了,方法之间独立,但是所有Action变量是共享的。SpringMVC的方法之间基本独立,共享Request数据,请求数据通过参数获取,处理结果通过ModelMap交回给框架,方法之间不共享变量。


interceptor实现机制:struts2有自己的拦截器机制,SpringMVC用的是独立的AOP方式。所以,尽管Spring的配置能够继承,但是配置量仍大于SpringMVC;


SpringMVC的配置是基于IOC容器的,一方面方便SpringMVC进行扩展和增强,另一方面有利于与Spring整合;而Struts2与Spring的整合,需要Spring提供了第三方包。


Struts2里面可以没有HttpServletRequest和HttpServletResponse,只有getter、setter或ActionContext里的数据,这样就会使Action比较独立。整个web与Action无关,这个action可以在任何环境下独立运行,也就是说,它可以最大限度的被重用。而SpringMVC不像Struts2那样隐藏了HttpServletRequest和HttpServletResponse,而是将它们做为了形参传入控制器的方法中。


Struts1的Action与SpringMVC的Controller一样,都是单例的,不是线程安全的。这就意味着,每个Request请求,系统都会用原有的instance去处理。这虽然减少了对象的创建和垃圾收集的时间,但是处理多线程调用时,Controller不是线程安全的;而Struts2是线程安全的。


这篇关于Struts1、Struts2、SpringMVC比较的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1059709

相关文章

springboot集成Lucene的详细指南

《springboot集成Lucene的详细指南》这篇文章主要为大家详细介绍了springboot集成Lucene的详细指南,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起... 目录添加依赖创建配置类创建实体类创建索引服务类创建搜索服务类创建控制器类使用示例以下是 Spring

Java调用Python的四种方法小结

《Java调用Python的四种方法小结》在现代开发中,结合不同编程语言的优势往往能达到事半功倍的效果,本文将详细介绍四种在Java中调用Python的方法,并推荐一种最常用且实用的方法,希望对大家有... 目录一、在Java类中直接执行python语句二、在Java中直接调用Python脚本三、使用Run

Java根据IP地址实现归属地获取

《Java根据IP地址实现归属地获取》Ip2region是一个离线IP地址定位库和IP定位数据管理框架,这篇文章主要为大家详细介绍了Java如何使用Ip2region实现根据IP地址获取归属地,感兴趣... 目录一、使用Ip2region离线获取1、Ip2region简介2、导包3、下编程载xdb文件4、J

浅析如何使用xstream实现javaBean与xml互转

《浅析如何使用xstream实现javaBean与xml互转》XStream是一个用于将Java对象与XML之间进行转换的库,它非常简单易用,下面将详细介绍如何使用XStream实现JavaBean与... 目录1. 引入依赖2. 定义 JavaBean3. JavaBean 转 XML4. XML 转 J

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St