本文介绍WebSphere下Oracle、SQL Server、Sybase、MySQL数据库连接池的配置方法,并给出相应调用连接池的示例。相对于Weblogic,WebSphere连接池的配置要稍微复杂一些,因为缺少相关的文档,需要一定的技巧和经验。特别是对于初学者,完整的配置好Websphere连接池还是有一定难度的。

一、系统准备
1.在相应的数据库中建立本文用到的表

create table TEST(C1 CHAR(10) )
insert into TEST values('FromTest')


2.准备环境变量,此部分往往会被初学者忽略。

image

点击“管理WebSphere变量”,ORACLE_JDBC_DRIVER_PATH的值输入操作系统中jar文件(classes12.jar)的位置。
“确认”后,界面最上方,点击“保存”,会再提示“保存”还是“放弃”,再选“保存”。

为方便起见,本文中,SQL Server的jar文件(msbase.jar、mssqlserver.jar、msutil.jar )、Sybase的jar文件(jconn2.jar)、mySQL的jar文件(mysql-connector-java-3.1.10-bin.jar)都放在同一目录(如:C:\oracle\ora92\jdbc\lib)。

3.本文中的所有例子测试均通过,环境:Windows2003、WebShpere5.1、ORACLE9I、SQL Server 2000、SYBASE12.5、MySQL5.0。

二、Oracle、SQL Server、Sybase、MySQL数据库连接池在WebSphere中的详细配置步骤

(一)、Oracle连接池的配置

