ssh整合

一.为什么要用框架和模式
1.为什么要用模式?
因为模式是一种指导,在一个良好的指导下,有助于你完成任务,有助于你作出一个优良的设计方案,达到事半功倍的效果。而且会得到解决问题的最佳办法。
2.为什么要用框架?
因为软件系统发展到今天已经很复杂了,特别是服务器端软件,设计到的知识,内容,问题太多。在某些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。而且框架一般是成熟,稳健的,他可以处理系统很多细节问题,比如,事物处理,安全性,数据流控制等问题。还有框架一般都经过很多人使用,所以结构很好,所以扩展性也很好,而且它是不断升级的,你可以直接享受别人升级代码带来的好处。总之:就是让开发更简单,让我们成功。
业务逻辑层:spring IoC,降低耦合度,减少模块之间在开发的影响.技巧:面向接口编程,使用反射机制,hibernate粒度等。
持久层:spirng的Hibernate支持
查看开源框架jar包源码方法:F3/Attach Source/External Folder/选择开源框架的src目录或src文件。如C:\Program Files\Java\jdk1.6.0_02\src.zip
                struts+spring方案一
原理:在Action中获取BeanFactory,并通过BeanFactory对象获取业务逻辑对象。
1创建web应用
2spring和struts集成
   安装struts{
struts的jar包
修改web.xml文件,定义struts的ActionServlet
提供struts-config.xml文件
提供国际化资源文件}
安装spring
拷贝spring的jar包
提供spring的配置文件
3在struts的Action中调用如下代码取出BeanFactory
     BeanFactory factory=WebApplicationContextUtils
                         .getRequiredWebApplicationContext(servletContext);
4通过BeanFactory取得业务对象,调用业务逻辑方法(不管理action)
struts+spring方案二
(耦合度比方案一低,最大的不便是所有的Action 必须同时在Struts 和
Spring 的配置文件中各配置一次。)
原理:将业务逻辑对象通过spring注入到action中,从而避免了在action中直接代码查找。
3因为Action中需要调用业务逻辑,在action中提供setter方法,让spring将业务逻辑对象注入给我们
4struts-config.xml文件中的<action>标签要改
5spring配置
local属性是在同一个配置文件中的bean
bean属性是指出一个bean,可以不在同一个配置文件中
一般用get不用load,因为get没有值返回null,而load会抛异常
spring需要配置hibernate的懒加载能够让Session解释完成再关闭,避免懒加载异常。OpenSessionInViewFilter模式web.xml中加入
<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate.support.OpenSessionInViewFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
window/show view/springbeans
show In spring beans view看spring bean的属性,看bean直接的依赖关联情况:在springbeans工作区里右键.xml文件/show Graph.
创建 Spring 配置文件,将文件放到src目录下,文件名称为 applicationContext.xml, 编译后放到 WEB-INF/classes/ 下.配置struts-config.xml文件,添加 spring的插件, 位置在 struts-config 文件的<message-resources>标签末尾.
<!-- 加载spring,xml -->
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
    <set-property    property="contextConfigLocation"    value="WEB-INF/classes/applicationContext-action.xml,WEB-INF/classes/applicationContext-business.xml,WEB-INF/classes/applicationContext-dao.xml,WEB-INF/classes/applicationContext-pojos.xml,WEB-INF/classes/applicationContext-sessionFactory.xml" />
  </plug-in>
<!--action注入service、pojo,service注入dao,dao注入sessionFactory-->
方法二:web.xml中加入
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            WEB-INF/applicationContext-*xml,classpath*:/applicationContext-*xml
        </param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
3. 修改 Struts 的 struts-config.xml 中的Action配置
原:
<action
attribute="loginForm"
input="/login.jsp"
name="loginForm"
path="/login"
scope="request"
validate="true"
type="com.test.struts.action.LoginAction" />
改为:
<action
attribute="loginForm"
input="/login.jsp"
name="loginForm"
path="/login"
scope="request"
validate="true"
type="org.springframework.web.struts.DelegatingActionProxy" />
type 部份为修改内容, 这里将使用spring的代理器来对Action进行控制. 没有调用到dao的Action的type没有必要改代理类来截获,
当提交到/login.do是将控制权交给了spring,然后由spring来把它转回到struts的Action.
修改 Struts 的 struts-config.xml 中的Action配置方法二
在<message-resources>标签前添加
<controller>
  <set-property property="processorClass"
      value="org.springframework.web.struts.DelegatingRequestProcessor"/>
