ssh框架搭建
第一步,创建WEB工程,添加struts支持
第二步,分包
第三步,添加spring支持
第四步,添加spring配置文件
第五步,在web.xml文件中配置初始化读取参数(spring的配置文件)
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
第六步,配置spring监听器
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
第七步,在struts-config.xml文件中配置请求处理器,将struts请求委托给spring代理,达到控制反转的目的
<controller processorClass=“
org.springframework.web.struts.DelegatingRequestProcessor">
</controller>
第八步,添加hibernate支持
第九步,配置好hibernate以后,在applicationContext.xml文件中会自动生成“数据源”,“sessionFactory”,代码如下:
<!-- 配置数据源 -->
<bean id="dsid" class="org.apache.commons.dbcp.BasicDataSource">
<!-- 方法注入 -->
<property name="driverClassName"
value="com.microsoft.jdbc.sqlserver.SQLServerDriver">
</property>
<property name="url"
value="jdbc:microsoft:sqlserver://localhost:1433;databaseName=pubs">
</property>
<property name="username" value="sa"></property>
<property name="password" value="sa"></property>
</bean>
<!-- 将hib中的sessionFactory封装 -->
<bean id="sfid"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 引用实例化好的数据源 -->
<property name="dataSource">
<ref bean="dsid" />
</property>
<property name="hibernateProperties">
<props>
<!-- 设置数据库方言 -->
<prop key="hibernate.dialect">
org.hibernate.dialect.SQLServerDialect
</prop>
<prop key="show_sql">
true
</prop>
</props>
</property>
</bean>
第十步,通过表,反向生成” 实体类”,” 配置文件”
第十一步,当正确添加实体后,在appilcationContext.xml文件中会自动添加实体类的映射
<!-- 将hib中的sessionFactory封装 -->
<bean id="sfid"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 映射表对象 -->
<property name="mappingResources">
<list>
<value>com/alex/ssh/entity/Root58.hbm.xml</value>
</list>
</property>
</bean>
第十二步,修改DAO类的位置,修改配置文件属性值
<bean id="Root58DAO" class="com.alex.ssh.dao.Root58DAO">
<property name="sessionFactory">
<ref bean="sfid" />
</property>
</bean>
第十三步,添加service类,反转service Class
<!-- 反转service -->
<bean id="rootService"
class="com.alex.ssh.service.RootService">
<property name="dao">
<ref bean="Root58DAO"/>
</property>
</bean>
public void save(RootForm root) {
Root58 r = new Root58();
r.setUsername(root.getName());
r.setUsercity(root.getCity());
this.getDao().save(r);
}
第十四步,添加struts部分(添加jsp,form,action)
第十五步,将struts-config.xml文件中action节点的type属性去掉
<action name="rootForm" path="/root"/>
第十六步,在acpplicationContext.xml文件中代理action类,也是一种控制反转的实现
<!-- 反转action name属性的取值与struts配置中的path="/root"一致 -->
<bean name="/root" class="com.alex.ssh.action.RootAction" >
<property name="service">
<ref bean="rootService"/>
</property>
</bean>
第十七步,运行调试
SSH生命周期
Struts,Hibernate,Spring经典面试题收藏
关键字: struts, hibernate, spring
Hibernate工作原理及为什么要用?
原理:
1.读取并解析配置文件
2.读取并解析映射信息,创建SessionFactory
3.打开Sesssion
4.创建事务Transation
5.持久化操作
6.提交事务
7.关闭Session
8.关闭SesstionFactory
为什么要用:
1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作
3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。
4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
2. Hibernate是如何延迟加载?
1. Hibernate2延迟加载实现:a)实体对象 b)集合(Collection)
2. Hibernate3 提供了属性的延迟加载功能
当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。
3.Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系)
类与类之间的关系主要体现在表与表之间的关系进行操作,它们都市对对象进行操作,我们程序中把所有的表与类都映射在一起,它们通过配置文件中的many-to-one、one-to-many、many-to-many、
4. 说下Hibernate的缓存机制
1. 内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存
2. 二级缓存:
a) 应用及缓存
b) 分布式缓存
条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非 关键数据
c) 第三方缓存的实现
5. Hibernate的查询方式
Sql、Criteria,object comptosition
Hql:
1、 属性查询
2、 参数查询、命名参数查询
3、 关联查询
4、 分页查询
5、 统计函数
6. 如何优化Hibernate?
1.使用双向一对多关联,不使用单向一对多
2.灵活使用单向一对多关联
3.不用一对一,用多对一取代
4.配置对象缓存,不使用集合缓存
5.一对多集合使用Bag,多对多集合使用Set
6. 继承类使用显式多态
7. 表字段要少,表关联不要怕多,有二级缓存撑腰
7. Struts工作机制?为什么要使用Struts?
工作机制:
Struts的工作流程:
在web应用启动时就会加载初始化ActionServlet,ActionServlet从
struts-config.xml文件中读取配置信息,把它们存放到各种配置对象
当ActionServlet接收到一个客户请求时,将执行如下流程.
-(1)检索和用户请求匹配的ActionMapping实例,如果不存在,就返回请求路径无效信息;
-(2)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中;
-(3)根据配置信息决定是否需要表单验证.如果需要验证,就调用ActionForm的validate()方法;
-(4)如果ActionForm的validate()方法返回null或返回一个不包含ActionMessage的ActuibErrors对象, 就表示表单验证成功;
-(5)ActionServlet根据ActionMapping所包含的映射信息决定将请求转发给哪个Action,如果相应的 Action实例不存在,就先创建这个实例,然后调用Action的execute()方法;
-(6)Action的execute()方法返回一个ActionForward对象,ActionServlet在把客户请求转发给 ActionForward对象指向的JSP组件;
-(7)ActionForward对象指向JSP组件生成动态网页,返回给客户;
为什么要用:
JSP、Servlet、JavaBean技术的出现给我们构建强大的企业应用系统提供了可能。但用这些技术构建的系统非常的繁乱,所以在此之上,我们需要一个规则、一个把这些技术组织起来的规则,这就是框架,Struts便应运而生。
基于Struts开发的应用由3类组件构成:控制器组件、模型组件、视图组件
8. Struts的validate框架是如何验证的?
在struts配置文件中配置具体的错误提示,再在FormBean中的validate()方法具体调用。
9. 说下Struts的设计模式
MVC 模式: web应用程序启动时就会加载并初始化ActionServler。用户提交表单时,一个配置好的ActionForm对象被创建,并被填入表单相应的数据,ActionServler根据Struts-config.xml文件配置好的设置决定是否需要表单验证,如果需要就调用ActionForm的 Validate()验证后选择将请求发送到哪个Action,如果Action不存在,ActionServlet会先创建这个对象,然后调用 Action的execute()方法。Execute()从ActionForm对象中获取数据,完成业务逻辑,返回一个ActionForward对象,ActionServlet再把客户请求转发给ActionForward对象指定的jsp组件,ActionForward对象指定的jsp生成动态的网页,返回给客户。
10. spring工作机制及为什么要用?
1.spring mvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作。
2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller.
3.DispatcherServlet请请求提交到目标Controller
4.Controller进行业务逻辑处理后,会返回一个ModelAndView
5.Dispathcher查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象
6.视图对象负责渲染返回给客户端。
为什么用:
{AOP 让开发人员可以创建非行为性的关注点,称为横切关注点,并将它们插入到应用程序代码中。使用 AOP 后,公共服务 (比如日志、持久性、事务等)就可以分解成方面并应用到域对象上,同时不会增加域对象的对象模型的复杂性。
IOC 允许创建一个可以构造对象的应用环境,然后向这些对象传递它们的协作对象。正如单词 倒置 所表明的,IOC 就像反 过来的 JNDI。没有使用一堆抽象工厂、服务定位器、单元素(singleton)和直接构造(straight construction),每一个对象都是用其协作对象构造的。因此是由容器管理协作对象(collaborator)。
Spring即使一个AOP框架,也是一IOC容器。 Spring 最好的地方是它有助于您替换对象。有了 Spring,只要用 JavaBean 属性和配置文件加入依赖性(协作对象)。然后可以很容易地在需要时替换具有类似接口的协作对象。}
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,如图 1 所示。
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
☆ 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
☆ Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
☆ Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
☆ Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
☆ Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
☆ Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
☆ Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独立应用程序、测试环境之间重用。
IOC 和 AOP
控制反转模式(也称作依赖性介入)的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器(在 Spring 框架中是 IOC 容器) 负责将这些联系在一起。
在典型的 IOC 场景中,容器创建了所有对象,并设置必要的属性将它们连接在一起,决定什么时间调用方法。下表列出了 IOC 的一个实现模式。
Spring 框架的 IOC 容器采用类型 2 和类型3 实现。
面向方面的编程
面向方面的编程,即 AOP,是一种编程技术,它允许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOP 的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。
AOP 和 IOC 是补充性的技术,它们都运用模块化方式解决企业应用程序开发中的复杂问题。在典型的面向对象开发方式中,可能要将日志记录语句放在所有方法和 Java 类中才能实现日志功能。在 AOP 方式中,可以反过来将日志服务模块化,并以声明的方式将它们应用到需要日志的组件上。当然,优势就是 Java 类不需要知道日志服务的存在,也不需要考虑相关的代码。所以,用 Spring AOP 编写的应用程序代码是松散耦合的。
AOP 的功能完全集成到了 Spring 事务管理、日志和其他各种特性的上下文中。
IOC 容器
Spring 设计的核心是 org.springframework.beans 包,它的设计目标是与 JavaBean 组件一起使用。这个包通常不是由用户直接使用,而是由服务器将其用作其他多数功能的底层中介。下一个最高级抽象是 BeanFactory 接口,它是工厂设计模式的实现,允许通过名称创建和检索对象。BeanFactory 也可以管理对象之间的关系。
BeanFactory 支持两个对象模型。
□ 单态 模型提供了具有特定名称的对象的共享实例,可以在查询时对其进行检索。Singleton 是默认的也是最常用的对象模型。对于无状态服务对象很理想。
□ 原型 模型确保每次检索都会创建单独的对象。在每个用户都需要自己的对象时,原型模型最适合。
bean 工厂的概念是 Spring 作为 IOC 容器的基础。IOC 将处理事情的责任从应用程序代码转移到框架。正如我将在下一个示例中演示的那样,Spring 框架使用 JavaBean 属性和配置数据来指出必须设置的依赖关系。
BeanFactory 接口
因为 org.springframework.beans.factory.BeanFactory 是一个简单接口,所以可以针对各种底层存储方法实现。最常用的 BeanFactory 定义是 XmlBeanFactory,它根据 XML 文件中的定义装入 bean,如清单 1 所示。
清单 1. XmlBeanFactory
BeanFactory factory = new XMLBeanFactory(new FileInputSteam("mybean.xml"));
在 XML 文件中定义的 Bean 是被消极加载的,这意味在需要 bean 之前,bean 本身不会被初始化。要从 BeanFactory 检索 bean,只需调用 getBean() 方法,传入将要检索的 bean 的名称即可,如清单 2 所示。
清单 2. getBean()
MyBean mybean = (MyBean) factory.getBean("mybean");
每个 bean 的定义都可以是 POJO (用类名和 JavaBean 初始化属性定义) 或 FactoryBean。FactoryBean 接口为使用 Spring 框架构建的应用程序添加了一个间接的级别。
IOC 示例
理解控制反转最简单的方式就是看它的实际应用。在对由三部分组成的 Spring 系列 的第 1 部分进行总结时,我使用了一个示例,演示了如何通过 Spring IOC 容器注入应用程序的依赖关系(而不是将它们构建进来)。
我用开启在线信用帐户的用例作为起点。对于该实现,开启信用帐户要求用户与以下服务进行交互:
☆ 信用级别评定服务,查询用户的信用历史信息。
☆ 远程信息链接服务,插入客户信息,将客户信息与信用卡和银行信息连接起来,以进行自动借记(如果需要的话)。
☆ 电子邮件服务,向用户发送有关信用卡状态的电子邮件。
三个接口
对于这个示例,我假设服务已经存在,理想的情况是用松散耦合的方式把它们集成在一起。以下清单显示了三个服务的应用程序接口。
清单 3. CreditRatingInterface
public interface CreditRatingInterface {
public boolean getUserCreditHistoryInformation(ICustomer iCustomer);
}
清单 3 所示的信用级别评定接口提供了信用历史信息。它需要一个包含客户信息的 Customer 对象。该接口的实现是由 CreditRating 类提供的。
清单 4. CreditLinkingInterface
public interface CreditLinkingInterface {
public String getUrl();
public void setUrl(String url);
public void linkCreditBankAccount() throws Exception ;
}
信用链接接口将信用历史信息与银行信息(如果需要的话)连接在一起,并插入用户的信用卡信息。信用链接接口是一个远程服务,它的查询是通过 getUrl() 方法进行的。URL 由 Spring 框架的 bean 配置机制设置,我稍后会讨论它。该接口的实现是由 CreditLinking 类提供的。
清单 5. EmailInterface
public interface EmailInterface {
public void sendEmail(ICustomer iCustomer);
public String getFromEmail();
public void setFromEmail(String fromEmail) ;
public String getPassword();
public void setPassword(String password) ;
public String getSmtpHost() ;
public void setSmtpHost(String smtpHost);
public String getUserId() ;
public void setUserId(String userId);
最近在弄j2ee,发现还是学到了很多东西,心情happy啊!昨天看到了一个文章是关于ssh的,就弄下来了,后面加点自己的东西,很感谢网上的各位前辈的总结。一个spring2.5+hibernate3.2+struts2.0组合框架,使用spring的IoC来管理应用的所有bean,包括struts2的action,充分发挥了spring轻量级框架的优势。
摘 要:针对当前Web应用程序开发面临的问题,结合目前比较流行的开源框架Spring、Struts和Hibernate,提出了一种开发J2EE Web应用的轻量级解决方案,以帮助开发人员在短期内搭建结构清晰、可复用性好、维护方便的Web应用程序。并且,通过案例具体说明了如何将这一方案应用到实际项目中。
关键词:J2EE MVC Struts Spring Hibernate
大型企业级Web应用系统的开发通常要求有一个良好的软件架构、便于协作开发和扩展升级,而传统的开发模式不能很好地满足这些要求。本文针对当前Web应用程序开发面临的问题,结合目前比较流行的开源框架SSH(Spring、Struts、Hibernate),提出一种开发J2EE 企业级Web应用的轻量级解决方案,并通过案例具体说明如何将这一方案应用到实际项目中。
1 框架技术
著名的软件大师Ralph Johnson对框架(Framework)进行了如下的定义: 框架是整个系统或系统的一部分的可重用设计,由一组抽象的类及其实例间的相互作用方式组成[1]。
框架一般具有即插即用的可重用性、成熟的稳定性以及良好的团队协作性。J2EE复杂的多层结构决定了大型的J2EE项目需要运用框架和设计模式来控制软件质量。目前,市场上出现了一些商业的、开源的基于J2EE的应用框架,其中主流的框架技术有:基于MVC模式的Struts框架和基于IoC模式的Spring框架以及对象/关系映射框架Hibernate等。
1.1 表示层框架Struts
Struts是一个在JSP Model2基础上实现的MVC框架,主要分为模型(Model)、视图(Viewer)和控制器(Controller)三部分,其主要的设计理念是通过控制器将表现逻辑和业务逻辑解耦,以提高系统的可维护性、可扩展性和可重用性[2]。Struts框架的体系结构如图1所示。
下面就图1所示的体系结构图分析Struts框架中的MVC组件。
(1)视图:视图部分主要由JSP页面组成,其中没有流程逻辑、业务逻辑和模型信息,只有标记。Struts自身包含了一组标记库(TagLib),这也是Struts的精华之一,灵活运用它们可以简化JSP页面的代码,提高开发效率。
(2)控制器:Struts中的Controller主要是其自身提供的ActionServlet。ActionServlet接收所有来自客户端的请求并根据配置文件(struts-config.xml)中的定义将控制转移到适当的Action对象。
(3)模型:Struts没有定义具体Model层的实现,Model层通常是和业务逻辑紧密相关的,有持续化的要求。目前在商业领域和开源世界,都有一些优秀的工具可以为Model层的开发提供便利。
1.2 业务逻辑层框架Spring
Spring是一个解决了许多J2EE开发中常见问题并能够替代EJB技术的强大的轻量级框架。这里所说的轻量级指的是Spring框架本身,而不是指Spring只能用于轻量级的应用开发。Spring的轻盈体现在其框架本身的基础结构以及对其他应用工具的支持和装配能力。与EJB这种庞然大物相比,Spring可使程序研发人员把各个技术层次之间的风险降低。
Spring框架的核心是控制翻转IoC(Inversion of Control)/依赖注入DI(Dependence Injection)机制。IoC是指由容器中控制组件之间的关系(这里,容器是指为组件提供特定服务和技术支持的一个标准化的运行时的环境)而非传统实现中由程序代码直接操控,这种将控制权由程序代码到外部容器的转移,称为“翻转”[3]。DI是对IoC更形象的解释,即由容器在运行期间动态地将依赖关系(如构造参数、构造对象或接口)注入到组件之中[3]。Spring采用设值注入(使用Setter方法实现依赖)和构造子注入(在构造方法中实现依赖)的机制,通过配置文件管理组建的协作对象,创建可以构造组件的IoC容器。这样,不需要编写工厂模式、单例模式或者其他构造的方法,就可以通过容器直接获取所需的业务组件。Spring框架的结构如图2所示。
Spring框架由七个定义明确的模块组成,且每个模块或组件都可以单独存在,或者与其他一个或多个模块联合实现。Spring Core Container是一个用来管理业务组件的IoC容器,是Spring应用的核心;Spring DAO和Spring ORM不仅提供数据访问的抽象模块,还集成了对Hibernate、JDO和iBatis等流行的对象关系映射框架的支持模块,并且提供了缓冲连接池、事务处理等重要的服务功能,保证了系统的性能和数据的完整性;Sprnig Web模块提供了Web应用的一些抽象封装,可以将Struts、Webwork等Web框架与Spring整合成为适用于自己的解决方案。
Spring框架可以成为企业级应用程序一站式的解决方案,同时它也是模块化的框架,允许开发人员自由地挑选适合自己应用的模块进行开发。Spring框架式是一个松耦合的框架,框架的部分耦合度被设计为最小,在各个层次上具体选用哪个框架取决于开发者的需要。
1.3 数据持久层框架Hibernate
O/R mapping技术是为了解决关系型数据库和面向对象的程序设计之间不匹配的矛盾而产生的。Hibernate是目前最为流行的O/R mapping框架,它在关系型数据库和Java对象之间做了一个自动映射,使得程序员可以以非常简单的方式实现对数据库的操作。Hibernate工作原理如图3所示。
Hibernate通过对JDBC的封装,向程序员屏蔽了底层的数据库操作,使程序员专注于OO程序的开发,有助于提高开发效率。程序员访问数据库所需要做的就是为持久化对象编制xml映射文件[4]。
底层数据库的改变只需要简单地更改初始化配置文件(hibernate.cfg.xml或者hibernate.properties)即可,不会对应用程序产生影响。
Hibernate有自己的面向对象的查询语言HQL,HQL功能强大,支持目前大部分主流的数据库,如Oracle、DB2、MySQL、Microsoft SQL Server等,是目前应用最广泛的O/R映射工具。Hibernate为快速开发应用程序提供了底层的支持。
2 基于SSH组合框架的Web应用模型设计与实现
2.1 集成SSH的新型J2EE框架
前面分析了基于J2EE的三种框架技术,下面通过集成以上三种框架技术来对传统的J2EE Web开发模型加以改进,以形成一种新的、轻量型的J2EE架构。
集成SSH框架的系统框架图如图4所示,系统从职责上分为四层:表示层、业务逻辑层、数据持久层和域模块层。其中使用Struts作为系统的整体基础架构,负责MVC的分离,在Struts框架的模型部分,利用Hibernate框架对持久层提供支持,业务层用Spring支持。具体做法是:用面向对象的分析方法根据需求提出一些模型,将这些模型实现为基本的Java对象,然后编写基本的DAO接口,并给出Hibernate的DAO实现,采用Hibernate架构实现的DAO类来实现Java类与数据库之间的转换和访问,最后由Spring完成业务逻辑。
系统的基本业务流程是: 在表示层中,首先通过JSP页面实现交互界面,负责传送请求(Request)和接收响应(Response),然后Struts根据配置文件(struts-config.xml)将ActionServlet接收到的Request委派给相应的Action处理。在业务层中,管理服务组件的Spring IoC容器负责向Action提供业务模型(Model)组件和该组件的协作对象数据处理(DAO)组件完成业务逻辑,并提供事务处理、缓冲池等容器组件以提升系统性能和保证数据的完整性。而在持久层中,则依赖于Hibernate的对象化映射和数据库交互,处理DAO组件请求的数据,并返回处理结果。
采用上述开发模型,不仅实现了视图、控制器与模型的彻底分离,而且还实现了业务逻辑层与持久层的分离。这样无论前端如何变化,模型层只需很少的改动,并且数据库的变化也不会对前端有所影响,大大提高了系统的可复用性。而且由于不同层之间耦合度小,有利于团队成员并行工作,大大提高了开发效率。
2.2 基于SSH框架的Web应用系统的实现
下面将通过一个实际的系统来展示如何进行基于SSH框架的Web应用开发。该系统是为某通信公司运营部开发的一个问答式系统,功能类似于百度知道和新浪爱问。由于系统的模块较多,下面就以一个用户管理模块为例来说明系统的开发实现过程,并将按照数据持久层、业务逻辑层、表示层的顺序说明系统构建过程。
(1)数据持久层
数据持久层由Java对象持久化类和数据访问对象(DAO)组成。每个数据库表都对应着一个持久化对象,这样就给予了开发者使用OO思想设计和开发的便利,同时也屏蔽了具体的数据库和具体的数据表、字段,消除了对数据库操作的硬编码在重用性上的弊端。用户信息表的部分结构如表1所示。
Hibernate通过映射(Mapping)文件将对象(Object)与关系型数据(Relational)相关联,因此需要编写和数据库表相对应的Java持久化类以及对应的映射文件。有了Java持久化类后就可以在此基础上实现数据访问类。在Spring框架中,数据访问类可以从辅助类HibernateDaoSupport继承,这极大地方便了Hibernate框架在Spring中的使用,相应的部分代码如下:
public class UserDao
extends HibernateDaoSupport {
public int add(User user) {
return Integer.ParseInt(this.getHibernateTemplate().save(user).toString());
}
public List findAll() {
return this.getHibernateTemplate().loadAll(User.class);
}
}
具体的Hibernate数据源、session工厂、事务管理、缓冲连接池等功能都由业务层的Spring容器提供。
(2)业务逻辑层
业务逻辑层由Spring框架支持,提供了处理业务逻辑的服务组件。开发者需要对业务对象建模,抽象出业务模型并封装在Model组件中。由于数据持久层实现了Java持久化类并且封装了数据访问对象(DAO),因此可以在Model组件中方便地调用DAO组件来存取数据。Spring的IoC容器负责统一管理Model组件和DAO组件以及Spring所提供的事务处理、缓冲连接池等服务组件。
在用户管理模块中,通过业务建模创建了用户模型UserService类,封装了对用户的权限管理以及积分管理等功能。UserService类通过调用数据访问类UserDao实现对用户数据的操作。这些组件的关系将通过配置Spring框架的applicationContext.xml联系起来,配置文件的主要内容如下:
(3)表示层
表示层结合JSP和Struts的TagLib库处理显示功能,利用ActionServlet将请求(*.do)映射到相应的Action,并由Action调用业务逻辑的服务组件,然后根据处理结果跳转到Forword对象指定的响应页面。
业务流程的部署由struts-config.xml完成。下面以一个显示所有用户信息的请求(ListUser.do)为例来说明配置文件的使用。
基于J2EE的Web应用以其层次性、平台无关性的优势已经逐渐成为了电子商务、电子政务主要的解决方案。本文针对传统的J2EE Web应用开发的弊端,提出了一种利用轻量级框架来快速搭建Web应用的解决方案,并且通过其在实际项目中的应用,证明了采用此方案可以帮助开发人员在短时间内建立结构清晰、可重用性好、维护扩展方便的Web应用程序。
参考文献
[1] GAMMA E, HELM R, JOHNSON R, et al. Design patterns:Elements of reusable object-oriented software[M]. Addison Wesley, 1994.
[2] 孙卫琴.精通Struts:基于MVC的Java Web设计与开发[M]. 北京:电子工业出版社,2004.
[3] JOHNSON R, HOELLER J, ARENDSEN A, et al. Java/J2EE application framework reference document. V1.1.
2004.
[4] 徐长盛,戴超.一种快速开发Web应用程序方法的研究[J]. 计算机工程与设计,2004,(12):2237-2239.
[5] 夏昕,曹晓钢,唐勇.深入浅出Hibernate[M]. 北京:电子工业出版社,2005.
[6] JOHNSON R.Expert one-on-one J2EE design and development[M]. 魏海萍译.北京:电子工业出版社,2003.
在用ssh开发web应用时,需要对生成的各个类文件进行组织,下面就对一个可行的目录方案进行介绍:
譬如应用中有一个用户管理模块,则在公共包下建立一个user包,如该公共包可以为com.simon.oa,
在user包下包括如下子包
1、controler包
该包放置各种struts的action。
2、dao包
该包放置各类dao(data access object),也就是放置对数据库访问的实现类,在用myeclipse中的“Hibernate Reverse Engineering”进行反向操作时在某一个目录中就会生成对应某个表的DAO,生成后可将该DAO拖到dao包中。在某些应用中将DAO作为接口,在该接口中包括所有对数据库的操作方法,然后在dao包建立一个hibernate包,在hibernate包中放置对DAO接口的实现,譬如:UserDAO接口有一个实现类为UserDaoImpl,将该类放置到hibernate包中,实际的开发倾向于后一种方式,因为对这个DAO接口可以实现spring的IoC操作。(不知道myeclipse对此是怎么考虑的,这个问题让我纠缠了很久,误将DAO理解成一个能够进行实际操作的类,而不是一个接口,以后开发要注意)
3、model包
该包中放置hibernate反向工程生成的bean和该bean对应的.hbm.xml文件。
4、service包
该包放置业务操作类,譬如用户服务类,一般情况将该用户操作类提取一个接口,然后在service包下生成一个impl包,在impl包中才放置用户操作接口的实现类。该用户接口实现类中调用DAO接口对数据库进行操作,而调用该实现类的方法在struts的action中。
5、vo包(value object)
vo包中的中包括struts中使用的POJO及actionform等信息。
VO: Value Object
DTO: Data Transfer Object
个人理解VO和DTO是类似的东西,原则上VO和DTO只有Public Fields,主要用于进程之间数据传递的问题,VO和DTO不会传递到表示层,在业务层就会被吸收。但看到很多人在建立VO和DTO时,也含有Setter,Getter属性和一些其它的辅助方法,这也无可厚非,我自己也不能确定这对不对。