1.进入管理控制台(http://localhost:9090/admin/)

2.选择:资源->JDBC提供程序,点击“新建”,建立JDBC提供程序。

image
点击“应用”后,类路径中,输入“${ORACLE_JDBC_DRIVER_PATH}/classes12.jar”,再点击“应用”。

3.定义数据源
点击界面中“数据源后”再点击“新建”,建立数据源。

image
JNDI取名ORACLE_JNDI,点击“应用”。

4.界面上点击“定制属性”,定义连接池的JDBC Driver、URL、用户名和口令等信息。
点击“URL”,URL的值输入:jdbc:oracle:thin:@localhost:1521:MYHORA,其中,localhost可以为ORACLE的IP地址,MYHORA是ORACLE的服务名称。
点击“确定”保存配置。
同样的方法输入:
driverType的值oracle.jdbc.driver.OracleDriver
databasename的值MYHORA
servername的值localhost
preTestSQLString的值为SELECT COUNT(1) FROM TEST
其余的取默认值。

5.本部分比较关键,是初学着比较困惑的地方。
我们看到,界面上并没有输入用户名、口令的地方,而没有用户名称、口令是无法连接数据库的。

image
在“定制属性”中点击“新建”,“名称”中输入user,“值”中输入数据库的用户名称,如:study,点击“确定”;
在“定制属性”中点击“新建”,“名称”中输入password,“值”中输入数据库的口令,如:study,点击“确定”;
我们看到,“定制属性”中多了两个我们自定义的属性user、password

image

6.保存配置,在“定制属性”界面的最上方点击“保存”。

7.测试连接

image

系统提示:成功信息,表明,连接池配置成功。
连接池配置成功后,WebSphere需要重新启动。

(二)、SQL server连接池的配置

SQL Server连接池的配置步骤同Oracle,具体的参数值:
JDBC 提供程序:下拉选择Microsoft JDBC driver for MSSQLServer 2000
Sybase连接池的配置步骤也同Oracle,具体的参数值:
常规属性中的名称:Microsoft JDBC driver for MSSQLServer 2000
常规属性中的描述:Microsoft JDBC driver for MSSQLServer 2000
常规属性中的类路径:
${ORACLE_JDBC_DRIVER_PATH}/msbase.jar
${ORACLE_JDBC_DRIVER_PATH}/mssqlserver.jar
${ORACLE_JDBC_DRIVER_PATH}/msutil.jar

常规属性中的实现类名:默认
数据源中的名称:SQLSERVER_JNDI
数据源中的JNDI:SQLSERVER_JNDI
定制属性中的databaseName:数据库名称
定制属性中的serverName:Sybase数据库服务器的名称或IP
定制属性中的portNumber:端口号
定制属性中的preTestSQLString:SELECT COUNT(1) FROM TEST
同Oracle,手工“新建”user和password属性,值为数据库的用户名和口令,该用户的缺省数据库必须为databaseName的值。
其他默认。

(三)、Sybase连接池的配置

JDBC 提供程序:下拉选择Sybase JDBC Driver
Sybase连接池的配置步骤也同Oracle,具体的参数值:
常规属性中的名称:SYBASE JDBC Driver
常规属性中的描述:SYBASE JDBC Driver
常规属性中的类路径:${ORACLE_JDBC_DRIVER_PATH}/jconn2.jar
常规属性中的实现类名:默认
数据源中的名称:SYBASE_JNDI
数据源中的JNDI:SYBASE_JNDI
定制属性中的databaseName:数据库名称
定制属性中的serverName:Sybase数据库服务器的名称或IP
定制属性中的portNumber:端口号
定制属性中的preTestSQLString:SELECT COUNT(1) FROM TEST
同Oracle,手工“新建”user和password属性,值为数据库的用户名和口令,该用户的缺省数据库必须为databaseName的值。
其他默认。

(四)、MySQL连接池的配置

MySQL连接池的配置步骤同Oracle稍有不同,JDBC 提供程序中并没有MySQL中的选项,选Oracle JDBC Driver就可以,实际运行中,WebSphere是以设置的参数为准的。

具体的参数值:
常规属性中的名称:MySQL JDBC Driver
常规属性中的描述:MySQL JDBC Driver
常规属性中的类路径:${ORACLE_JDBC_DRIVER_PATH}/mysql-connector-java-3.1.10-bin.jar
常规属性中的实现类名:com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource
数据源中的名称:MYSQL_JNDI
数据源中的JNDI:MYSQL_JNDI

image

由于WebSphere没有缺省的MySQL选项,“定制属性”全部需要手工新建。具体的值要根据MySQL的实际环境要做相应修改(petshop是我机器上的数据库名称)。

三、应用程序中测试连接池。

1. jsp程序中测试连接池

附件中的TestConnPoolWeb.ear文件直接发布后,
运行:http://localhost:9080/TestConnPoolWeb/oracle_pool.jsp,结果:ORACLE_JNDI:FromTest
运行:http://localhost:9080/TestConnPoolWeb/sqlserver_pool.jsp,结果:SQLSERVER_JNDI:FromTest
运行:http://localhost:9080/TestConnPoolWeb/sybase_pool.jsp,结果:SYBASE_JNDI:FromTest
运行:http://localhost:9080/TestConnPoolWeb/mysql_pool.jsp,结果:MYSQL_JNDI:FromTest

2. 程序说明

得到连接的方法:

private static Connection getConnection(String strConnPoolJndi) throws NamingException, SQLException {
Context ctx = null;
ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup(strConnPoolJndi);
Connection conn = ds.getConnection();

return conn;

}

参数strConnPoolJndi分别为:ORACLE_JNDI、SQLSERVER_JNDI、SYBASE_JNDI、MYSQL_JNDI,对于相应的数据库。
从表中查询一条数据:

public static String getDBData(String strConnPoolJndi) {
String strReturn="";
Connection conn = null;
Statement st = null;
ResultSet rs = null;

try {
conn = getConnection(strConnPoolJndi);
st = conn.createStatement();
rs = st.executeQuery( "select C1 from TEST" );

if (rs.next()) {
strReturn = rs.getString(1);
}

}
...

jsp中打印出表中的一条记录:

<%
out.println("ORACLE_JNDI:" + test.pool.TestPool.getDBData("ORACLE_JNDI"));
%>


附件TestConnPoolWeb.ear(包括源程序)
posted @ 2007-03-28 11:08 edsonjava 阅读(1676) | 评论 (0)编辑 收藏
 
1.环境 sun jdk1.4.2,eclipse3.1 MyEclipse 4.0
2.介绍:MyEclipse配置Websphere6的时候需要做比配置其它server更多的工作;
        Websphere6必须和MyEclipse安装在一个机器上;
        Websphere6必须使用IBM的jdk,位置在<was-install-dir>/java;
        只有MyEclipse Enterprise J2EE project可以部署在Websphere6上。
3.Websphere6安装和配置
第一步 点击创建概要表(profile);
第二步 输入概要表名称(例如 MyEclipse);
第三步 选择概要表路径 D:\IBM\WebSphere\AppServer\profiles\MyEclipse;
第四步 输入结点名:MyEclipseNode,主机名:127.0.0.1;
第五步 输入端口号,默认端口即可;
第六步 不选做为windows服务;
第七步 完成;
第八步 启动服务器,打开管理控制台;
第九步 点击服务器-应用服务器,然后点击服务器名称;
第十步 查看标签“配置”->故障诊断->记录和跟踪;
第十一步 点击“JVM日志”->配置标签,修改“文件名”为console,点击确定;
第十二步 提示已更改了您的本地配置。单击“保存”应用对主配置的更改,点击“保存”,下一页再点“保存”;
第十三步 推出管理控制台,停止服务器;
4.MyEclipse配置
第一步 配置 Window > Preferences > MyEclipse > Application Servers > WebSphere 6;
第二步 配置JDK JRE home directory 为 /java,WebSphere只能运行在IBM JDK上;
        (WebSphere is known to run on a heavily modified IBM JDK and running it with Sun's JDK, JRockit, GCJ or other JDKs simply will not work)
第三步 创建 Web project 例如“IBMTestWeb”,再创建 Enterprise project 例如“IBMTest”;
第四步 部署 必须点击菜单条上的部署的快捷方式 Deploy MyEclipse J2EE Project to Server;

(MyEclipse Deployment Manager must be launched by clicking the button on your toolbar as shown in the screenshot below)
第五步 部署 IBMTest,选择第二项“Packaged Archive” 部署-完成;
第六步 在MyEclipse中启动 Websphere6,等待出现“为电子商务开放服务器 server1”,即启动完成;
(wait for the Server server1 open for e-business message as before.)
第七步 打开Websphere6的管理控制台 应用程序->安装新的应用程序,选择
           D:\IBM\WebSphere\AppServer\profiles\MyEclipse\installableApps\IBMTest.ear,点击下一步;
第八步 选择“启用类重新装入,点击下一步;
第九步 选中 “IBMTestWeb.war”,点击下一步 ;
第十步 选中 “IBMTestWeb.war”,点击下一步 ;
第十一步 提示“应用程序 IBMTest 安装成功。”后,点击  “保存到主配置”,最后启动该应用程序;
第十二步 删除以前部署的包,重新部署 IBMTest,选择第一项“Exploded Archive”,下面选择“Delete remote resource before deployment” 部署-完成;


 最终访问http://127.0.0.1/IBMTestWeb/index.jsp  这样就可以实时调试,实时更新了
posted @ 2007-03-28 10:41 edsonjava 阅读(669) | 评论 (0)编辑 收藏
 

摘自 IBM WebSphere 开发者技术期刊

引言

Spring 和 Hibernate 是两个开放源代码项目,有些客户可能有兴趣使用它们。本文描述如何配置这些框架,以便与 WebSphere Application Server 一起在各种场景中使用。不过,本文不是对某一框架的认可或推荐。IBM 也不直接支持其中任何一个开放源代码项目。IBM 支持有限制地使用这些应用程序框架(如下面所述),就像它支持在 WebSphere Application Server 上运行的任何客户的应用程序一样。本文还描述一些不支持的场景,在 WebSphere Application Server 和堆栈产品中应该避免此场景。





回页首


产品和客户技术支持

一个用户理应关注的问题是那些使用开放源代码的项目所获得的支持,以及使用开放源代码对供应商支持其许可产品的影响。IBM 了解某些客户可能希望将非 IBM 的框架和 IBM WebSphere Application Server 结合使用,并且在为客户提供一些信息,以促进他们为 IBM WebSphere Application Server 创建最可靠的操作环境。IBM 考虑了客户安装的开放源代码和应用程序框架,它们或者绑定为应用程序的一部分,或者作为共享库成为应用程序代码的一部分。在使用开放源代码项目时通过谨慎地利用此信息,客户可以满怀信心地使用 IBM 产品,并继续访问 IBM 产品和技术支持。如果在将这些框架与 WebSphere 产品结合使用时遇到问题,IBM 将尽力确保 WebSphere 产品不出现问题。

如果客户认真研究了本文中的建议,并记住避免和理解以下几个关键点,则预期可以安全地在 IBM 产品上使用 Spring 和 Hibernate 之类的框架:

  • 客户必须确保按 WebSphere Application Server 允许的方式使用这些框架。具体说来,这意味着客户在使用内部产品接口时,不应使用框架——遗憾的是,许多开放源代码框架在未经认真配置的情况下就这样使用了。客户应避免在 WebSphere 上明确记录应避免的场景。

  • 对于开放源代码框架,客户应该确保理解并能够访问他们与 WebSphere Application Server 一起使用的框架的匹配源代码和二进制。

  • 建议客户从开放源代码社区或使用开放源代码社区的合作伙伴那里获取框架的补救性服务。

有关 IBM 支持和策略的详细信息,请参考 IBM Support HandbookWebSphere Application Server Support Statement

尽管在开放源代码环境中使用 WebSphere Application Servers 时按照本文的建议做法有助于增强您的体验,但本文并没有列出开放源代码组件影响 WebSphere Application Server 操作或其他组件操作的所有情况。使用开放源代码的用户务必检查所有组件的规范,以避免出现许可、支持和技术问题。

在本文的剩余部分中,当使用术语“支持”或“受支持”时,描述的用法仅限于使用 IBM 有文档记录的功能。作者已尽了最大努力来提供有关如何配置和使用这些框架的建议,以确保其用法与记录的产品行为一致。





回页首


Hibernate

Hibernate 是传统的 Java™ 对象 (POJO) 的开放源代码持久性框架,它通过 XML 配置文件提供 POJO 到关系数据库表的与对象相关的映射。Hibernate 框架是应用程序调用的、用于数据持久性的数据访问抽象层。此外,Hibernate 还提供了从 Java 类到数据库表(以及从 Java 数据类型到 SQL 数据类型)的映射以及数据查询和检索功能。Hibernate 生成必需的 SQL 调用,还负责结果集处理和对象转换。

Hibernate 由 Gavin King(Hibernate 项目的奠基人)领导的软件开发团队开发,目的是解决 EJB 2.x 实体 EJB 中存在的诸多缺陷。Hibernate 与 JBoss Group 紧密关联,这是由于 JBoss 雇佣了大量的一流 Hibernate 开发人员的结果。最近,在 Java Community Process (JCP) 中的持久性框架的发展中已涉及 Hibernate,并且 Hibernate 的许多概念已合并到 Java Persistence API (JPA) 规范中。最新版本的 Hibernate 将发展为符合 JPA 规范。JPA 似乎将成为主要的 Java 持久性 API。具体说来,JPA 是 Java EE 5 必要部分。(有关如何使用 Hibernate 的 developerWorks 文章,请参见参考资料。)

尽管下文的描述中支持在 WebSphere Application Server 上使用 Hibernate,但是 IBM 并不直接支持 Hibernate。任何人使用 Hibernate 时都需要按 Hibernate Project Support page 的描述获取对它的支持。客户应该保留与开源项目相关的源数据,以用于问题调试。

使用场景

以下场景描述了有关如何将 Hibernate 与 WebSphere Application Server 和 WebSphere 堆栈产品结合使用的一些可能场景。这些仅是示例场景,不应认为是推荐的场景。前文已提到,客户应该保留与开源项目相关的源数据,以用于问题调试

使用 WebSphere Application Server 数据源

为使 Hibernate 从 WebSphere Application Server 获取数据库连接,必须使用 Java EE(以前称为 J2EE)规范中强制规定的资源引用。这可以确保 WebSphere Application Server 能够为连接池、事务语义和隔离级别提供正确的行为。通过设置 hibernate.connection.datasource 属性(在 Hibernate 配置文件中进行了定义)将 Hibernate 配置为从 WebSphere Application Server 检索数据源,以引用在模块的部署描述符中定义的资源引用(例如 java:comp/env/jdbc/myDSRef)。例如:

<property name="hibernate.connection.datasource">
	java:/comp/env/jdbc/myDSRef
</property>

Web 应用程序的 Java EE 资源引用在 WAR 文件级别定义,这意味着容器中的所有 Servlet 和 Java 类均共享资源引用。在 EJB 模块内部,资源引用在各个 EJB 组件上定义。这意味着,如果许多 EJB 组件都使用相同的 Hibernate 配置,则每个 EJB 必须在每个 EJB 组件上定义相同的引用名称。这会导致复杂的情况,稍后我们将进一步讨论。

配置了数据源之后,确保 Hibernate 正常工作的下一个步骤是正确配置事务支持。

事务策略配置

为了正确地使用事务,Hibernate 需要两个重要部分的配置。第一个部分是 hibernate.transaction.factory_class,它定义事务控制,第二个部分是 hibernate.transaction.manager_lookup_class,它定义注册事务同步的机制,这样,当持久性管理器需要与数据库同步更改时会在事务端得到通知。对于事务控制,同时支持容器管理的配置和 Bean 管理的配置。将 Hibernate 和 WebSphere Application Server 结合使用时,必须在 Hibernate.cfg.xml 中设置以下属性:

  • 对于容器管理的事务:

    <property name="hibernate.transaction.factory_class">
    	org.hibernate.transaction.CMTTransactionFactory
    </property>
    <property name="hibernate.transaction.manager_lookup_class">
    	org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
    </property>

  • 对于 Bean 管理的事务:

    <property name="hibernate.transaction.factory_class">
    	org.hibernate.transaction.JTATransactionFactory
    </property>
    <property name="hibernate.transaction.manager_lookup_class">
    	org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
    </property>
    <property name="jta.UserTransaction">
    	java:comp/UserTransaction
    </property >

jta.UserTransaction 属性将工厂类配置为从 WebSphere 容器获取 UserTransaction 对象实例的实例。

WebSphere Application Server V6.x 和更高版本在 WebSphere 平台上支持 hibernate.transaction.manager_lookup_class 属性,WebSphere Business Integration Server Foundation V5.1 和更高版本也支持此属性。此属性将 Hibernate 配置为使用在 WebSphere Business Integration Server Foundation V5.1 和 WebSphere Application Server V6.0 中引入的 ExtendedJTATransaction 接口,WebSphere ExtendedJTATransaction 接口建立了一个模式,并通过 JTA 1.1 规范在 Java EE 5 中正式确立。

WebSphere Application Server 环境中 Hibernate 的使用模式

当结合使用 Hibernate 和 WebSphere Application Server 时,Hibernate 的“按请求会话”和“长对话”模式均可使用。客户必须选择适用于其应用程序的模式,不过我们主张使用“按请求会话”模式,因为它可以提供更好的扩展性。

  • 多个隔离级别

    可共享的连接通过让多个资源用户能够共享现有的连接,改进了在 WebSphere Application Server 中的性能。不过,如果可共享的连接和多个隔离级别都是必需的,则为每个连接配置定义单独的资源引用和 Hibernate 会话工厂。不能够更改共享连接的隔离级别。因此,也不可能使用 hibernate.connection.isolation 属性在共享连接上设置隔离级别。有关连接共享的策略和约束的详细信息,请参见 在 WebSphere Application Server V5 中共享连接。(尽管本文通常适合于在 WebSphere Application Server V5 上使用的所有共享连接,但是连接共享建议仍适用于在 V6.x 上运行的 Hibernate。)

  • Web 应用程序

    可以在 HttpSession 对象中使用和存储 Hibernate 的“长对话”会话;不过,Hibernate 会话持有活动实例,由于可能需要将会话序列化或将其复制到其他集群成员,因此将其存储在 HttpSession 中不是可扩展模式。最好使用 HttpSession 来存储断开连接的对象(只要它们非常小,即 10KB 到 50KB),并且在需要更新时,重新将它们与新的 Hibernate 会话关联。这是因为 HttpSession 最适用于书签,而不适用于缓存。在 Improving HttpSession Performance with Smart Serialization 中讨论了如何使 HttpSession 的内存使用率降至最低。不是将 HttpSession 用作缓存,而是考虑使用 ObjectGrid 或 DistributedObjectCache 之类的 WebSphere 数据缓存技术,这在下一部分进行介绍。

有关高性能、可扩展应用程序的最佳实践,强烈建议您阅读 Performance Analysis for Java Websites 一书。

集成二级缓存

Hibernate 会话表示工作单元的范围。在 Hibernate 会话的生命周期中,Session 接口管理持久性。通常,它通过保持对单一线程有效的一级缓存实例并维护它负责的映射实体类实例的识别或状态做到这一点。在完成工作单元(会话)时释放缓存。还可以将二级缓存配置为在 SessionFactory 的所有会话之间共享(包括在群集之间共享)。请注意,在 Hibernate 中进行缓存会导致一些需要解决的问题。第一,对于数据库的外部更改或跨群集更改,无法确保缓存的一致性(除非使用识别群集的缓存)。第二,其他层(如数据库)可能已经缓存,从而使 Hibernate 缓存的值降至最低。在进行应用程序设计时,必须认真考虑这些问题,但是这些问题超出了本文的讨论范围。

在发布时,没有确定与 WebSphere Application Server 相关的 Hibernate 群集识别缓存的行为,因此,还不能确定是否支持该行为,我们对此不做进一步的讨论。所以,需要分布式缓存的客户应当考虑创建使用属性 hibernate.cache.provider_class 实现 org.hibernate.cache.CacheProvider 的类,这会在 WebSphere 中使用两个分布式缓存实现中的一个。

Hibernate 附带了几个预配置的缓存。在 Hibernate Cache 文档页中可以找到关于这些缓存的信息。对于只读数据,一个内存缓存可能就足够了。不过,当聚集应用程序并需要群集识别缓存时,本地只读缓存是不够的。如果需要分布式缓存,我们建议使用 WebSphere 提供的分布式缓存实现之一。可以将它们用作 Hibernate 的二级缓存:

在 WebSphere Enterprise Service Bus 和 WebSphere Process Server 中使用 Hibernate

WebSphere Process Server 和 WebSphere Enterprise Service Bus (ESB) 将 Service Component Architecture (SCA) 和 Service Data Objects (SDO) 用作 SOA 的装配和编程模式。(请参见参考资料,了解关于 SCA 和 SDO 的更多信息。)SCA 组件不是 Java EE 组件,因此它们没有资源引用,但是改为依靠服务和适配器来连接系统。在构建 Java SCA 组件时,不能使用资源引用;因此,SCA 组件不能直接使用 Hibernate。

在这种情况下,应将 Hibernate 持久性隐藏在某种 Facade 后面。有两个备选方案:

  • 创建本地 EJB 会话 Facade 以包装 Hibernate 持久性。会话 Facade 提供适配器逻辑,以便将 Hibernate 实体 POJO 映射到服务数据对象并返回。然后集成开发人员可以使用 EJB 导入调用会话 Facade,并以紧密耦合方式使用对应的服务质量 (QoS) 调用它。

  • 创建 EJB Web 服务会话 Facade 以包装 Hibernate 持久性。然后集成开发人员可以使用 Web 服务导入调用持久性的 Web 服务。这不需要构建 POJO 到 SDO 的转换程序,由于目前 SCA 对数据类型只使用 SDO。图 1 说明了使用两个模式的业务流程,但该流程的详细信息不在本文的讨论范围之内。


图 1. 示例业务流程
图 1. 示例业务流程

WebSphere Application Server V6.1 上的 Hibernate JPA API

Hibernate 的 JPA 支持提供 JPA 标准持久性,并且是专有 Hibernate API 的较好备选方案。Hibernate 的 JPA 实现需要基于 Java EE 5 的运行时,因此,它仅在 WebSphere Application Server V6.1 或更高版本上运行。在发布时,Hibernate 的 JPA 支持不能在 WebSphere z/OS 和 iSeries 平台上运行。Hibernate 文档描述了如何使用 Hibernate 的 JPA 实现包装和部署应用程序。

避免的场景

以下各部分将描述不支持的配置和用例。这仅表示当前已确定的不支持的场景。其他不支持的场景将在以后确定。

不支持的事务配置

Hibernate 文档描述了用于在 WebSphere Application Server 版本 4 和 5 产品上运行的事务策略配置,但是这些配置使用内部 WebSphere 接口,在那些早期版本上不受支持。在上面的事务策略配置部分中描述了 Hibernate 唯一支持的事务配置。正如前面所述,这意味着仅在 WebSphere Application Server V6.x 之后(包括 V6.x)的版本和 WebSphere Business Integration Server Foundation V5.1 上支持使用 Hibernate。

不可交互操作的/不可移植的功能

JPA 规范中的 3.2.4.2 部分描述了可能导致互操作性和潜在的可移植性问题的情况。这与结合使用延迟加载(即 @Basic(fetch=LAZY))和分离对象有关。将分离对象合并回会话时,JPA 将检查该对象,并使用任何更改值来更新数据存储。不过,数据对象是简单的 POJO。在分离时,如果部分 POJO 状态没有加载,则在合并回去时可能显示为已更改。要使它正常工作,供应商必须实现特定于其运行时的序列化技术。这不是互操作的,语义也不能移植。





回页首


Spring

通常将 Spring 描述为轻量级容器环境,但是将其描述为用于简化开发的框架可能更适当。其主要概念是使用依赖项注入 (DI) 和面向方面的编程 (AOP) 来简化和平稳地进行从开发到测试再到生产的转换。

Spring 框架是一个流行的开放源代码框架,它由 Interface21, Inc. 根据 Rod Johnson 发表的关于依赖项注入 (DI) 的设计模型开发。Spring 可以在独立应用程序或应用服务器中使用。由于 Spring 提供的一些服务通常由应用服务器运行时提供,所以需要认真设计 Spring 与应用服务器的结合使用,以避免在 Spring 实现和应用服务器提供的实现之间发生冲突。

本部分其余内容将描述使可能发生的实现冲突或矛盾点降至最低的用例,还将描述应避免的其他矛盾点(如果可能)。

尽管下文的描述中支持在 WebSphere Application Server 上有限使用 Spring,但是 IBM 并不直接支持 Spring。任何人使用 Spring 时都需要按 Spring Product Support page 的描述获取对它的支持。客户应该保留用于帮助调试问题的与开放源代码项目相关的源。

使用场景

以下部分将描述 Spring 在 WebSphere Application Server 上的一些使用场景。不过,应由客户负责确定这些场景是否适合他们的具体情况。IBM 不支持、也不建议使用 Spring。本文仅演示在 WebSphere Application Server 上使用 Spring 的一组场景,并演示必须如何自定义 Spring 才能与 WebSphere Application Server 一起运行。

简单的 Bean 逻辑容器

使用 Spring 的最常用的场景之一是使用简单的 Java Bean 类配置并驱动业务逻辑。本文稍后描述的避免了问题的 Spring 应用程序在 WebSphere Application Server 中运行时不应该有任何问题。Spring documentation page 应提供了使用 Spring Bean 构建应用程序的足够信息。此处不存在任何特定于 WebSphere 的内容。

在 WebSphere 中使用 Spring DAO 框架

下面是关于在 WebSphere Application Serveruse 上使用 Spring DAO 功能的三个示例:

  • 基本型 DAO 用法

    WebSphere Application Server 管理在应用服务器执行环境中使用的资源。需要访问 JDBC 数据源之类资源的 Spring 应用程序应该利用 WebSphere 管理的资源。为此,需要执行以下若干步骤。

    1. 在开发过程中,应该使用资源引用配置 WAR 模块。例如:

      <resource-ref>
      	<res-ref-name>jdbc/springdb</res-ref-name>
      	<res-type>javax.sql.DataSource</res-type>
      	<res-auth>Container</res-auth>
      	<res-sharing-scope>Shareable</res-sharing-scope>
      </resource-ref>
      

    2. 对于 EJB JAR 文件,应该在需要访问数据源的每个 EJB 中声明同一资源引用。

    3. 然后使用与以下类似的内容在 Spring 配置文件中声明数据源 Bean:

      <bean id="WASDataSource" 
          class="org.springframework.jndi.JndiObjectFactoryBean">
      	<property name="jndiName" 
      		value="java:comp/env/jdbc/springdb"/>
      	<property name="lookupOnStartup" 
      		value="false"/>
      	<property name="cache" 
      		value="true"/>
      	<property name="proxyInterface" 
      		value="javax.sql.DataSource"/>
      </bean>

      这将配置 Bean,以便从模块的配置引用查找数据源。注意,jndiName 属性值匹配与资源引用中声明的资源引用名称连接的模式 java:comp/env/

    4. 然后,Spring 应用程序可以在适当情况下使用数据源 Bean。

    5. 将应用程序部署到 WebSphere Application Server 时,必须配置资源提供程序和资源数据源,以便由 Spring 应用程序资源引用使用。在部署过程中,在模块的部署描述符中声明的资源引用将绑定到应用服务器的配置数据源。

  • 事务型 DAO 用法

    在 Spring 中,有许多方法可以驱动事务控制下的资源更新。这包括编程形式和声明形式。声明形式有注释形式和非注释形式。在使用 Spring 事务支持时,获得权限的重要方法是适当地配置 Spring 对底层事务管理器的使用。在 WebSphere Application Server 中,Spring 使用的事务管理器的唯一支持形式如下:

    <bean d="transactionManager"
    class="org.springframework.transaction.jta.JtaTransactionManager">
    	<property name="autodetectTransactionManager"
    		value="false"/>
    </bean>

    可以将此事务管理器 Bean 提供给 JdbcTemplate 类,或通过事务策略的声明形式利用。有关为什么这是唯一形式的详细信息,请参见避免的场景部分。

  • 休眠型 DAO 用法

    Spring 记录将 Hibernate 和 Spring 一起使用的基本设置。在 WebSphere Application Server 环境中使用 Hibernate 和 Spring 时,有必要将上述对二者的配置要求合并在一起。正如前面所述,在 Spring 和 Hibernate 中使用 JNDI 访问事务管理的资源和适当配置是必要的。

Spring Web MVC

Spring 的 Web MVC 框架在某一时间内一直是其他框架的备选框架。由 WebSphere Application Server 提交、使用和支持的 Web MVC 框架包括 JSF 和 Struts。Spring 参考手册描述了如何将 Spring 与这些 Web 框架集成。尽管 WebSphere Application Server 支持上面的任何用法,但 IBM 仅为 WebSphere Application Server 附带的框架提供缺陷支持。

计划和线程池

如果需要异步运行代码,那么应该使用 WorkManagerTaskExecutor。在 Spring 中,这是唯一使用由 WebSphere Application Server 托管的线程池的 TaskExecutor 实现。其他 TaskExecutor 实现可以启动非托管线程。有关非托管线程的详细信息,请参见避免的场景

在 WebSphere Application Server 管理控制台中,通过导航到 Resources => Asynchronous beans => Work managers 可以对 WorkManager 进行设置。然后可以在 Spring 配置文件中使用资源的 JNDI 名称来定义 WorkManagerTaskExecutor。

Spring Portlet

Spring Portlet 可以在 WebSphere Portal V6.0 和 WebSphere Application Server V6.1 Portlet 容器中运行。有关 Spring Portlet 的示例集,请参见 Spring Portlet MVC。在 WebSphere Application Server V6.1 Portlet 容器中运行 Portlet 需要创建其他 Web 应用程序才能定义 Portlet 的布局和聚合。从 WebSphere Application Server 信息中心可以获得关于如何使用 Portlet 聚合器标记库的信息,在文章 探索 WebSphere Application Server V6.1 Portlet 容器: 第 1 部分:Portlet 容器介绍 中的其他补充信息中也可找到。

通常结合使用 JSF 和 Portlet 进行呈现。关于如何将 Spring、Hibernate、JSF 和 WebSphere Portal 组合起来运行的信息可以通过文章 Configuring Hibernate, Spring, Portlets, and OpenInSessionViewFilter with IBM WebSphere Portal Server 了解。

避免的场景

已经知道以下场景在 WebSphere Application Server 环境中会出现问题,应该避免它。列出这些场景的原因有许多,不过,最常见的原因是 Spring 使用了内部 WebSphere 接口。这些内部接口的使用破坏了 WebSphere Application Server 保证应用程序环境的完整性和管理应用程序资源的能力。应该避免使用任何依赖于内部 WebSphere 接口的 Spring 功能。

REQUIRES_NEW 和 NOT_SUPPORTED 事务策略

WebSphere Application Server 为维护数据完整性提供了可靠的环境。它提供此环境的方法之一是始终确保应用程序逻辑在事务范围内执行。在容器将要执行业务逻辑时,它会检查事务状态。如果全局事务不是动态的,则容器会创建并管理新的 local transaction containment (LTC) 范围。容器将在业务逻辑结束时完成 LTC,并在任何应用程序启动的全局事务过程中将它挂起。这可以确保在业务逻辑执行结束时总是正确地清除资源。

Spring 为管理事务提供了机制。不过,它支持的事务策略超出了通常可以在应用程序级别处理的策略集的范围。具体说来,它为 REQUIRES_NEW 和 NOT_SUPPORTED 的 EJB 容器管理的语义提供它自已的等效支持。这两个容器管理的策略都需要挂起和恢复事务的功能,但是为使用 EJB 容器而保留了此功能(不适当的使用会导致数据完整性问题)。为提供此行为,Spring 使用了内部 WebSphere 接口,但不知道它对容器的影响。使用内部接口挂起和恢复事务将破坏 Web 和 EJB 容器管理资源和 LTC 的功能,并可能使容器处于未知状态,从而可能导致数据损坏。

以下两个步骤可以避免此场景:

  • 不使用需要挂起和恢复语义的 Spring 事务策略。
  • 不配置 Spring JtaTransactionManager 使其支持挂起和恢复语义。

第一是应用程序设计时间限制。如果您构建应用程序,请不要在语义中设计需要使用 Spring 来挂起和恢复事务。如果需要挂起和恢复语义,请改为使用无状态会话 EJB。

第二是部署时间配置约束。如果在 WebSphere Application Server 中部署基于 Spring 的应用程序,则该应用程序在尝试使用 Spring 的挂起和恢复语义时将会失败。以这种方式失败比随机数据损坏错误要好得多。下面是必须在 WebSphere Application Server 中配置 Spring JtaTransactionManager 的正确方法:

<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
	<property name="autodetectTransactionManager" 
		value="false"/>
</bean>

这将把 transactionManager Bean 配置为使用 UserTransaction API 来控制事务的开始、提交和回滚。这使得可以不使用挂起和恢复语义来支持事务控制。

上面所述的 Spring JtaTransactionManager 用法不支持与现有事务同步的 Spring 注册功能。要做到这一点,需要使用 WebSphereTransactionManagerFactoryBean。使用 WebSphereTransactionManagerFactoryBean 的客户或调用内部事务管理器接口的任何其他类将不受支持。

JDBC 本机连接

当各种 JDBC 操作需要与本机 JDBC 资源交互时,Spring 可提供访问本机连接的机制。当在 JdbcTemplate 类上设置了 NativeJdbcExtractor 类时,JdbcTemplate 类才可以利用此功能。设置 NativeJdbcExtractor 类后,当与 WebSphere Application Server 一起使用时,Spring 总是向下找到本机 JDBC 连接。这将忽略以下 WebSphere QoS 功能和优点:

  • 连接处理跟踪和再关联
  • 连接共享
  • 事务状态
  • 池管理
  • 最后的代理事务参与。

这带来的另一个问题是 WebSphereNativeJdbcExtractor 类将依赖于内部 WebSphere 适配器类。这些内部类可能因 WebSphere Application Server 的版本而异,并且以后可能更改,从而中断依赖于此功能的应用程序。

在 WebSphere Application Server 上不支持使用 NativeJdbcExtractor 类实现(例如 WebSphereNativeJdbcExtractor),客户应避免需要它的场景。备选方案是使用 WebSphere Application Server WSCallHelper 类来访问非标准供应商的数据源扩展。

类加载器的缺点

Spring 和 WebSphere Application Server 都使用多个开放源代码项目,遗憾的是,它们共有的项目版本并不总是匹配。应该将 Spring 依赖项包装为应用程序的一部分,并且应该按照下面的描述设置服务器以避免冲突。否则,类加载器可能无法为运行时或应用程序加载适当的版本。通常,这将导致在日志中出现有关类的版本不匹配、ClassCastExceptions 或 java.lang.VerifyErrors 等异常。

其中一个示例是使用 Jakarta Commons Logging。配置供应用程序使用的 Jakarta Commons Logging (JCL),或者使用不是由应用服务器提供的其他版本的 JCL(例如,使用应用程序代码嵌入的 JCL)需要在 WebSphere Application Server 上进行特定的配置。有关如何配置部署的应用程序,以使用内嵌版本的常用技术的策略,请参见 Integrating Jakarta Commons Logging。请关注支持网站,了解是否提供了如何在 WebSphere Application Server V6.x 产品上配置内嵌 JCL 的更新。这仅仅是冲突的一个示例。其他示例可能包括应用程序使用的 JDOM 或特定版本的 JavaMail。不支持将 WebSphere Application Server 的 JAR 文件替换为这些或具有更高版本或不同版本的其他包。

在 WebSphere Application Server 上困扰 Spring 用户的另一个类加载器问题是 Spring 加载资源的方法。资源可以包括消息绑定之类的内容,通过类加载器层次结构和在层次结构中查找资源的各种策略,能够在非目标位置找到使用公共名称的资源。可以使用 WebSphere Application Server 类加载器查看器来帮助解决此问题。合并资源和包括其他版本的公共库可能需要应用程序将资源重命名为唯一的名称。

非托管线程

某些 Spring 场景可能导致创建非托管的线程。非托管线程对 WebSphere Application Server 是未知的,并且不能访问 Java EE 上下文信息。此外,它们可以在 WebSphere Application Server 不知道的情况下利用资源,存在管理员不能控制其数量和资源使用情况的问题,在发生故障时,它们还阻止应用服务器正常关机或恢复资源。应用程序应该避免导致启动非托管线程的任何场景:

  • registerShutdownHook

    第一种场景是在使用 Spring AbstractApplicationContext 或它的一个子类时。registerShutdownHook 是一个公共方法,它可以创建线程并将其注册到 Java 虚拟机,以便在关机时运行以关闭 ApplicationContext。应用程序可以避免这一点,方法是利用从 WebSphere 容器接收的常规生命周期通知来显式调用 ApplicationContext 上的关闭。

  • 入站 JMS 消息

    Spring JMS MessageListenerContainer 类利用启动非托管线程(例如 SimpleAsyncTaskExecutor)的类来侦听传入的 JMS 消息。Spring JMS 容器不仅可以启动非托管线程,而且还可以使用无法由 Java EE 环境中的应用程序调用的 JMS API。(有关详细信息,请参见 Java EE 规范 J2EE.6.6 部分。)

    可以使用 Spring 远程处理 API 生成 JMS 消息,但是客户应该使用消息驱动的 Bean 处理传入的消息,避免使用 Spring JMS MessageListenerContainer。这可以使用容器适当地控制和恢复资源和事务。

  • JMX 服务器

    应用程序应避免使用 Spring JMX ConnectorServerFactoryBean,它是启动非托管线程的另一个类。WebSphere Application Server 已经向 JMX 服务器提供了多个受支持的连接器协议。应用程序可以向 WebSphere Application Server 的 JMX 服务器注册 MBean,并对它们进行远程访问。

  • 非集成的计划包

    Spring 提供或集成了大量的计划包。只有与 WebSphere Application Server 托管的线程一起使用的 Spring 计划包是 CommonJ WorkManager 计划包。其他包(如 quartz 和 JDK Timer)会启动非托管线程,应该避免使用。

  • WeakReferenceMonitor

    Spring 为简化开发 EJB 组件提供了方便的类。请注意,这些方便的类会生成 WeakReferenceMonitor 用来执行清除操作的非托管线程。





回页首


结束语

如果经过充分考虑避免了问题场景,则可以在 WebSphere 平台上以完全支持的方式使用 Hibernate 和 Spring。尤其是,客户必须确保他们使用这些框架不涉及使用内部 WebSphere 接口。获得 IBM 的 WebSphere Application Server 支持的用户如果在将 WebSphere Application Server 和 Spring 或 Hibernate 一起使用时遇到问题,可以获得 IBM 的帮助来诊断问题,除非问题被确认为使用了不支持的场景,或不是 WebSphere Application Server 的问题。客户应该按照相应项目网络上的说明自行从其他公司获得对 Hibernate 和 Spring 框架的支持。


posted @ 2007-03-27 17:17 edsonjava 阅读(453) | 评论 (0)编辑 收藏
 
下载mysql jdbc 驱动

1.建立用户自定义配置jdbc提供程序 (!!!)
配置类路径指向 mysql jdbc driver jar file
实现类名为:com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource

2.建立数据源
设置jndi名等职


3.定制连接池属性(!!!)
自定义下列名称和值
名称    值
databaseName schemaname?autoReconnect=true
factory com.mysql.jdbc.jdbc2.optional.MysqlDataSourceFactory
password password
port 3306   
serverName localhost  
user username  
4.重启应用服务器,测试连接
posted @ 2007-03-27 16:59 edsonjava 阅读(703) | 评论 (0)编辑 收藏
 

 



  轻量级的企业应用开发越来越受到广大J2EE应用开发者的追捧,而Spring框架又是轻量级容器的杰出代 表。由于Spring的使用日渐广泛,因此已有许多基于WebSphere应用服务器(WAS)的应用采用了Spring框架。本文首先介绍使用 Spring开发Web应用的基本问题,然后结合WebSphere应用服务器,讲述Spring应用如何结合容器提供的服务。文章目的是与大家一起探讨 如何更好的采用Spring框架开发基于WebSphere应用服务器的应用。

  1、Spring框架的主要思想描述

   Spring框架的核心思想我们可以用两个字来描述,那就是"解耦"。应用程序的各个部分之间(包括代码内部和代码与平台之间)尽量形成一种松耦合的结 构,使得应用程序有更多的灵活性。应用内部的解耦主要通过一种称为控制反转(IOC)的技术来实现。控制反转的基本思想就是本来由应用程序本身来主动控制 的调用等逻辑转变成由外部配置文件来被动控制。通常我们用一个所谓的好莱坞原则(Don't call me. I will call you.)来比喻这种控制反转的关系。由于控制反转的概念相对比较广泛,很多应用服务器实际上也实现了不同程度的控制反转技术,只是这些应用服务器对应用 程序的侵入性太强。因此Martin Fowler专门写了一篇文章讨论控制反转这个概念,并提出一个描述更为准确的概念,叫依赖注入(Dependency Injection)。

   Spring框架中的各个部分都充分使用了这种依赖注入的技术实现,从而给应用以最大的灵活度。实际上,这种依赖注入的参数化应用控制并不是 Spring的首创,比如IBM的多渠道应用整合平台(Branch Transformation Toolkit,BTT)很早就采用了这种外部参数化控制的技术。BTT中的"对象工厂"与Spring框架中的BeanFactory也有着异曲同工之 妙。

  Spring框架另外一个比较重要的技术是它对于面向切面的编程(AOP)的支持。随着应用复杂度的逐渐上升和对应用灵活性要求 的提高,IT逻辑和业务逻辑尽量分离的呼声也越来越高。AOP技术作为实现这种分离的一种比较好的途径而越来越受到大家的重视。Spring提供的是一种 动态AOP实现,也即通过代理模式动态地在目标对象的方法前后插入相应的处理代码。应用程序与底层应用服务器平台的解耦也可以借助AOP技术来实现。 Spring内置的AOP支持是一种锦上添花的功能。它使得一些本来必须由容器支持的功能,比如事务控制可以脱离开容器运行,从而达到"瘦身"的目的。这 也是为什么Spring框架常被人成为轻量级容器的一个原因。

Spring框架可以与许多已有的框架技术结合使用。J2EE技术应用的一 个重要特点是相关的开源社区非常活跃。Web应用的不同层次都有非常多优秀的开源框架存在。比如Web层的Struts,OR映射层的Hibernate 等。Spring框架并不重新发明轮子,它的出现不是为了替代这些已有的框架。相反,Spring框架在设计上可以独立构建应用或者结合已有的框架一起构 建应用。另外一个值得指出的地方是Spring框架的几大模块之间相互耦合度很小,因此Spring框架的使用可以根据实际需要选其部分模块循序渐进的使 用,而非必须统统照搬。

  2、基于Spring的Web应用基础

  2.1 Web应用的典型层次

  Web应用一般在逻辑上根据功能分为以下几层:

  1.展示层

   这一层主要如何生成展示给最终用户的界面,尽可能少的包含业务逻辑处理。对于基于J2EE的Web应用,JSP是其最为常见的一种技术。Spring对 于展示层的支持非常灵活,除了直接支持JSP之外,它还支持基于FreeMarker模板,基于Velocity模板或其它文档类型的界面等的表现层实 现。

  2.业务层

  业务层一般包含主要的业务逻辑,尤其是与用例相对应的那些业务逻辑。另外,这一层也适合包含事务管理和安全控制方面的逻辑。良好的业务层设计可以使得展示层可以采用不同的技术而不影响业务层。业务层的功能上可以类比于J2EE技术中的无状态会话BEAN层次。

  3.数据访问对象(DAO)接口层

   DAO实际上就是数据接口层,在应用中建议通过接口来体现。DAO的存在使得数据访问可以与底层持久化层的具体实现相分离。一般在DAO接口中主要就是 实现数据对象的查询、存储、删除等操作。从理论上讲,DAO层与底层数据的存储方式是独立的,也就是说并不一定要求是关系型数据库。Spring框架在设 计的时候也考虑到了其它非关系型数据库数据源的情况。

  4.持久业务对象

  持久业务对象是问题域中业务对象的持久化 表示,比如一个用户对象,一个银行帐户等。我们一般通过某种O/R映射技术来实现这些业务对象的持久化。持久业务对象是可以包含业务逻辑的,与业务层所包 含的业务逻辑不同的地方是持久业务对象所包含的是与具体业务对象直接相关且更为通用的业务逻辑。

  5.企业信息系统

  企业信息系统泛指Web应用需要连接的后台系统,一般可以分为三大类,即ERP系统,企业传统的遗留系统和关系型数据库。大部分Web应用都是基于关系型数据库的,这也是像Spring等常见框架所主要考虑的企业信息系统。

  设计良好的Web应用在层次一般是上一层依赖下一层,但是下一层不依赖上一层。我们可以暂时概括为"向下而不向上依赖原则"。为了使得不同层次之间的依赖降到最低,建议使用接口耦合。这一点又是Spring框架发挥它外部配置优势的地方。

  2.2 MVC的选择

  虽然说MVC这种模式早在Java语言出现前就有了,但是这种模式在J2EE时代才大行其道,为广大Web应用开发者所接受。对于各种基于MVC的框架而言,其要解决的问题主要可以分为以下几部分:

  1.将Web页面中的输入封装成一个数据对象,比如像Struts的表单BEAN,Spring MVC中的命令类等。

  2.根据请求的不同,由负责分发的控制器来映射和调用相应的逻辑处理单元,并将上面的数据对象作为参数传入。

  3.逻辑处理单元完成相应的处理之后又把结果放入一个数据对象。

  4.在选择的展现界面中把返回的数据对象通过某种方式显示出来。

   在使用Spring构建MVC的时候,可以选择直接使用Spring自己的MVC实现,或者利用Spring对已有的一些MVC框架的支持。比如 Spring可以支持Struts,WebWork等,与它们结合使用。Spring引以为傲的非侵入的特性在Spring MVC上表现得并不如人意。它与Servlet API的耦合度较其它部分高,而且需要使用一些Spring的接口和类。

   Spring MVC的主要分发器实现是org.springframework.web.servlet.DispatcherServlet,这是Spring MVC的访问入口。Spring提供SimpleFormController,AbstractCommandController等类来帮助应用构建 各种控制器动作,并用ModelAndView类来联系展示和逻辑返回数据。如上节所述,Spring MVC能够支持不同的界面展示技术,而且界面的展示和其后面控制器的实现是分离的,也即界面展示技术的变化不用修改控制器的实现,只需要利用Spring 的控制反转技术修改外部配置文件即可。比如,在使用JSP展示技术时,外部配置文件的viewResolver定义如下:








<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name="prefix"><value>/view/</value></property>
<property name="suffix"><value>.jsp</value></property>
</bean>


  如果切换到FreeMaker模板技术,那么除了页面模板的修改之外,主要就是把对应的外部配置文件更改一下即可,如下所示。具体的展示逻辑部分不用做什么修改。








<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.freemarker.FreeMarkerView
</value>
</property>
<property name="suffix"><value>.ftl</value></property>
</bean>
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath">
<value>/view/</value>
</property>
</bean>


   如果不使用Spring的MVC框架而想结合已有的一些MVC框架,Spring也是支持的。Spring对于常见的MVC框架都提供了支持,包括 Struts,WebWork,Tapestry和JSF等。结合使用这些框架的一个好处是可以使用一些已有的熟悉的技术,另外结合Spring的AOP 拦截器可以相对比较容易地处理框架动作共有的事情,比如动作的日志处理等。如果选择这些MVC框架,那么在使用框架的配置文件和应用的Spring配置文 件都需要做相应的修改。比如使用Struts的时候,Struts-config.xml配置文件中的映射动作类型一般会设置成 org.springframework.web.struts.DelegatingActionProxy,或者设置控制器为 org.springframework.web.struts.DelegatingRequestProcessor。然后需要在相应应的 WebApplicationContext中定义与Struts Action对应的Bean。这样就可以充分利用Spring的控制反转技术来管理Struts的Action了。

  另外在使用这些框 架的时候要解决的一个问题是上下文的装载。比如使用Struts,可以使用ContextLoaderPlugin来装载Web上下文。这个 ContextLoaderPlugin替换了原来通过DispacherServlet装载的方式。需要在struts-config.xml文件中添 加如下条目:<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"/>。这种方式可以使 Spring的Web上下文随着Struts ActionServlet的初始化而装载。

  因此,如果用户已有的应用是基于某个 MVC框架,或者用户熟悉某个框架,那么可以利用Spring对这些框架的支持结合使用。因为我们的目的本来就是为了解决问题而不是为了使用某种技术。但 是对其它用户而言,如果不是对已有的一些MVC框架比较熟悉的话,那就直接使用Spring的MVC框架就可以了。

2.3 Web Context设置

  对于不依赖于应用服务器的Spring 上下文(Context)设置,通常在应用代码中通过FileSystemXmlApplicationContext或ClasspathXmlApplicationContext来获取。比如使用这样的代码来得到上下文:








ApplicationContext ctx = new FileSystemXmlApplicationContext("config.xml");


   但是按照控制反转的原则,应用程序代码应该尽可能少的知道上下文的设置。因此,在基于Spring的Web应用中,这样的代码也可以省去。Spring 可以通过配置让Web容器自动装载上下文配置文件。从本质上讲,Web应用的ServletContext就是Spring用来存放应用上下文的地方。 Spring中与Web Context装载相关的有几个类:

  1.ContextLoaderListener:一般的应用服务器如WAS都能先装载Listener,如果不是的话,那么只能使用ContextLoaderServlet。

   2.ContextLoaderServlet:需要配置<load-on-startup>使得它率先装载。真正装载Context的类是 ContextLoader,上面两个类只是两种调用ContextLoader的不同途径。ContextLoader内部实际调用的是 XmlWebApplicationContext,其缺省配置文件为/WEB-INF/applicationContext.xml。

  如果使用ContextLoaderListener,其在web.xml中的配置一般如下:








<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>


  如果使用ContextLoaderServlet,其在web.xml中的配置一般如下:








<servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>


   应用本身可能除了基于HTTP的Web渠道之外还通过别的渠道对外提供服务,因此,一个比较好的做法是把展示相关的配置与后面业务处理部分的配置分开。 这样如果更改了应用的访问渠道,只需要修改对应的配置文件即可。因此,Spring提供了一个WebApplicationContext的概念。在 WebApplicationContext中一般包含与Web访问相关的配置定义,包括各种控制动作的定义、界面展示的定义等等。

   WebApplicationContext一般由DispatcherServlet来初始化。在上下文层次结构上可以把它看成是 ApplcationContext的子上下文。在缺省的情况下,DispatcherServlet装载的配置文件名称为其Servlet名称- Servlet.xml,但是可以通过contextConfigLocation参数来定制。DispatcherServlet在web.xml中的 定义示例如下:








<servlet>
<servlet-name>Dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/context/Webcontrollers.xml</param-value>
</init-param>


  2.4 数据持久化层

   虽然使用J2EE技术的Web应用可以连接多种不同的企业信息系统(EIS),但是毫无疑问数据库是其中最为重要和常见的一种。正因如此,Spring 对数据库访问提供了非常完备的支持。数据访问对象(DAO)模式是J2EE模式中非常重要的一种。它的主要目的是使得持久化层与业务逻辑层分离,从而屏蔽 持久化层的具体实现。我们可以把Spring的DAO支持分为两大类,一是直接基于Spring JDBC模板的数据访问,另一类是基于某种O/R映射框架的数据访问。这里刚好可以使用Spring的控制反转特性,通过外部配置文件来定义DAO接口和 实际实现类之间的关系。Spring框架目前支持的O/R映射框架包括Hibernate、JDO、TopLink、iBATIS等。

  假设我们定义了一个userDAO。当使用JDBC来实现这个DAO的时候,定义的类可以如下所示:








public class userDAOJDBC extends JdbcDaoSupport implements userDAO{ … }


  如果使用Hibernate来实现这个DAO的时候,定义的类如下:








public class UserDAOHibernate extends HibernateDaoSupport implements UserDAO { … }


  Spring对于其它的O/R映射机制都有相应的抽象类供应用使用,比如对于iBATIS有SqlMapClientDaoSupport,对于JDO有JdoDaoSupport等。

  下面我们看一下如何在Spring的配置文件中定义上述DAO与具体实现的关系。假设我们的userDAO具体实现是通过Hibernate,那么在applicationContext.xml中的一个DAO可以定义如下:








<bean id="userDAO" class="com.fgw.dao.hibernate.UserDAOHibernate">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>


   在这里我们实际DAO接口定义是:com.fgw.dao.UserDAO,而具体实现类为: com.fgw.dao.hibernate.UserDAOHibernate。显然,对于其它DAO的实现,我们只需要在配置文件中修改相应的实现类 (具体实现类当然是比不可少的)和属性即可。比如对于JDBC的DAO实现,属性就定义成相应的数据源。

  3、Spring与WebSphere应用服务器的配合

  Spring与底层J2EE应用服务器还是存在一些需要结合的地方,这里给出WAS中的一些结合点。

  3.1 使用WAS数据源

   在Java应用程序中,数据库的连接一般有两种方式来得到。一种是通过java.sql.DriverManager的方式来得到数据库连接。这种方式 不依赖于应用服务的支持,但是也不提供数据库连接池的功能。另外一种方式是通过javax.sql.DataSource的方式来得到数据库连接。在传统 基于J2EE的应用需要通过JNDI来得到数据源(javax.sql.DataSource)对象,然后再通过数据源来得到相应的数据库连接。常见的应 用服务器都支持这种方式,且一般都提供了数据库连接池的支持。虽然说我们一般推荐使用数据库连接池,但是也有一些时候我们需要脱离开应用服务器的环境使用 数据库(比如单元测试,比如应用移植等)。然而应用程序使用这两种方式的时候代码是不一样的,因此只能通过代码来应变。Spring提供了一个统一使用数 据源的解决方案,然后通过控制反转的机制用外部配置文件来指定使用的数据源。这样一方面可以统一这两种得到数据库连接的方式,另一方面也不需要像通常的 J2EE应用通过繁琐的JNDI代码来得到数据源。这样应用程序也就不需要知道使用的何种数据源。

  Spring提供了一个DriverManagerDataSource类来统一第一种方式的数据源获取。如果使用WAS中的Cloudscape数据库,用外部配置文件可配置如下:








<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.ibm.db2j.jdbc.DB2jDriver</value>
</property>
<property name="url">
<value>jdbc:db2j:D:\\DBName</value>
</property>
</bean>


  Spring提供了JndiObjectFactoryBean类来支持第二种方式的数据源获取。假设WAS中已经配置好的数据源名称为jdbc /MyDB,那么用外部配置文件可配置如下:








<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>java:comp/env/jdbc/MyDB</value></property>
</bean>
或者
<bean id="dataSource"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>jdbc/MyDB</value></property>
<property name="resourceRef"><value>true</value></property>
</bean>


   从上面配置我们可以得知,通过使用Spring,应用程序能够统一使用不同的数据源实现。如果使用环境发生变化,那么只需要修改Spring的配置文件 即可。对于部署在WAS上的Web应用,在生产环境中推荐使用WAS实现的数据库连接池。一方面是因为连接池实现地比较完善。另一方面,使用WAS提供的 数据库连接池可以很完善地支持JTA事务。

  3.2 使用WAS的JTA

  Web应用程序在使用事务的时候常常会涉 及一个事务类型的选择。是选择像JDBC事务这样的本地事务呢还是使用JTA支持的全局事务。这个与应用程序需要涉及到的事务管理器类型和个数密切相关。 Spring本身不支持分布式事务,因此分布式事务需要底层的JTA。但是Spring提供了事务的抽象,即底层真正事务实现可以切换而不影响应用程序代 码。这样应用程序可以依赖于底层WAS,也可以轻易地脱离开应用服务器的环境。这一点与前面数据源的抽象非常类似。

  WAS本身对于事 务划分有两种支持方式,一种是声明式的,当然这种管理方式需要EJB容器的支持,即所谓的容器管理事务(CMT)。另外一种方式是编程式的,通过程序代码 来直接使用JTA编程接口。Spring对于事务的划分也可以分为声明式和编程式两种方式。对于Spring编程式的事务划分方式,总体上可以分为两大 类。一类是通过直接使用实现PlatformTransactionManager接口的类。另一类是通过使用TransactionTemplate模 板类,模板类的使用可以简化事务控制代码。Spring对于声明式事务划分的支持实际上是利用了它的AOP机制。相对于编程式事务划分,这种基于AOP的 方式比较灵活,而且对代码的侵入性几乎为零。因此,如果没有特殊需要推荐使用这种事务划分方式。基于AOP的常用事务划分方式可以使用 ProxyFactoryBean加TransactionInterceptor方式,或者使用 TransactionPorxyFactoryBean的方式。前一种方式相对比较灵活,而后一种则对使用相对比较简单。

  无论是哪 一种事务划分方式,底层都需要一个事务管理机制作为支撑。如果是单一的事务资源管理器,那么根据所使用的后台事务管理资源不同的类型,可以选择的 PlatformTransactionManager实现有DataSourceTransactionManager, HibernateTransactionManager, JdoTransactionManager, PersistenceBrokerTransactionManager,和JmsTransactionManager等。无论是单个还是多个事务资 源管理器,都可以使用JtaTransactionManager类。如果使用JtaTransactionManager,那么所有事务管理实际都会委 托给底层应用服务器的JTA实现。

  例如,如果使用JDBC或iBATIS,那么我们可以使用简单的DataSourceTransactionManager,外部配置文件片断如下:








<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>


  如果使用Hibernate,那么我们可以使用HibernateTransactionManager,外部配置文件片断如下:








<bean id="transactionManager" class="org.springframework.orm.hibernate.
HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>


   使用WAS的JTA支持,我们只需要把上述对应bean中的class属性改成class属性改为 org.springframework.transaction.jta.JtaTransactionManager,然后再把属性改为 WebSphere对应的TransactionManager,参考如下:








<bean id="wasTxMgr"
class="org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean"/>
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<ref local="wasTxMgr"/>
</property>
</bean>


   通过采用Spring的事务支持,底层事务采用何种方式的决定就不必在一开始开发就做出决定。因为我们能够通过Spring的外部配置文件来进行切换真 正的事务支持。不过,虽然也有第三方的JTA支持,但是WAS能够提供非常稳定的XA支持,因此推荐使用WAS的JTA,尤其是当应用涉及到分布事务处理 的时候。这样无论应用涉及几个事务资源都可以统一解决。

  3.3 如何加载Spring的JAR包

  Spring框 架的核心JAR包是spring.jar,但是根据实际使用情况需要一些扩展JAR包和依赖JAR包。那在WAS中如何处理这些JAR包文件呢?在Web 应用中一个简单而直接的处理方式放是把这些使用到的JAR文件都拷贝到对应的WEB-INF/lib目录下面。这种方法虽然简单,但是当有多个 Spring应用程序的时候这种处理方式就需要在每个应用的WEB-INF/lib目录下都拷贝一份相同的JAR文件。这里可以通过共享库的方式来统一解 决类库共享这个问题。

  共享库就是WAS专门用来解决不同应用程序之间共享JAR或本地库文件的一种机制。共享库由一个名字、一个 JAVA类路径和/或一个装载JNI库本地库路径组成。它可以分别在单元,节点和服务器级别定义。但是共享库定义了并不意味着它会被装载,只有当这个共享 库与某个应用程序或应用服务器关联之后,它才会被加载。如果一个共享库与一个应用程序关联,那么这个共享库由应用程序类加载器加载。如果一个共享库与应用 服务器关联,那么这个共享库就需要一个专门定义的类加载器来加载。这个类加载器需要用户自己定义。其操作如下:选应用服务器比如server1'类加载器 '新建一个类加载器'加载器与共享库关联。

  在创建这个类加载器之前一般都需要预先定义好共享库。 根据上面的介绍可知,通过共享库解决Spring应用的JAR包共享问题,主要就是两个步骤。一是,把Spring应用中需要共享的JAR包定义成为一个 共享库。二是,选定相应的WAS服务器实例,把它与上面创建的共享库关联起来。这样此WAS服务器实例上的所有应用都能够使用共享库中定义的JAR包。使 用共享库这种方式的时候要注意理解类的装载次序和方式。如果是这种与WAS服务器实例关联的共享库JAR包,其类加载器在层次结构上在应用程序类加载器上 面,即是它的父加载器。关于WAS的类装载器结构和策略可以进一步参考WAS信息中心。

  4、结束语

   Spring框架的核心内容并不依赖于任何容器,但是显然基于Web的应用是Spring主要的应用类型。了解和使用Spring框架一方面可以简化应 用的开发和测试,另一方也可以加深对J2EE技术的理解。另外轻量级的Web应用开发正在成为一种趋势,因此何乐而不为之。上面所讨论的只是Spring 使用中常见的一些内容,Spring框架自己也正变得越来越复杂。当然,Spring、Hibernate等框架中体现的一些思想也正被JEE 5规范所借鉴,尤其是EJB 3中也有了控制反转的应用和POJO的大量使用。实际上无论是JEE技术标准还是Spring等框架,其目的都是如何简化企业应用的开发,只是作为标准, JEE要考虑的内容更为广泛一些,程度也更为深入一些。(源自:IBM )
posted @ 2007-03-27 16:58 edsonjava 阅读(382) | 评论 (0)编辑 收藏
 
package   com.hull.validatecode;  
   
  import   java.util.*;  
  import   java.io.*;  
  import   java.awt.*;  
  import   java.awt.image.*;  
   
  import   javax.servlet.*;  
  import   javax.servlet.http.*;  
   
  import   com.sun.image.codec.jpeg.*;  
   
  public   class   ValidateCode   extends   HttpServlet  
  {  
  private   Font   imgFont   =   new   Font("宋体",Font.BOLD,16);   //设置字体  
   
  public   void   doGet(HttpServletRequest   request,HttpServletResponse   response)  
      throws   ServletException,IOException  
  {  
  doPost(request,response);  
  }  
   
  public   void   doPost(HttpServletRequest   request,HttpServletResponse   response)    
      throws   ServletException,IOException  
  {  
  String   vCode   =   "";  
  int     intCode   =   0;  
   
   
  intCode   =   (new   Random()).nextInt(9999);  
  if(intCode<1000)    
        intCode   +=   1000;  
  vCode   =   intCode+"";  
   
  /*  
    *   绘图  
    */  
  response.setContentType("image/gif");  
  ServletOutputStream   vout   =   response.getOutputStream();  
  BufferedImage   image   =   new   BufferedImage(50,20,BufferedImage.TYPE_INT_RGB);  
  Graphics   graph   =   image.getGraphics();  
   
  //   设置背景颜色  
  graph.setColor(Color.white);  
  graph.fillRect(1,1,48,18);  
   
  //设置字体颜色  
  graph.setColor(Color.black);  
  graph.setFont(imgFont);  
   
  char   c;  
  for(int   i=0;i<4;i++)  
  {  
  c   =   vCode.charAt(i);  
  graph.drawString(c+"",9*i+4,16);    
  }  
   
  JPEGImageEncoder   encoder   =   JPEGCodec.createJPEGEncoder(vout);  
  encoder.encode(image);  
   
  //   对session赋值  
  HttpSession   session   =   request.getSession(true);  
  session.removeAttribute("VerifyCode");  
  session.setAttribute("VerifyCode",vCode);  
   
  vout.close();  
  }  
   
  }  
   
  调用:  
  <img   src="ValidateCode"   align="center">
posted @ 2007-03-13 10:55 edsonjava 阅读(413) | 评论 (0)编辑 收藏
 

现在有不少网站在用户填写表单时,同时要求填写验证码,验证码的一个目的就是防范一些恶意的网站下载软件,这些软件能通过遍历链接而将网站的所有网页下载。还可以防止用户不经过本网站的页面而使用网站的资源。所以现在有不少网站都使用了验证码技术,验证码通常是一个在 WEB 服务器上生成的随机字符串,同时以某种方式保存起来,比如保存到与当前的 Session 中,然后在用户提交网页时与用户输入的验证比较是否一致,然而如果直接以明文的方式,还是不能防范一些功能较强的自动填写表格的软件。所以一般将验证码以图片的形式显示出来,同时可以将在图片中显示的字符串进行一些处理,比如使用旋转字符,添加背景纹理等技术以增大被软件识别的难度。下面简要介绍一下如果实现这种验证码:

首先实现一个 servlet 用来生成图片(当然也可以用 jsp 实现):

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.*;

import com.sun.image.codec.jpeg.*;

import java.awt.*;

import com.sun.image.codec.jpeg.*;

import java.awt.image.BufferedImage;

import java.awt.image.DataBuffer;

import java.awt.geom.GeneralPath;

import javax.swing.*;

import java.math.*;

public class Servlet1

extends HttpServlet {

//Process the HTTP Get request

  public void doGet(HttpServletRequest request, HttpServletResponse response) throws

      ServletException, IOException {

    response.setContentType(CONTENT_TYPE);

    response.setContentType("image/jpeg");  // 必须设置 ContentType image/jpeg

    int length = 4;      // 设置默认生成 4 个数字

    Date d = new Date();

    long lseed = d.getTime();

    java.util.Random r = new Random(lseed);   // 设置随机种子

    if (request.getParameter("length") != null) {

      try {

       length = Integer.parseInt(request.getParameter("length"));

      }

      catch (NumberFormatException e) {

      }

    }

    StringBuffer str = new StringBuffer();

    for (int i = 0; i <length; i++) {

      str.append(r.nextInt(9));        // 生成随机数字

}

// 可以在此加入保存验证码的代码

    // 创建内存图像

    BufferedImage bi = new BufferedImage(40, 16, BufferedImage.TYPE_INT_RGB);

    Graphics2D g = bi.createGraphics();

    g.clearRect(0, 0, 16, 40);

    g.setColor(Color.green.CYAN);

    g.drawString(str.toString(), 4, 12);

    try {

      // 使用 JPEG 编码,输出到 response 的输出流

      JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(response.

      getOutputStream());

      JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);

      param.setQuality(1.0f, false);

      encoder.setJPEGEncodeParam(param);

      encoder.encode(bi);

    }

    catch (Exception ex) {

   

    }

  }   

}  

然后在需求显示验证码的加入以下代码就可以了

<img alt="" src="/WebModule1/servlet1"   width="40" height="16"/>

/WebModule1/servlet1 替换成你用来生成验证码的 servlet 的全路径。

 

posted @ 2007-03-12 16:37 edsonjava 阅读(216) | 评论 (0)编辑 收藏
 
JSF-Spring

This quickstart will show you how to start using JSF-Spring in a web application. It assumes you've got an existing web application. The first steps describe how to install and configure Spring and JSF. If you've got one or both of them installed already, just skip the corresponding sections.

Installing Spring

Download Spring (2.0) from http://www.springframework.org/download and extract the following jars to WEB-INF/lib:

  • dist/spring.jar
  • lib/jakarta-commons/commons-logging.jar

Then, create a basic application context

WEB-INF/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?/gt;
<!DOCTYPE beans PUBLIC
	"-//SPRING//DTD BEAN//EN"
	"http://www.springframework.org/dtd/spring-beans.dtd">
<beans></beans>

and define the listener so that Spring initializes itself on application startup:

WEB-INF/web.xml (partial)

<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Installing JSF

Download either Sun's Reference Implementation (v1.1.01) from http://java.sun.com/javaee/javaserverfaces/download.html or MyFaces (Core 1.1.4 Distribution) from http://myfaces.apache.org/download.html and copy the jars from the lib directory of the downloaded archive to WEB-INF/lib. When using Sun's Reference Implementation, you gotta make sure you've got jstl.jar in your path since the distribution doesn't provide it.

Then, create a basic faces configuration

WEB-INF/faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE faces-config PUBLIC
	"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
	"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config></faces-config>

and define the faces servlet that will start up JSF and handle all requests:

WEB-INF/web.xml (partial)

<servlet>
	<servlet-name>Faces Servlet</servlet-name>
	<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>Faces Servlet</servlet-name>
	<url-pattern>*.jsf</url-pattern>
</servlet-mapping>

Installing JSF-Spring

Download JSF-Spring (4.0) from http://sourceforge.net/project/showfiles.php?group_id=107519 and extract the following jars to WEB-INF/lib:

  • dist/jsf-spring.jar
  • dist/cglib-nodep-2.1_3.jar

Then, define the listener that initializes JSF-Spring on application startup:

WEB-INF/web.xml (partial)

<listener>
	<listener-class>de.mindmatters.faces.spring.context.ContextLoaderListener</listener-class>
</listener>

Note that this is not a replacement for Spring's ContextLoaderListener, you need both. Furthermore, the order in which you define the listeners is important: First Spring's, then JSF-Spring's ContextLoaderListener.

Testing the Setup - a simple application

To verify that JSF-Spring is set up properly, we'll create two simple beans: One service bean providing data and one ui bean formatting it for rendering:

de/mindmatters/faces/quickstart/service/TimeService.java

package de.mindmatters.faces.quickstart.service;

import java.util.Date;

public interface TimeService {
	Date getNow();
}

de/mindmatters/faces/quickstart/service/TimeServiceImpl.java

package de.mindmatters.faces.quickstart.service;

import java.util.Date;

public class TimeServiceImpl implements TimeService {
	public Date getNow() {
		return new Date();
	}
}

WEB-INF/applicationContext.xml (partial)

<bean id="timeService" class="de.mindmatters.faces.quickstart.service.TimeServiceImpl" />

de/mindmatters/faces/quickstart/ui/UiBean.java

package de.mindmatters.faces.quickstart.ui;

import java.text.SimpleDateFormat;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

import de.mindmatters.faces.quickstart.service.TimeService;

public class UiBean implements InitializingBean {
	private TimeService timeService = null;

	public void afterPropertiesSet() throws Exception {
		Assert.notNull(getTimeService(), "timeService must be set");
	}

	public String getShortDate() {
		return SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT).format(
				getTimeService().getNow());
	}

	public TimeService getTimeService() {
		return timeService;
	}

	public void setTimeService(TimeService timeService) {
		this.timeService = timeService;
	}
}

WEB-INF/faces-config.xml (partial)

<managed-bean>
	<managed-bean-name>uiBean</managed-bean-name>
	<managed-bean-class>de.mindmatters.faces.quickstart.ui.UiBean</managed-bean-class>
	<managed-bean-scope>request</managed-bean-scope>
	<managed-property>
		<property-name>timeService</property-name>
		<value>#{timeService}</value>
	</managed-property>
</managed-bean>

As you can see, uiBean is managed by JSF and references timeService which is managed by Spring. Furthermore, it can benefit from various Spring features, namely InitializingBean in this case.

Now, create a simple page rendering the current date:

index.jsp

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<f:view>
  <html>
    <head>
	  <title>jsf-spring quickstart</title>
    </head>
    <body>
    	<h:outputText value="#{uiBean.shortDate}"/>
    </body>
  </html>
</f:view>

Remember to view this page by accessing /index.jsf with your browser, when using / or /index.jsp, your request won't be handled by FacesServlet and thus will produce errors.

posted @ 2007-02-01 17:36 edsonjava 阅读(429) | 评论 (0)编辑 收藏
 
     摘要: 网上关于 Apache + JK + Tomcat 的集群配置例子很多,按着例子配置下来,基本都能运行,不过,在一些重要的地方却没有进一步的说明。这次公司一个产品就是采用 Apache+JK+Tomcat 集群,在整个配置、测试过程中,遇到了许多的问题,经过不断测试、摸索,最后总算是搞定了,性能也达到了预期的目标。针对网上的例子,感觉有必要再详细的介绍一下我...  阅读全文
posted @ 2006-12-26 10:27 edsonjava 阅读(467) | 评论 (0)编辑 收藏
 

[精华] 原来win+apache实现ssl的证书认证如此简单


http://www.chinaunix.net 作者:ataman  发表于:2006-02-26 15:45:34
发表评论】【查看原文】【Web服务器讨论区】【关闭

windows+apache的情况下,实现ssl的证书认证
(win下用openssl做证书极为困难的问题彻底解决了)

我写得非常详细,一步一步都说得很清楚。实际操作极为简单,要不了5分钟,是我的字打得太多了.如果发现错误,遗漏请提出。

首先,到http://hunter.campbus.com/去下载和自己的apache版本相同的的Apache_xxx-xxxOpenssl_xxx-Win32.zip。解压缩后找到这5个文件mod_ssl.so(modules目录),ssl.conf,ssl.default.conf(conf目录,

其中default.conf作为备份),libeay32.dll, ssleay32.dll(这2个都在bin目录)。把它们全都复制到你自己的apahce下的对应目录。



###############################################################################

接下来,更改设置文件


对于httpd.conf和ssl.conf,如果你的服务器没有域名,那么servername就填ip好了。
比如:ServerName 10.10.10.10:80(httpd.conf)
ServerName 10.10.10.10:443(ssl.conf)

打开httpd.conf:
找到#LoadModule ssl_module modules/mod_ssl.so,去掉前面的‘#‘,这样就在启动时加载了ssl模块。

打开ssl.conf:
找到#<IfDefine SSL>;和#</IfDefine>;,把前面的’#‘号都去掉,否则启动apache时还要加参数,麻烦。
如下设置:
SSLMutex none                         (这个我是none,有人是default,具体怎么设可以研究一下)
SSLCertificateFile conf/server.crt    (服务器证书的位置,就是公钥吧?)
SSLCertificateKeyFile conf/server.key (服务器私钥的位置)
SSLCACertificateFile conf/ca.crt      (CA根证书的位置,进行客户端验证时需要。也是一个CA公钥吧?

我把它们都放在apache的conf目录下了)
DocumentRoot "xxxxx"                  (指向要ssl加密认证的文档目录,比如"f:/http")

SSLVerifyClient require               (去掉前面的‘#’号,进行客户端验证时需要)
SSLVerifyDepth  1                     (去掉前面的‘#’号,把10改为1,进行客户端验证时需要)



##############################################################################
现在,就要制作证书了


去openvpn.net下载并安装openvpn。
这是一个虚拟个人网络制作工具,他能完美的在win(linux,BSD也行)下制作根、服务器、客户端证书。
安装完毕后,开始-程序-附件-命令提示符,进到openvpn的easy-rsa目录,比如:
f:\program files\openvpn\easy-rsa>;_
输入:
init-config 回车

会产生几个文件,切换出来,打开vars.bat文件,修改其中的KEY_COUNTRY(国家2位字母), KEY_PROVINCE(省2位字母), KEY_CITY(城市), KEY_ORG(组织),  KEY_EMAIL(电子邮箱)这几个参数,免的后面制证时

反复输入麻烦。保存退出,继续使用命令提示符。
依次输入以下两个命令,当然是分别回车喽:
vars
clean-all   (这两个是准备工作)




####################################################################################


1.
建立CA根证书


接着输入build-ca   回车(这个就是建立CA根证书啦)


然后显示:

ai:/usr/share/openvpn/easy-rsa # ./build-ca
Generating a 1024 bit RSA private key
............++++++
...........++++++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [KG]:          国家名2位字母,默认的参数就是我们刚才修改过的。
State or Province Name (full name) [NA]:    省、州名2位字母
Locality Name (eg, city) [BISHKEK]:         城市名
Organization Name (eg, company) [OpenVPN-TEST]:     组织名
Organizational Unit Name (eg, section) []:           组织里的单位名
Common Name (eg, your name or your server's hostname) []:这个是关键,应该输入颁发根证书单位的域名

,不过因为是根证书,所以怎么填都无所谓。只有服务器证书才需要认真填。
Email Address [me@myhost.mydomain]: 电子邮箱

好了,CA根证书制作完成!在keys目录下,它的名字就叫ca.crt,CA的私钥是ca.key


#######################################################################


2.
现在制作服务器证书:
在命令提示符下,输入
build-key-server server   回车
你会看到和上面很相似的东西
但要注意这里的Common Name (eg, your name or your server's hostname) []:
这个才是真正的关键。这里应该输入服务器的域名比如www.xxx.com。
如果没有域名,就应该填ip,与httpd.conf和ssl.conf里的设置对应,
ServerName 10.10.10.10:80(httpd.conf)
ServerName 10.10.10.10:443(ssl.conf)

也就是说填:10.10.10.10

接下来看到 a challenge password []:填不填随便,我不填
an optional company name []: 填不填随便,我不填

sign the certificate? [y/n] 敲y回车。用CA根证书对服务器证书签字认证。
1 out 1 certificate requests certified,commit? [y/n] 敲y回车,确认。

好了,建好了在keys目录下的server.crt(证书)和server.key(私钥)


#######################################################################


3.
现在制作客户端证书:

在命令提示符下,输入
build-key client1   回车
又是一通国家省市组织等等,comman name也是随便填的。
然后
a challenge password []:填不填随便,我不填
an optional company name []: 填不填随便,我不填

sign the certificate? [y/n] 敲y回车。用CA根证书对客户端证书签字认证。
1 out 1 certificate requests certified,commit? [y/n] 敲y回车,确认。

好了,建好了在keys目录下的client1.crt(客户端证书)和client1.key(私钥)

等等, .crt的客户端证书是不能使用的,必须把它转化为.pfx格式的文件!!

所以,还是在命令提示符下,输入
openssl 回车
看到openssl>;
再输入
pkcs12 -export –in keys/client1.crt -inkey keys/client1.key -out keys/client1.pfx
回车,
看到Enter export password:会要求你建立客户端证书的输出密码,我填hehe,
verifying-Enter export password再确认一遍hehe,好了!


########################################################################


把keys目录下的ca.crt和server.crt,server.key都复制到apache的conf目录下,(ssl.conf需要)
ca.key自己保留吧,找个合适的地方储存起来.


#########################################################################


客户端安装证书


打开internet explorer(IE),工具-internet选项-内容-证书,点选'个人'
再点击导入,把客户端证书client1.pfx导入到个人组里(别忘了扩展名是pfx)。
这里还要输入刚才建立的输出密码hehe才能倒入呢。

接着,点选'受信任的根证书颁发机构',点击导入,把CA根证书ca.crt导入到受信任的根证书颁发机构里。


#########################################################################

好啦,重新启动apache,打开IE,
在地址栏里输入https://10.10.10.10或者域名,弹出个窗口要选择个人的数字证书。
点选,然后确定。
如果服务器证书的common name填写正确的话,你就可以直接进入网站了,看到右下角的小锁头(可靠的SSL128位)。
如果服务器证书的common name填写不正确,就会弹出个‘安全警报’框,告诉你3条:
1.安全证书由信任的站点颁发
(如果说是由不信任的站点颁发,那就是你的ca根证书ca.crt没有导入到ie的受信任的根证书颁发机构里)

2.安全证书的日期有效 
(这个日期缺省是10年,可以在openvpn的easy-rsa目录下的openssl.cnf里调整修改,然后重新制作一整套证书(openssl.cnf看起来像拨

号网络的快捷方式,要用记事本,写字板打开修改))

3.“安全证书上的名称无效,或者与站点名称不匹配”
这就是服务器证书的common name填写不正确所致,不过这也没关系,有人好像愿意这样。我是不想看到这个警告框,烦人。

即使有安全警报,你仍能进入网站,看到右下角的小锁头(可靠的SSL128位)


#################################
最后,成功啦!用吧。

我自己把httpd.conf里的listen 80都加#注释了,servername改为10.10.10.10:443,只用https不用http,嗬嗬!!!

posted @ 2006-12-25 17:00 edsonjava 阅读(427) | 评论 (0)编辑 收藏
仅列出标题
共7页: 上一页 1 2 3 4 5 6 7 下一页