</controller>
增加这些设置之后,不管你查询任何类型的 Action,Sping都自动在它的context配置文件中寻找。实际上,你甚至不需要指定类型。下面两个代码片断都可以工作: 
<action path="/user" type="com.whatever.struts.UserAction"/>        
<action path="/user"/>
如果你使用 Struts 的 modules 特性,你的 bean 命名必须含有 module 的前缀。 举个例子,如果一个 Action 的定义为 <action path="/user"/>,而且它的 module 前缀为“admin”, 那么它应该对应名为 <bean name="/admin/user"/> 的 bean。注意:
action bean必须使用name属性,不能用id属性
那么属性必须和struts-config.xml中的<action>标签的path属性值一致
最好将scope设置为prototype(或singleton=false),即每次请求创建一个action,从而避免了struts action的线程安全 
4. 配置spring 来实例化被删除的 Action type.
<beans>
<bean name="/login" class="com.test.struts.action.LoginAction" scope=prototype></bean>
</beans>
Spring 通过 org.springframework.web.struts.DelegatingActionProxy 这个类, 然后根据 Struts 配置文件中的 <action path="/login" ..> 和 Spring 配置文件中的 <bean name="/login" ..> 来将 Spring 管理下的 Struts Action 类和提交的路径匹配起来, 这些就是关于转交控制权的配置内容.

hibernate.cfg.xml中
当没有数据库表时可以在hibernate.cfg.xml中配置,让他运行时自己建表
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="show_sql">true</property>  <!--终端输出sql-->
<property name="format_sql">true</property> <!-- 使SQL语句格式更加美观统一 -->

<property name=" use_sql_comments ">true</property> <!--添加sql注释--> 
<property name="connection.useUnicode">true</property>
<property name="connection.characterEncoding">UTF-8</property>
spring.xml中
<prop key="show_sql">true</prop>
<prop key="format_sql">true</prop>
<prop key="connection.useUnicode">true</prop>
<prop key="connection.characterEncoding">UTF-8</prop> 
Middlegen+Ant+XDoclet能很方便构建项目.配置环境变量可以使用或方便使用因为可以命令行直接输入命令,不需要到该目录下。
spring事务管理
getHibernateTemplate().executeFind()返回list。
静态方法不能用getHibernateTemplate()因此可以用HibernateTemplate。HibernateTemplate对Hibernate Session操作进行了封装,借助HibernateTemplate我们可以脱离每次数据操作必须首先获得Session实例、启动事务、提交/回滚事务以及烦杂的try/catch/finally的繁琐操作。
    <bean id="hibernateTemplate"
        class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </proper
