传统的Java
Web应用程序是采用JSP+Servlet+Javabean来实现的,这种模式实现了最基本的MVC分层,使的程序结构分为几层,有负责前台展示的
JSP、负责流程逻辑控制的Servlet以及负责数据封装的Javabean。但是这种结构仍然存在问题:如JSP页面中需要使用符号嵌入很多的
Java代码,造成页面结构混乱,Servlet和Javabean负责了大量的跳转和运算工作,耦合紧密,程序复用度低等等,SSH框架应运而生…
————————————————
1.什么是SSH框架
官方的说法:SSH是 struts+spring+hibernate的一个集成框架,是目前较流行的一种web应用程序开源框架。SSH不是一个框架,而是把多个框架(Struts、Spring以及Hibernate)紧密的结合在一起,用于构建灵活、易于扩展的多层Web应用程序。
Java EE架构大致分为以下几个层次:
1.实体层(POJO层)
2.数据访问层(DAO层)
3.业务逻辑层(Service层)
4.控制器层(Controller层)
5.表现层(View层)
其中SSH框架的系统从职能上分大致可以分为四层:表示层、业务逻辑层、数据持久层和域模块层(实体层)。
由SSH构建系统的基本业务流程是:
1、在表示层中,首先通过JSP页面实现交互界面,负责传送请求(Request)和接收响应(Response),然后Struts根据配置文件(struts-config.xml)将ActionServlet接收到的Request委派给相应的Action处理。
2、在业务层中,管理服务组件的Spring IoC容器负责向Action提供业务模型(Model)组件和该组件的协作对象数据处理(DAO)组件完成业务逻辑,并提供事务处理、缓冲池等容器组件以提升系统性能和保证数据的完整性。
3、在持久层中,则依赖于Hibernate的对象化映射和数据库交互,处理DAO组件请求的数据,并返回处理结果。
采用上述开发模型,不仅实现了视图、控制器与模型的彻底分离,而且还实现了业务逻辑层与持久层的分离。这样无论前端如何变化,模型层只需很少的改动,并且数据库的变化也不会对前端有所影响,大大提高了系统的可复用性。而且由于不同层之间耦合度小,有利于团队成员并行工作,大大提高了开发效率。
————————————————
2.struts总结
2.1 什么是struts
从简单性来看,Struts是这三个框架中最简单的一个,它是基于MVC的框架。它通过采用JavaServlet/JSP技术,实现了基于Java EEWeb应用的MVC设计模式的应用框架,是MVC的一个具体实现或着说是MVC的一个具体产品。
2.2 Struts的核心构成
Struts的核心同样也是MVC的核心,Struts是MVC的一个具体产品。
(1)Model
由Action、ActionForm以及JavaBean组成,其中ActionForm用于将用户请求的参数,封装成为ActionForm对象,我们可以理解为实体,由ActionServlet转发给Action,Action处理用户请求,将处理结果返回到界面。
(2)View
该部分采用JSP+大量的taglib,实现页面的渲染。
(3)Controller
Controller是Struts的核心控制器,负责拦截用户请求,通过调用Model来实现处理用户请求的功能。
2.3为什么要用struts
首先,Struts 是MVC的一种实现,它将 Servlet和 JSP 标记(属于 J2EE 规范)用作实现的一部分。Struts继承了MVC的各项特性,并根据J2EE的特点,做了相应的变化与扩展,减弱了业务逻辑接口和数据接口之间的耦合,以及让视图层更富于变化。
另外, struts具有页面导航功能,使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。
**2.3.1 structs1
**
想要理解strusts1,我是先通过strusts1的运行原理图来理解的,然后,我们根据原理图来讲解structs1原理。
用户在视图层输入数据。
第一步:structs框架总控制器,初始化,开始读取strusts-config.xml文件。
struts框架的总控制器ActionServlet是一个Servlet,它在web.xml中配置成自动启动的Servlet,在启动时总控制器会读取配置文件(struts-config.xml)的配置信息,为struts中不同的模块初始化相应的对象。(面向对象思想)
第二步:视图层向总控制器发送Http请求
用户提交表单或者通过URL向WEB服务器提交请求,请求的数据用HTTP协议传给web服务器
第三步: Form填充
struts的总控制器ActionServlet在用户提交请求时将数据放到对应的form对象中的成员变量中。
第四步:派发请求
控制器根据配置信息,对象ActionConfig将请求派发到具体的Action,对应的formBean一并传给这个Action中的excute()方法。
第五步:处理业务
Action一般只包含一个excute()方法,它负责执行相应的业务逻辑(调用其它的业务模块)完毕后返回一个ActionForward对象。服务器通过ActionForward对象进行转发工作。
第六步:返回响应
Action将业务处理的不同结果返回一个目标响应对象给总控制器。
第七步:查找响应
总控制器根据Action处理业务返回的目标响应对象,找到对应的资源对象,一般情况下为jsp页面。
第八步:响应用户
目标响应对象将结果传递给资源对象,将结果展现给用户。
structs1的优缺点
1.优点:
①开源的框架,结构清晰
②是MVC的经典实现(MVC是一种思想,而不是一种技术)
③处理异常机制,实现国际化
④具有强大的标签库
⑤解决了JSP页面存在大量的JAVA代码,维护起来方便
⑥在formBean中会自动提交,不会去使用传统的get、set方法得到值、取值
2.缺点:
①配置复杂
②测试不方便
③依赖web容器
④action是一个单例模式,必须设置为线程安全
2.3.2 structs2
structs2原理图
第一步:客户端初始化一个指向Servlet容器(例如Tomcat)的请求
第二步:这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
第三步:接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
第四步:如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
第五步:ActionProxy通过Configuration Manager询问框架的配置文件,找到需要调用的Action类
第六步:ActionProxy创建一个ActionInvocation的实例。
第七步:ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
第八步:一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
注意:在上述过程中所有的对象(Action,Results,Interceptors,等)都是通过ObjectFactory来创建的
structs2的优缺点:
优点:
大量的拦截器:
Struts2本身提供了大量的可重用的拦截器,比如类型转换拦截器,很多时候我们从页面取得参数,这个时候它是String类型的,我们需要手动。
基于插件的框架:
Struts2是一个基于插件的框架,社区中提供了很多实用的插件,比如jfreechat/json等等,使用这些插件可以简化我们的开发,加快开发进度。
struts2最大的缺点莫过于在好多web服务器上支持不好,例如在websphere5.5,weblogic8.1及以前版本支持非常查,需要用最新的。
多种视图的支持:
多种视图的支持:jsp,freemarker,Veloctiy,只要你愿意,你甚至可以通过轻松的改造让它支持pdf,同一个项目中你可以支持多种视图。
更加的模块化:
与Struts1.X 相比,Struts2更加的模块化,可以轻松将配置信息按功能界限拆分成多个文件,便于管理和团队协作开发。
与Spring的集成:
与Struts1.x相比,Struts2不必再自己编写singleton,进一步的降低了程序间的耦合性,就Struts2内部本身而言,降低了框架本身的偶合性。
基于pojo易于测试:
在Struts1.x中我需要Mock出这两个Http对象,使我们很难编写Action的单元测试,与Struts1.x相比,Struts2的Action 不再依赖于HttpServletRequest和HttpServletResponse对象,使我们能够更方便的针对Action编写单元测试。
缺点:
Struts2中Action中取得从jsp中传过来的参数时还是有点麻烦。
可以为Struts2的Action中的属性配置上Getter和Setter方法,通过默认拦截器,就可以将请求参数设置到这些属性中。如果用这种方式,当请求参数很多时,Action类就会被这些表单属性弄的很臃肿,让人感觉会很乱。还有Action中的属性不但可以用来获得请求参数还可以输出到Jsp中,这样就会更乱。假设从JSP1中获得了参数money=100000,但是这个Action还要输出到JSP2中,但是输出的格式却不同,money=100,000,这样这个Action中的money中的值就变了。
校验还是感觉比较繁琐,感觉太烦乱,也太细化了。
如果校验出错的只能给用户提示一些信息。如果有多个字段,每个字段出错时返回到不同的画面,这个功能在Strut2框架下借助框架提供的校验逻辑就不容易实现。
安全性有待提高。
Struts2曝出2个高危安全漏洞,一个是使用缩写的导航参数前缀时的远程代码执行漏洞,另一个是使用缩写的重定向参数前缀时的开放式重定向漏洞。这些漏洞可使黑客取得网站服务器的“最高权限”,从而使企业服务器变成黑客手中的“肉鸡”。
3.Hibernate总结
Hibernate是一种Java语言下的ORM(Object-Relation
Mapping)的解决方案的一种框架,实现了数据持久化功能。Hibernate能将对象模型所表示的JOPO实体映射到基于SQL的关系模型结构中,对JDBC进行了最大限度地对象封装,使得程序员可以通过面向对象地编程思维来操作数据库。
其实在Struts2里面也是用到了很多映射的思想,比如:execute()方法,这个以后再例子中大家能很好地体会到,这里就不详谈。
Hibernate的核心构成
会话工厂(SessionFactory)
配置对象被用于创造一个SessionFactory对象,使用提供的配置文件为应用程序依次配置Hibernate,并允许实例化一个会话对象。SessionFactory是一个线程安全对象并由应用程序所有的线程所使用。
SessionFactory是一个重量级对象所以通常它都是在应用程序启动时创造然后留存为以后使用。每个数据库需要一个SessionFactory对象使用一个单独的配置文件。所以如果你使用多种数据库那么你要创造多种SessionFactory对象。
会话(Session)
一个会话被用于与数据库的物理连接。Session对象是轻量级的,并被设计为每次实例化都需要与数据库的交互。持久对象通过 Session对象保存和检索。
Session 对象不应该长时间保持开启状态因为它们通常情况下并非线程安全,并且它们应该按照所需创造和销毁。
事务(Transaction)
事务对象指定工作的原子单位,它是一个可选项.org.hibernate.Transaction接口提供事务管理的方法。
Query 对象
Query对象使用SQL或者Hibernate查询语言(HQL)字符串在数据库中来检索数据并创造对象。一个查询的实例被用于连结查询参数,限制由查询返回的结果数量,并最终执行查询。
Criteria 对象
Criteria对象被用于创造和执行面向规则查询的对象来检索对象。
Configuration 对象
配置对象是你在任何Hibernate应用程序中创造的第一个Hibernate对象,并且经常只在应用程序初始化期间创造。它代表了Hibernate所需一个配置或属性文件,配置对象提供了两种基础组件。
数据库连接:由Hibernate支持的一个或多个配置文件处理。这些文件是hibernate.properties和hibernate.cfg.xml。
类映射设置:这个组件创造了 Java类和数据库表格之间的联系。
1.hibernate的工作原理
第一步:Configuration.config() 来读取xml配置文件
第二步:Configuration.config()来读取配置文件里面的映射信息
第三步:创建会话工厂
第四步:打开会话
第五步:开启事务
第六步:持久化到数据库
第七步:关闭会话
第八步:关闭会话工厂
2.hibernate优缺点
优点:
1.hibernate是基于ORMapping技术的开源的框架,对JDBC进行了轻量级的封装,使用面向对象的思维来操纵数据库。
2.hibernate提供了session缓存和二级缓存,对于不需要进行复杂查询的系统,性能有提升。
3.低侵入式设计
缺点:
1.hibernate不容易上手,学习成本太高
2.hibernate由于不直接对底层数据库进行操作,所以不适合复杂的查询(统计)
3.不适合大量的聚集操作(存储过程)
4.Spring总结
Spring是J2EE应用程序框架,是轻量级的IOC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框架,Hibernate框架等组合使用。
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式。
IOC 控制反转
对象创建责任的反转,在spring中BeanFacotory是IoC容器的核心接口,负责实例化,定位,配置应用程序中的对象及建立这些对象间的依赖。
XmlBeanFacotory实现BeanFactory接口,通过获取xml配置文件数据,组成应用对象及对象间的依赖关系。
spring中有三种注入方式,一种是set注入,一种是接口注入,另一种是构造方法注入。
AOP 面向切面编程
面向方面的编程,即AOP,是一种编程技术,它允许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOP
的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。
4.1 为什么使用Spring
没有Spring,Struts和Hibernate可以很好的运行,我称这样的模式为“独木桥”,但是有了Spring,Struts和Hibernate能够更好的结合在一起,协调的工作。我称这样的模式为“阳光大道”。Spring的核心思想是IoC和AOP,Spring使得管理对象更加方便,极大的降低组件之间的耦合度,实现了软件各层之间的解耦。Spring的优点还有很多,我们就不再累述了。
4.2 Spring简介
spring 是一个轻量级的,基于IOC和AOP核心技术的企业级开源开发框架。
动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,根据xml Spring的配置文件来动态的创建对象,和调用对象里的方法的。
Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象 进行监督和控制(也就是 在调用这类对象的具体方法的前后去调用你指定的 模块)从而达到对一个模块扩充的功能。这些都是通过配置类达到的。
Spring目的:就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring根据这些配置 内部通过反射去动态的组装对象)
注意:Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。
4.3 Spring的主要特征
(1)轻量级:spring是一个轻量级的开发框架,基本版本大约只有2M
(2)IOC:控制反转,应用程序中对象之间的依赖是由spring 来控制的
(3)AOP:面向切面编程,spring支持面向切面编程,这样可以将业务逻辑和系统服务分开,分离
(4)容器:包含并管理应用程序中对象的生命周期和配置信息
(5)MVC思想:spring也是基于MVC思想的框架,也遵循模型-视图-控制器这三个层次
(6)事务:spring提供一个持续化的接口,可以上至扩展到本地事务下至扩展到全局事务
(7)异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,hibernate,or JDO抛出的)转化为一致的unchecked 异常。
4.4 Spring的优缺点
优点:
Spring能有效地组织你的中间层对象,不管你是否选择使用了EJB。如果你仅仅使用了Struts或其他为J2EE的 API特制的framework,Spring致力于解决剩下的问题。
Spring能消除在许多工程中常见的对Singleton的过多使用。根据我的经验,这是一个很大的问题,它降低了系统的可测试性和面向对象的程度。
通过一种在不同应用程序和项目间一致的方法来处理配置文件,Spring能消除各种各样自定义格式的属性文件的需要。曾经对某个类要寻找的是哪个魔法般的属性项或系统属
性感到不解,为此不得不去读Javadoc甚至源编码?有了Spring,你仅仅需要看看类的JavaBean属性。Inversion of Control的使用(在下面讨论)帮助完成了这种简化。
通过把对接口编程而不是对类编程的代价几乎减少到没有,Spring能够促进养成好的编程习惯。
Spring被设计为让使用它创建的应用尽可能少的依赖于他的APIs。在Spring应用中的大多数业务对象没有依赖于Spring。
使用Spring构建的应用程序易于单元测试。
Spring能使EJB的使用成为一个实现选择,而不是应用架构的必然选择。你能选择用POJOs或local EJBs来实现业务接口,却不会影响调用代码。
Spring帮助你解决许多问题而无需使用EJB。Spring能提供一种EJB的替换物,它们适用于许多web应用。例如,Spring能使用AOP提供声明性事务管理而不通过EJB容器,如果你仅仅需要与单个数据库打交道,甚至不需要一个JTA实现。
Spring为数据存取提供了一个一致的框架,不论是使用的是JDBC还是O/R mapping产品(如Hibernate)。
缺点:
1.jsp中要写很多代码、控制器过于灵活,缺少一个公用控制器
2.Spring不支持分布式,这也是EJB仍然在用的原因之一。