</bean>
JDK 的代理机制来实现事务管理的解决方案, 相比起来它有一个麻烦的地方就是必须需要生成一个 DAO 的接口才能工作. 那么另一种比较简单的解决方案就是用 CGBLIB, 可以不用编写接口, 那么下面是 Spring 参考文档中的内容:
基于JDK和CGLIB的代理
这个小节作为说明性文档,解释了对于一个目标对象(需要被代理的对象),ProxyFactryBean是如何决定究竟创建一个基于JDK还是CGLIB的代理的。 
注意
ProxyFactoryBean需要创建基于JDK还是CGLIB代理的具体行为在版本1.2.x和2.0中有所不同。现在ProxyFactoryBean在关于自动检测接口方面使用了与TransactionProxyFactoryBean相似的语义。 
如果一个需要被代理的目标对象的类(后面将简单地称它为目标类)没有实现任何接口,那么一个基于CGLIB的代理将被创建。这是最简单的场景,因为JDK代理是基于接口的,没有接口意味着没有使用JDK进行代理的可能。 在目标bean里将被插入探测代码,通过interceptorNames属性给出了拦截器的列表。注意一个基于CGLIB的代理将被创建即使ProxyFactoryBean的proxyTargetClass属性被设置为false。 (很明显这种情况下对这个属性进行设置是没有意义的,最好把它从bean的定义中移除,因为虽然这只是个多余的属性,但在许多情况下会引起混淆。) 
如果目标类实现了一个(或者更多)接口,那么创建代理的类型将根据ProxyFactoryBean的配置来决定。 
如果ProxyFactoryBean的proxyTargetClass属性被设为true,那么一个基于CGLIB的代理将创建。这样的规定是有意义的,遵循了最小惊讶法则(保证了设定的一致性)。 甚至当ProxyFactoryBean的proxyInterfaces属性被设置为一个或者多个全限定接口名,而proxyTargetClass属性被设置为true仍然将实际使用基于CGLIB的代理。 
如果ProxyFactoryBean的proxyInterfaces属性被设置为一个或者多个全限定接口名,一个基于JDK的代理将被创建。被创建的代理将实现所有在proxyInterfaces属性里被说明的接口;如果目标类实现了全部在proxyInterfaces属性里说明的接口以及一些额外接口,返回的代理将只实现说明的接口而不会实现那些额外接口。 
如果ProxyFactoryBean的proxyInterfaces属性没有被设置,但是目标类实现了一个(或者更多)接口,那么ProxyFactoryBean将自动检测到这个目标类已经实现了至少一个接口, 一个基于JDK的代理将被创建。被实际代理的接口将是目标类所实现的全部接口;实际上,这和在proxyInterfaces属性中列出目标类实现的每个接口的情况是一样的。然而,这将显著地减少工作量以及输入错误的可能性。 
好了, 详细阐述这个解决方案.
用 MyEclipse 的自动生成功能产生的 Spring + Hibernate 的 DAO 有时候会出现不能保存数据但是可以查询数据的问题, 这是因为默认生成的 Spring 配置文件里面没有包含对事务的操作, 也就是没有 commit Hibernate transaction 的调用所以无法保存数据. 也就是正确的调用需要 beginTran, save, commit, 但是现在就少了 tran 的调用代码部分. 
解决方法是在配置文件里"侵入性"(必须这样做, 做额外的配置和修改, 否则就无法正常工作, 所以是侵入性的)的加入事务配置后就可以正常的保存数据了.
1. 用 Eclipse 的重构给自动生成的 UsersDAO 类添加一个接口, 里面包含所有的方法声明, 例如 IUsersDAO, 加入接口的目的是为了使用 JDK 的动态代理方式实现的 Spring AOP 来工作,
2. 修改配置文件给原来的 UsersDAO 加入代理类来进行事务管理:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
.................
    <!-- UsersDAO implements IUsersDAO 接口 -->
    <bean id="UsersDAO" class="dao.UsersDAO">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>
................
1.基于CGLIB的代理, 修改配置文件给原来的 UsersDAO 加入代理类来进行事务管理:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!--右键new sessionFactory-->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation"
            value="file:src/hibernate.cfg.xml">
        </property>
    </bean>
    <bean id="UsersDAO" class="dao.UsersDAO">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>
<!-- 以下两个 Bean transactionManager 和baseTxProxy 是新加入的内容, 用来配置事务 -->
    <!-- 声明一个 Hibernate 3 的 事务管理器供代理类自动管理事务用 -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>
    <!-- 这个代理类是最后对外公开的类, 否则因为没有进行事务操作, 
    保存时没有提交 hibernate 的事务, 这将无法对数据库进行改动, 也就是原来要调用 UsersDAO 的地方都要转而调用这个代理对象 baseTxProxy; 具体的属性配置在 target 参数那里指定了这个对象对原来的 UsersDAO 对象进行代理;
    也因为要使用代理, 只有通过它来作为原来配置的UsersDAO 的代理工作, 才能让 Spring 在保存数据的时候自动打开Hibernate 的Transaction 并提交, 即属性 transactionManager 配置的 HibernateTransactionManager --> 
<bean id="baseTxProxy" lazy-init="true" 
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<!-- 注意这个属性,  必须为 true 使用CGLIB才不用强制编写DAO接口,使用dao接口不需要-->
        <property name="proxyTargetClass">
            <value>true</value>
        </property>
<property name="target">
<ref local="userServiceTarget " />
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="is*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
<!-- *是通配符,可以表示没有注册的所有方法 -->
</props>
</property>
</bean>
<bean id="userServiceTarget" class="org.mzone.service.impl.userServiceTarget">
      <property name="userDAO"><ref local="userDAO"/></property>
       <property name="articleDao"><ref local="articleDAO"/></property>
</bean>
</beans>

时间: 2024-08-22 15:14:02

ssh整合的相关文章

SSH整合问题实现DAO接口出现的问题

问题描述 SSH整合问题实现DAO接口出现的问题 package com.integration.dao; import java.util.List; import com.integration.entity.User; import org.hibernate.Query; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class UserDAOImpl extends Hiber

配置-求助,SSH整合后拦截器不起作用

问题描述 求助,SSH整合后拦截器不起作用 struts.xml配置如下 <interceptors> <interceptor name="loginInterceptor" class="com.music.interceptor.LoginInterceptor"></interceptor> <interceptor-stack name="globalInterceptor"> <i

exception-容器启动就报错,ssh整合

问题描述 容器启动就报错,ssh整合 严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListenerjava.lang.IllegalArgumentException at org.springframework.asm.ClassReader.(Unknown Source) at org.sp

SSH, 整合分页功能,连带DAO经典封装

任何一个封装讲究的是,使用,多状态. Action:     任何一个Action继承分页有关参数类PageManage,自然考虑的到分页效果,我们必须定义下几个分页的参数.并根据这个参数进行查值. 然后在继承ServiceManage,ServiceManage类是用来 存放共用的东西:response,重要的是Service的get set 具体讲一下PageManage,    totalPages;//总页数    totalRecord;//总记录数    showRecordNum=

exception-升级ssh整合出现错误java.lang.NoSuchMethodError:

问题描述 升级ssh整合出现错误java.lang.NoSuchMethodError: 下面是控制台打印的信息,麻烦看到的高手帮忙解决: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [cn/com/hope/framework/spring/appl

ssh整合是时,使用日期插件把数据插入数据库是发生错误

问题描述 ssh整合是时,使用日期插件把数据插入数据库是发生错误 警告: SQL Error: 604, SQLState: 60000 2015-7-9 20:31:44 org.hibernate.util.JDBCExceptionReporter logExceptions 严重: ORA-00604: 递归 SQL 级别 1 出现错误 ORA-00942: 表或视图不存在 2015-7-9 20:31:44 org.hibernate.tool.hbm2ddl.SchemaUpdate

java-Java的框架SSH整合的项目,项目启动时总是会报一个莫名其妙的错误?

问题描述 Java的框架SSH整合的项目,项目启动时总是会报一个莫名其妙的错误? Unable to load configuration. - [unknown location] Caused by: Unable to load configuration. - [unknown location] Caused by: Unable to load jar:file:/D:/mars-workspace/.metadata/.plugins/org.eclipse.wst.server.

ssh整合-SSH整合时出现空指针问题

问题描述 SSH整合时出现空指针问题 最近在做实训,所以想尝试用SSH框架来做个项目,我跟着视频,一步一步的敲代码,一运行, 报空指针,好吧,看看是什么说,根据提示信息:是employeeService为null,可是我在 applicationContext-bean.xml的配置文件中已经注入了啊: 这下就难道我了,在网上搜索了快两天了,还是没有头绪,所以特来请教大神们,教教我呗: 项目我上传在: http://1185651333201311151844.iteye.com/admin/b

注解-麻烦帮我看下SSH整合遇到的问题

问题描述 麻烦帮我看下SSH整合遇到的问题 最近公司要用SSH注解开发 我做了个小demo但是导入Easy UI的时候出现这个错误 解决方案 看样子是你代码里的EasyUI的引入路径写错了.可以把代码贴出来看下. 解决方案二: <link rel="stylesheet" type="text/css" href="/EasyUI/themes/default/easyui.css"> <link rel="style

带分页功能的SSH整合,DAO层经典封装

任何一个封装讲究的是,使用,多状态.Action:     任何一个Action继承分页有关参数类PageManage,自然考虑的到分页效果,我们必须定义下几个分页的参数.并根据这个参数进行查值. 然后在继承ServiceManage,ServiceManage类是用来 存放共用的东西:response,重要的是Service的get set 具体讲一下PageManage,    totalPages;//总页数    totalRecord;//总记录数    showRecordNum=D