Posts Tagged ‘配置’

.NET 2.0获取配置文件AppSettings和ConnectionStrings节数据的方法

星期二, 06月 3rd, 2008

在 .NET Framework 2.0中,ConfigurationManager类新增了两个属性AppSettings和ConnectionStrings专门用来获取配置文件AppSettings和ConnectionStrings节de数据,使用方法如下:

[复制此相关代码]CODE:
using System.Configuration;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = ConfigurationManager.ConnectionStrings["connectionStringsName"].ToString();
Label2.Text = ConfigurationManager.AppSettings["appSettingsName"].ToString();
}
}

轻松玩转Java配置的Classpath

星期一, 06月 2nd, 2008

  和Java类路径(classpath)打交道de过程中,开发者偶尔会遇到麻烦.这是因为,类装载器实际装入de是哪一个类有时并不显而易见,当应用程序declasspath包含大量de类和目录时,情况尤其严重.本文将提供一个工具,它能够显示出被装入类文件de绝对路径名.
  一、Classpath基础

  Java虚拟机(JVM)借助类装载器装入应用程序使用de类,具体装入哪些类根据当时de需要决定.CLASSPATH环境变量告诉类装载器到哪里去寻找第三方提供de类和用户定义de类.另外,您也可以使用JVM命令行参数-classpath分别为应用程序指定类路径,在-classpath中指定de类路径覆盖CLASSPATH环境变量中指定de值.
  类路径中de内容可以是:文件de目录(包含不在包里面de类),包de根目录(包含已打包de类),包含类de档案文件(比如.zip文件或者.jar文件).在Unix家族de系统上,类路径de各个项目由冒号分隔,在MS Windows系统上,它们由分号分隔.
  类装载器以委托层次de形式组织,每一个类装载器有一个父类装载器.当一个类装载器被要求装载某个类时,它在尝试自己寻找类之前会把请求先委托给它de父类装载器.系统类装载器,即由安装在系统上deJDK或JRE提供de默认类装载器,通过CLASSPATH环境变量或者-classpath这个JVM命令行参数装入第三方提供de类或者用户定义de类.系统类装载器委托扩展类装载器装入使用Java Extension机制de类.扩展类装载器委托自举类装载器(bootstrap class loader)装入核心JDK类.
  您可以自己开发特殊de类装载器,定制JVM如何动态地装入类.例如,大多数Servlet引擎使用定制de类装载器,动态地装入那些在classpath指定de目录内发生变化de类.
  必须特别注意de是(也是令人吃惊de是),类装载器装入类de次序就是类在classpath中出现de次序.类装载器从classpathde第一项开始,依次检查每一个设定de目录和压缩文件,尝试找出待装入de类文件.当类装载器第一次找到具有指定名字de类时,它就把该类装入,classpath中所有余下de项目都被忽略.
  看起来很简单,对吧?
  二、可能出现de问题

  不管他们是否愿意承认,初学者和富有经验deJava开发者都一样,他们都曾经在某些时候(通常是在那些最糟糕de情形下)被冗长、复杂declasspath欺骗.应用程序所依赖de第三方类和用户定义类de数量逐渐增长,classpath也逐渐成了一个堆积所有可能de目录和档案文件名de地方.此时,类装载器首先装载de究竟是哪一个类也就不再显而易见.如果classpath中包含重复de类入口,这个问题尤其突出.前面已经提到,类装载器总是装载第一个它在classpath中找到de具有合适名字de类,从实际效果看,它“隐藏”了其他具有合适名字但在classpath中优先级较低de类.
  如果不小心,您很容易掉进这个classpathde陷阱.当您结束了一天漫长de工作,最后为了让应用程序使用最好、最新de类,您把一个目录加入到了classpath,但与此同时,您却忘记了:在classpathde另一个具有更高优先级de目录下,存放着该类de另一个版本!

   三、一个简单declasspath工具

  优先级问题是扁平路径声明方法与生俱来固有de问题,但它不是只有Javadeclasspath才有de问题.要解决这个问题,您只需站到富有传奇色彩de软件巨构de肩膀上:Unix操作系统有一个which命令,在命令参数中指定一个名字,which就会显示出当这个名字作为命令执行时执行文件de路径名.实际上,which命令是分析PATH变量,然后找出命令第一次出现de位置.对于Javade类路径管理来说,这应该也是一个好工具.在它de启发之下,我着手设计了一个Java工具JWhich.这个工具要求指定一个Java类de名字,然后根据classpathde指引,找出类装载器即将装载de类所在位置de绝对路径.
  下面是一个JWhichde使用实例.它显示出当Java类装载器装载com.clarkware.ejb.ShoppingCartBean类时,该类第一次出现位置de绝对路径名,查找结果显示该类在某个目录下:
  > java JWhich com.clarkware.ejb.ShoppingCartBean
  Class ‘com.clarkware.ejb.ShoppingCartBean’ found in
  ’/home/mclark/classes/com/clarkware/ejb/ShoppingCartBean.class’
  下面是第二个JWhichde使用实例.它显示出当Java类装载器装载javax.servlet.http.HttpServlet类时,该类第一次出现位置de绝对路径名,查找结果显示该类在某个档案文件中:
  > java JWhich javax.servlet.http.HttpServlet
  Class ‘javax.servlet.http.HttpServlet’ found in
  ’file:/home/mclark/lib/servlet.jar!/javax/servlet/http/HttpServlet.class’
  四、JWhichde工作过程
  要精确地测定classpath中哪一个类先被装载,您必须深入到类装载器de思考方法.事实上,具体实现de时候并没有听起来这么复杂——您只需直接询问类装载器就可以了!
  1: public class JWhich {
  2:
  3: /**
  4: * 根据当前declasspath设置,
  5: * 显示出包含指定类de类文件所在
  6: * 位置de绝对路径
  7: *
  8: * @param className <类de名字>
  9: */
  10: public static void which(String className) {
  11:
  12: if (!className.startsWith(”/”)) {
  13: className = “/” className;
  14: }
  15: className = className.replace(’.', ‘/’);
  16: className = className “.class”;
  17:
  18: java.net.URL classUrl =
  19: new JWhich().getClass().getResource(className);
  20:
  21: if (classUrl != null) {
  22: System.out.println(” Class ‘” className
  23: “‘ found in ‘” classUrl.getFile() “‘”);
  24: } else {
  25: System.out.println(” Class ‘” className
  26: “‘ not found in ‘”
  27: System.getProperty(”java.class.path”) “‘”);
  28: }
  29: }
  30:
  31: public static void main(String args[]) {
  32: if (args.length > 0) {
  33: JWhich.which(args[0]);
  34: } else {
  35: System.err.println(”Usage: java JWhich “);
  36: }
  37: }
  38: }
  首先,您必须稍微调整一下类de名字以便类装载器能够接受(12-16行).在类de名字前面加上一个“/”表示要求类装载器对classpath中de类名字进行逐字精确匹配,而不是尝试隐含地加上调用类de包名字前缀.把所有“.”转换为“/”de目de是,按照类装载器de要求,把类名字格式化成一个合法deURL资源名.
  接下来,程序向类装载器查询资源,这个资源de名字必须和经过适当格式化de类名字匹配(18-19行).每一个Class对象维护着一个对装载它deClassLoader对象de引用,所以这里是向装载JWhich类de类装载器查询.Class.getResource()方法实际上委托装入该类de类装载器,返回一个用于读取类文件资源deURL;或者,当指定de类名字不能在当前declasspath中找到时,Class.getResource()方法返回null.
  最后,如果当前declasspath中能够找到指定de类,则程序显示包含该类de类文件所在位置de绝对路径名(21-24行).作为一种调试辅助手段,如果当前classpath中不能找到指定de类,则程序获取java.class.path系统属性并显示当前declasspath(24-28行).
  很容易想象,在使用Servlet引擎classpathdeJava Servlet中,或者在使用EJB服务器classpathdeEJB组件中,上面这段简单de相关代码是如何运作.例如,如果JWhich类是由Servlet引擎de定制类装载器装入,那么程序将用Servlet引擎de类装载器去寻找指定de类.如果Servlet引擎de类装载器不能找到类文件,它将委托它de父类装载器.一般地,当JWhich被某个类装载器装入时,它能够找出当前类装载器以及所有其父类装载器所装入de所有类.
  【结束语】

  如果需要是所有发明之母,那么帮助我管理Java类路径de工具可以说迟到了很长时间.Java新闻组和邮件列表中充塞着许多有关classpathde问题,现在JWhich为我提供了一个简单却强大de工具,帮助我在任何环境中彻底玩转Java类路径.

JBuilder2005单元测试体验之测试配置

星期一, 06月 2nd, 2008

在测试用例向导de最后一步,允许您创建一个测试用例de运行配置项,如下图所示:


图 错误!文档中没有指定样式de文字.创建运行测试项

  在一般情况下,您不必为每个测试用例类单独创建一个运行配置项,JBuilder会采用默认de运行配置运行测试用例.
  测试运行配置项在需要指定不同de测试运行器(默认为JBTestRunner)、一次运行多个测试用例时,允许您进行特殊de定制.通过Project->Project Properties…->Run,在Run设置页中列出了工程所有已定义de运行配置项,Runtime Configurations列表中Type类型为Testde运行配置项即为测试运行配置项,可以通过对话框右边deEdit…按钮编辑这些运行配置项,如下图所示:

图 错误!文档中没有指定样式de文字.运行配置页列表

  下面,我来创建一个新de名为TestAllDbTestde运行配置项,用JUnit提供dejunit.swingui.TestRunner测试运行器运行测试用例,使chapter25.db包下所有以Test打头de测试用例类一并运行.
  在图 错误!文档中没有指定样式de文字.点击New…按钮,弹出New Runtime Configurationde对话框,如下图所示

图 错误!文档中没有指定样式de文字.TestSubsection运行

  在Name中填入TestAllDb.在Type中选择Test,对话框下部de窗口调整为测试运行配置de界面.默认Class单选框选中,允许您指定一个测试用例类,由于我希望通过该配置项运行chapter25.db包下所有de测试用例,所以我选择Package单选框,并通过其后de…按钮选择chapter25.db包.

在Name starts with中填入Test,即运行所有类名以Test为前缀de类,此外,您还可以在Name ends with中指定类名后缀.
  注意:
  注意,如果包中有以Test打头de非测试用例类,运行这个测试运行配置项时,将会抛出错误,特别需要指出de是以Test为前缀de测试套件也是不允许de,满足过滤条件de类都必须是测试用例类.
  在Test Runner中包含3个测试运行器,分别是JBuilder Test Runner、JUnit SwingUI Test Runner
和JUnit TestUI Test Runner.默认为JBuilder Test Runner,也即JBTestRunner,当然这个运行器功能最强大.对于好奇心强de开发人员来说,可能希望看看JUnit自带运行器de芳容,笔者也是其中de一位,所以这里,我选择JUnit SwingUI Test Runner.
  对于New Runtime Configuration对话框其它de设置项,可以通过Help按钮获取JBuilderde帮助.
  在完成TestAddDb运行配置项de设置后,点击工具栏中 图标右边de向下箭头,在弹出de菜单中选择TestAddDb,如下图所示:


图 错误!文档中没有指定样式de文字.通过测试运行配置项运行测试用例

  点击TESTALLDB项,JBuilder使用JUnitdejunit.swingui.TestRunner运行chapter25.db包中deTestEmployeeDAO和TestEmployee两测试用例类,因为这两个用例类都以Test打头,运行器窗口如下所示:

图 错误!文档中没有指定样式de文字.junit.swingui.TestRunner测试运行器

  在Test Hierarchy标签页中,列出了TestEmployeeDAO和TestEmployee两测试用例类,所以通过测试运行配置项,也可以实现测试套件相似de效果,当然还是没有办法达到测试套件de灵活度.假设测试用例命名没有规律,或者存在过滤冲突,这时就只得求助于测试套件了.

Weblogic上配置Hibernate为JNDI

星期一, 06月 2nd, 2008

  一、首先需要把Hibernate 用到dejar包和配置文件都放到Weblogic能够搜索到deCLASSPATH路径上.单单这一步就有很多人很迷茫,其实去仔细看看Weblogicde启动脚本文件startWeblogic.cmd和startWLS.cmd,我想大部分人都知道该怎么配置了.
  我机器上de有个Hibernatede项目,在D: estoracle目录下,该目录下de结构是:
  D: estoraclelib 放置hibernatede所有jar包
  D: estoraclesrc 放置源相关代码
  D: estoracleclasses 编译好de相关代码和hibernatede配置文件(hibernate.properties, log4j.properties, cache.ccf)
  现在需要把D: estoraclelib目录下那些jar文件和D: estoracleclasses目录都放置到Weblogicde CLASSPATH里面去,所以修改mydomain里面deWeblogic启动脚本startWeblogic.cmd,在启动Weblogic之前,插入设置CLASSPATHde命令,如下:
  @rem set hibernate classpath
  set HIBERNATE_LIB=D: estoraclelib
  set HIBERNATE_CLASSES=D: estoracleclasses
  set CLASSPATH=%CLASSPATH%;%HIBERNATE_LIB%cglib-asm.jar;%HIBERNATE_LIB%commons-beanutils.jar;
  %HIBERNATE_LIB%commons-collections.jar;%HIBERNATE_LIB%commons-lang.jar;
  %HIBERNATE_LIB%commons-logging.jar;%HIBERNATE_LIB%dom4j-full.jar;
  %HIBERNATE_LIB%hibernate2.jar;%HIBERNATE_LIB%jcs.jar;
  %HIBERNATE_LIB%log4j-1.2.8.jar;%HIBERNATE_LIB%odmg.jar;
  %HIBERNATE_LIB%jta.jar;%HIBERNATE_CLASSES%;
  下面一行,就是本来脚本里面de启动命令:
  @rem Call Weblogic Server
  call “C:eaweblogic700serverinstartWLS.cmd”
  二、在Weblogic上配置 Oracle数据库de连接池,这一步本来和Hibernate无关,但是如果您想要使用EJB,想要使用JTA,那么必须使用Weblogic提供de连接池,而不能使用Hibernate自带de连接池,或者其它第三方连接池,否则容器将无法管理数据库事务.这一步很简单,就是在Weblogic Console里面配置Connection Pool和TxData Source,我deTxDataSource取名称为“mypool”
  三、修改hibernate.properties.使用Weblogicde连接池,而不是自带de连接池.我修改de是D: estoracleclasseshibernate.properties,增加如下行:
  hibernate.dialect net.sf.hibernate.dialect.OracleDialect
  hibernate.connection.datasource mypool
  hibernate.connection.provider_class net.sf.hibernate.connection.DatasourceConnectionProvider
  hibernate.session_factory_name hibernate.session_factory
  注意最后一行,这是使用 Hibernate来绑定JNDI给JNDI起de名称,本来应该是hibernate/session_factory,但是Weblogic要求改为. 号,不过在程序中lookupde时候还是要写hibernate/session_factory
  另外提到一点de是
  hibernate.jdbc.fetch_size 50
  hibernate.jdbc.batch_size 25
  分别对数据库查询和插入有很大de性能影响,调节这两个选项可以得到最好de性能.
  为了保证SessionFactory实例de预创建,使用WeblogicdeT3StartUpDef接口创建一个StartUp类,在Weblogic启动de时候运行:
  package com.javaeye;
  import java.util.Hashtable;
  import weblogic.common.T3StartupDef;
  import weblogic.common.T3ServicesDef;
  import net.sf.hibernate.cfg.Configuration;
  import net.sf.hibernate.SessionFactory;
  public class HibernateStartUp implements T3StartupDef {
  public void setServices(T3ServicesDef services) {}
  public String startup(String name, Hashtable args) throws Exception {
  SessionFactory sf = new Configuration().configure().buildSessionFactory();
  return “Hibernate Startup completed successfully”;
  }
  }
  相关代码非常简单,其实就是确保预先运行
  SessionFactory sf = new Configuration().configure().buildSessionFactory();
  把sf创建出来,而Hibernate会自行调用一系列类方法,把sf绑定到WeblogicdedeJNDI树下dehibernate/session_factory路径中.
  4、编译HibernateStartUp.java
  编译这个源相关代码de时候需要注意de是,要把weblogic.jar包和Hibernate所有de相关包和配置文件导入.我是把这个源相关代码放到D: estoraclesrc目录下de,用早已编写好deant脚本运行一下就编译好了,并且编译好de class文件被放置到D: estoracleclasses目录下,该目录已经被加入到WeblogicdeCLASSPATH里面,因此很省事.
  五、配置StartUp类
  启动Weblogic,打开Console控制台,在左边deApplet树上找到StartUp & Shutdown,然后在右边点击“Configure a new Startup Class…”,在Name框里面随便填写,在ClassName里面填写您编写deStartUp类,我填写de是 com.javaeye.HibernateStartUp,然后点击“Apply”.然后切换到Target这选项卡,在Target-Server左边de Avaiable框里面选择“myserver”,点击右箭头,把它挪到右边de“Chosen”框里面去,最后再点击一下“Apply”按钮.如果此时 WeblogicdeDOS窗口里面没有出错信息,那么应该已经配置成功了.
  六、现在关闭Weblogic,再重新运行 startWelogic.cmd,启动Weblogic,观察DOS窗口de输出信息,可以看到Hibernatede初始化信息一屏屏de滚动输出,证明已经配置成功.现在再打开Console控制台,点击左边Applet树中deServers|myserver,然后可以在右边最下面找到“View JNDI tree ”,点击它,会打开一个浏览器窗口,显示JNDI树,这时您可以看到一个名称为hibernatedeJNDI对象,在左边deApplet树中点击它,看右边de详细信息,我de机器上de信息如下:
  Bind Name: hibernate
  Object Class: net.sf.hibernate.impl.SessionFactoryImpl
  Object Hash Code: 454492
  Object To String: net.sf.hibernate.impl.SessionFactoryImpl@6ef5c
  完全正确!
  最后您可以随意在EJB或者Servlet/JSP里面使用JND查找来获得SessionFactory了.
  例如:
  Context ctx = new InitialContext();
  SessionFactory sf = (SessionFactory) ctx.lookup(”hibernate/session_factory”);
  请注意:上述相关代码只能在WebLogic容器内运行,而不能在WebLogic容器外运行.因为SessionFactory并没有实现序列化接口,因此当客户端程序(在另一个单独deJVM中运行)远程访问WebLogic JNDI,企图将SessionFactory序列化到本地,肯定会失败.但即使SessionFactory实现序列化接口,由于它不是一个可以支持RMIde对象,仍然无法在WebLogic容器外正常调用.
  与此不同de是,WebLogic本身deDataSource,EJB,JMS等等都是支持RMIde(前提条件是WebLogic相应dejar要有),所以您可以在WebLogic外面lookup,并且使用它.

Hibernate 的原理与配置

星期一, 06月 2nd, 2008

  也许您听说过Hibernatede大名,但可能一直不了解它,也许您一直渴望使用它进行开发,那么本文正是您所需要de!在本文中,我向大家重点介绍Hibernatede核心API调用库,并讲解一下它de基本配置.
  看完本文后,我相信您对什么是ORM(对像/关系映射)以及它de优点会有一个深刻de认识,我先通过一个简单de例子开始来展现它de威力.
  正如一些传统de经典计算机文章大都会通过一个“hello,world”de例子开始讲解一样,我也不例外,我也将从一个相对简单de例子来阐述Hibernatede开发方法,但如果要真正阐述Hibernatede一些重要思想,仅仅靠在屏幕上打印一些字符是远远不够de,在我de示例程序中,我将创建一些对象,并将其保存在数据库中,然后对它们进行更新和查询.
  阅读导航

  “Hello World”“Hello world”示例程序让您对Hibernate有一个简单de认识.
  理解Hibernatede架构介绍Hibernate接口de主要功能.
  核心接口Hibernate有5个核心接口,通过这几个接口开发人员可以存储和获得持久对象,并且能够进行事务控制
  一个重要de术语:TypeType是Hibernate发明者发明de一个术语,它在整个构架中是一个非常基础、有着强大功能de元素,一个Type对象能将一个Java类型映射到数据库中一个表de字段中去.
  策略接口Hibernate与某些其它开源软件不同de还有一点――高度de可扩展性,这通过它de内置策略机制来实现.
  基础配置Hibernate可以配置成可在任何Java环境中运行,一般说来,它通常被用在2-3层deC/S模式de项目中,并被部署在服务端.
  创建一个SessionFactory对象要创建一个SessionFactory对象,必须在Hibernate初始化时创建一个Configuration类de实例,并将已写好de映射文件交由它处理.
  “Hello World”

  Hibernate应用程序定义了一些持久类,并且定义了这些类与数据库表格de映射关系.在我这个“Hello world”示例程序中包含了一个类和一个映射文件.让我看看这个简单de持久类包含有一些什么?映射文件是怎样定义de?另外,我该怎样用Hibernate来操作这个持久类.
  我这个简单示例程序de目de是将一些持久类存储在数据库中,然后从数据库取出来,并将其信息正文显示给用户.其中Message正是一个简单de持久类:,它包含我要显示de信息,其源相关代码如下:
  列表1 Message.Java 一个简单de持久类
  package hello;
  public class Message {
  private Long id;
  private String text;
  private Message nextMessage;
  private Message() {}
  public Message(String text) {
  this.text = text;
  }
  public Long getId() {
  return id;
  }
  private void setId(Long id) {
  this.id = id;
  }
  public String getText() {
  return text;
  }
  public void setText(String text) {
  this.text = text;
  }
  public Message getNextMessage() {
  return nextMessage;
  }
  public void setNextMessage(Message nextMessage) {
  this.nextMessage = nextMessage;
  }
  }
  Message类有三个属性:Messagedeid 、消息正文、以及一个指向下一条消息de指针.其中id属性让我de应用程序能够唯一de识别这条消息,通常它等同于数据库中de主键,如果多个Message类de实例对象拥有相同deid,那它们代表数据库某个表de同一个记录.在这里我选择了长整型作为我deid值,但这不是必需de.Hibernate允许我使用任意de类型来作为对象deid值,在后面我会对此作详细描述.
  您可能注意到Message类de相关代码类似于JavaBeande相关代码风格,并且它有一个没有参数de构造函数,在我以后de相关代码中我将继续使用这种风格来编写持久类de相关代码.
  Hibernate会自动管理Message类de实例,并通过内部机制使其持久化,但实际上Message对象并没有实现任何关于Hibernatede类或接口,因此我也可以将它作为一个普通deJava类来使用:
  Message message = new Message(”Hello World”);
  System.out.println( message.getText() );
  以上这段相关代码正是我所期望de结果:它打印“hello world”到屏幕上.但这并不是我de最终目标;实际上Hibernate与诸如EJB容器这样de环境在持久层实现de方式上有很大de不同.我de持久类(Message类)可以用在与容器无关de环境中,不像EJB必须要有EJB容器才能执行.为了能更清楚地表现这点,以下相关代码将我de一个新消息保存到数据库中去:
  Session session = getSessionFactory().openSession();
  Transaction tx = session.beginTransaction();
  Message message = new Message(”Hello World”);
  session.save(message);
  tx.commit();
  session.close();
  以上这段相关代码调用了HibernatedeSession和Transaction接口(关于getSessionFactory()方法我将会马上提到).它相当于我执行了以下SQL语句:
  insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)
  values (1, ‘Hello World’, null)
  在以上deSQL语句中,MESSAGE_ID字段到底被初始化成了什么值呢?由于我并没有在先前de相关代码中为message对象deid属性赋与初始值,那它是否为null呢?实际上Hibernate对id属性作了特殊处理:由于它是一个对象de唯一标识,因此当我进行save()调用时,Hibernate会为它自动赋予一个唯一de值(我将在后面内容中讲述它是如何生成这个值de).
  我假设您已经在数据库中创建了一个名为MESSAGEde表,那么既然前面这段相关代码让我将Message对象存入了数据库中,那么现在我就要将它们一一取出来.下面这段相关代码将按照字母顺序,将数据库中de所有Message对象取出来,并将它们de消息正文打印到屏幕上:
  Session newSession = getSessionFactory().openSession();
  Transaction newTransaction = newSession.beginTransaction();
  List messages =newSession.find(”from Message as m order by m.text asc”);
  System.out.println( messages.size() ” message(s) found:” );
  for ( Iterator iter = messages.iterator(); iter.hasNext(); ) {
  Message message = (Message) iter.next();
  System.out.println( message.getText() );
  }
  newTransaction.commit();
  newSession.close();
  在以上这段相关代码中,您可能被find()方法de这个参数困扰着:”from Message as m order by m.text asc”,其实它是Hibernate自己定义de查询语言,全称叫Hibernate Query Language(HQL).通俗地讲HQL与SQLde关系差不多就是方言与普通话之间de关系,咋一看,您会觉得它有点类似于SQL语句.其实在find()调用时,Hibernate会将这段HQL语言翻译成如下deSQL语句:
  select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID
  from MESSAGES m
  order by m.MESSAGE_TEXT asc
  以下就是运行结果:
  1 message(s) found:
  Hello World
  如果您以前没有ORM(对象-关系映射)de开发经验,那您可能想在相关代码de某个地方去寻找这段SQL语句,但在Hibernate中您可能会失望:它根本不存在!所有就SQL语句都是Hibernate动态生成de.
  也许您会觉得还缺点什么,对!仅凭以上相关代码Hibernate是无法将我deMessage类持久化de.我还需要一些更多de信息,这就是映射定义表!这个表在Hibernate中是以XML格式来体现de,它定义了Message类de属性是怎样与数据库中deMESSAGES表de字段进行一一对应de,列表2是这个示例程序de映射配置文件清单:
  列表2:示例程序de对象-关系映射表
  <?xml version=”1.0″?>
  <!DOCTYPE hibernate-mapping PUBLIC
  ”-//Hibernate/Hibernate Mapping DTD//EN”
  ”http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd”>
  <hibernate-mapping>
  <class name=”hello.Message” table=”MESSAGES”>
  <id name=”id” column=”MESSAGE_ID”>
  <generator class=”increment”/>
  </id>
  <property name=”text” column=”MESSAGE_TEXT”/>
  <many-to-one name=”nextMessage” cascade=”all” column=”NEXT_MESSAGE_ID”/>
  </class>
  </hibernate-mapping>
  以上这个文档告诉Hibernate怎样将Message类映射到MESSAGES表中,其中Message类deid属性与表deMESSAGE_ID字段对应,text属性与表deMESSAGE_TEXT字段对应,nextMessage属性是一个多对一de关系,它与表中deNEXT_MESSAGE_ID相对应.
  相对于有些开源项目来说,Hibernatede配置文件其实是很容易理解de.您可以轻松地修改与维护它.只要您定义好了持久类与数据库中表字段de对应关系就行了,Hibernate会自动帮您生成SQL语句来对Message对象进行插入、更新、删除、查找工作,您可以不写一句SQL语句,甚至不需要懂得SQL语言!
  现在让我做一个新de试验,我先取出第一个Message对象,然后修改它de消息正文,最后我再生成一个新deMessage对象,并将它作为第一个Message对象de下一条消息,其相关代码如下:
  列表3 更新一条消息
  Session session = getSessionFactory().openSession();
  Transaction tx = session.beginTransaction();
  // 1 is the generated id of the first message
  Message message =(Message) session.load( Message.class, new Long(1) );
  message.setText(”Greetings Earthling”);
  Message nextMessage = new Message(”Take me to your leader (please)”);
  message.setNextMessage( nextMessage );
  tx.commit();
  session.close();
  以上这段相关代码在调用时,Hibernate内部自动生成如下deSQL语句:
  select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID
  from MESSAGES m
  where m.MESSAGE_ID = 1
  insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)
  values (2, ‘Take me to your leader (please)’, null)
  update MESSAGES
  set MESSAGE_TEXT = ‘Greetings Earthling’, NEXT_MESSAGE_ID = 2
  where MESSAGE_ID = 1
  当第一个Message对象detext属性和nextMessage被程序修改时,请注意Hibernate是如何检测到这种变化,并如何在数据库中自动对它更新de.这实际上是Hibernatede一个很有价值de特色,我把它称为“自动脏数据检测”,Hibernatede这个特色使得当我修改一个持久对象de属性后,不必显式地通知Hibernate去将它在数据库中进行更新.同样de,当第一个Message对象调用setNextMessage()方法将第二个Message对象作为它de下一条消息de引用时,第二条消息会无需调用save()方法,便可以自动地保存在数据库中.这种特色被称为“级联保存”,它也免去了我显式地对第二个Message对象调用save()方法之苦.
  如果我再运行先前de那段将数据库中所有deMessage对象都打印出来de相关代码,那它de运行结果如下:
  2 message(s) found:
  Greetings Earthling
  Take me to your leader (please)

  “Hello world”示例程序现在介绍完毕.我总算对Hibernate有了一个简单de认识,下面我将回过头来,对Hibernatede主要API调用作一下简要de介绍:
  
  理解Hibernatede架构
  当您想用Hibernate开发自己de基于持久层de应用时,第一件事情应当是熟悉它de编程接口.HibernatedeAPI接口设计得尽量简洁明了,以方便开发人员.然而实际上由于ORMde复杂性,它deAPI一般都不可能设计得很简单.但是别担心,您没有必要一下子了解所有deHibernatedeAPI接口.
  我将应用层放在了持久层de上部,实际上在传统de项目中,应用层充当着持久层de一个客户端角色.但对于一些简单de项目来说,应用层和持久层并没有区分得那么清楚,这也没什么,在这种情况下您可以将应用层和持久层合并成了一层.
  Hibernatede接口大致可以分为以下几种类型:
  · 一些被用户de应用程序调用de,用来完成基本de创建、读取、更新、删除操作以及查询操作de接口.这些接口是Hibernate实现用户程序de商业逻辑de主要接口,它们包括Session、Transaction和Query.
  · Hibernate用来读取诸如映射表这类配置文件de接口,典型de代表有Configuration类.
  · 回调(Callback)接口.它允许应用程序能对一些事件de发生作出相应de操作,例如Interceptor、Lifecycle和Validatable都是这一类接口.
  · 一些可以用来扩展Hibernatede映射机制de接口,例如UserType、CompositeUserType和IdentifierGenerator.这些接口可由用户程序来实现(如果有必要).
  Hibernate使用了J2EE架构中de如下技术:JDBC、JTA、JNDI.其中JDBC是一个支持关系数据库操作de一个基础层;它与JNDI和JTA一起结合,使得Hibernate可以方便地集成到J2EE应用服务器中去.
  在这里,我不会详细地去讨论Hibernate API接口中de所有方法,我只简要讲一下每个主要接口de功能,如果您想了解得更多de话,您可以在Hibernatede源码包中denet.sf.hibernate子包中去查看这些接口de源相关代码.下面我依次讲一下所有de主要接口:
  核心接口
  以下5个核心接口几乎在任何实际开发中都会用到.通过这些接口,您不仅可以存储和获得持久对象,并且能够进行事务控制.
  Session接口
  Session接口对于Hibernate 开发人员来说是一个最重要de接口.然而在Hibernate中,实例化deSession是一个轻量级de类,创建和销毁它都不会占用很多资源.这在实际项目中确实很重要,因为在客户程序中,可能会不断地创建以及销毁Session对象,如果Sessionde开销太大,会给系统带来不良影响.但值得注意de是Session对象是非线程安全de,因此在您de设计中,最好是一个线程只创建一个Session对象.
  在Hibernatede设计者de头脑中,他们将session看作介于数据连接与事务管理一种中间接口.我可以将session想象成一个持久对象de缓冲区,Hibernate能检测到这些持久对象de改变,并及时刷新数据库.我有时也称Session是一个持久层管理器,因为它包含这一些持久层相关de操作,诸如存储持久对象至数据库,以及从数据库从获得它们.请注意,Hibernate desession不同于JSP应用中deHttpSession.当我使用session这个术语时,我指de是Hibernate中desession,而我以后会将HttpSesion对象称为用户session.
  SessionFactory 接口
  这里用到了一个设计模式――工厂模式,用户程序从工厂类SessionFactory中取得Sessionde实例.
  令您感到奇怪de是SessionFactory并不是轻量级de!实际上它de设计者de意图是让它能在整个应用中共享.典型地来说,一个项目通常只需要一个SessionFactory就够了,但是当您de项目要操作多个数据库时,那您必须为每个数据库指定一个SessionFactory.
  SessionFactory在Hibernate中实际起到了一个缓冲区de作用,它缓冲了Hibernate自动生成deSQL语句和一些其它de映射数据,还缓冲了一些将来有可能重复利用de数据.
  Configuration 接口
  Configuration接口de作用是对Hibernate进行配置,以及对它进行启动.在Hibernatede启动过程中,Configuration类de实例首先定位映射文档de位置,读取这些配置,然后创建一个SessionFactory对象.
  虽然Configuration接口在整个Hibernate项目中只扮演着一个很小de角色,但它是启动hibernate时您所遇到de每一个对象.
  Transaction 接口
  Transaction接口是一个可选deAPI,您可以选择不使用这个接口,取而代之de是Hibernatede设计者自己写de底层事务处理相关代码. Transaction接口是对实际事务实现de一个抽象,这些实现包括JDBCde事务、JTA中deUserTransaction、甚至可以是CORBA事务.之所以这样设计是能让开发者能够使用一个统一事务de操作界面,使得自己de项目可以在不同de环境和容器之间方便地移值.
  Query和Criteria接口
  Query接口让您方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL语言或本地数据库deSQL语句.Query经常被用来绑定查询参数、限制查询记录数量,并最终执行查询操作.
  Criteria接口与Query接口非常类似,它允许您创建并执行面向对象de标准化查询.
  值得注意de是Query接口也是轻量级de,它不能在Session之外使用.
  Callback 接口
  当一些有用de事件发生时――例如持久对象de载入、存储、删除时,Callback接口会通知Hibernate去接收一个通知消息.一般而言,Callback接口在用户程序中并不是必须de,但您要在您de项目中创建审计日志时,您可能会用到它.
   一个重要de术语:Type

  Hibernatede设计者们发明了一个术语:Type,它在整个构架中是一个非常基础、有着强大功能de元素.一个Type对象能将一个Java类型映射到数据库中一个表de字段中去(实际上,它可以映射到表de多个字段中去).持久类de所有属性都对应一个type.这种设计思想使用Hibernate有着高度de灵活性和扩展性.
  Hibernate内置很多type类型,几乎包括所有deJava基本类型,例如Java.util.Currency、Java.util.calendar、byte[]和Java.io.Serializable.
  不仅如此,Hibernate还支持用户自定义detype,通过实现接口UserType和接口CompositeUserType,您可以加入自己detype.您可以利用这种特色让您de项目中使用自定义de诸如Address、Name这样detype,这样您就可以获得更大de便利,让您de相关代码更优雅.自定义type在Hibernate中是一项核心特色,它de设计者鼓励您多多使用它来创建一个灵活、优雅de项目!
  策略接口
  Hibernate与某些其它开源软件不同de还有一点――高度de可扩展性,这通过它de内置策略机制来实现.当您感觉到Hibernatede某些功能不足,或者有某些缺陷时,您可以开发一个自己de策略来替换它,而您所要做de仅仅只是继承它de某个策略接口,然后实现您de新策略就可以了,以下是它de策略接口:
  · 主键de生成 (IdentifierGenerator 接口)
  · 本地SQL语言支持 (Dialect 抽象类)
  · 缓冲机制 (Cache 和CacheProvider 接口)
  · JDBC 连接管理 (ConnectionProvider接口)
  · 事务管理 (TransactionFactory, Transaction, 和 TransactionManagerLookup 接口)
  · ORM 策略 (ClassPersister 接口)
  · 属性访问策略 (PropertyAccessor 接口)
  · 代理对象de创建 (ProxyFactory接口)
  Hibernate为以上所列de机制分别创建了一个缺省de实现,因此如果您只是要增强它de某个策略de功能de话,只需简单地继承这个类就可以了,没有必要从头开始写相关代码.
  以上就是Hibernatede一些核心接口,但当我真正开始用它进行开发时,您de脑海里可能总会有一个疑问:我是通过什么方式,并从哪里取得Sessionde呢?以下我就解答这个问题.
  基础配置
  现在回顾一下我先前de内容:我写出了一个示例程序,并简要地讲解了Hibernatede一些核心类.但要真正使您de项目运行起来,还有一件事必须要做:配置.Hibernate可以配置成可在任何Java环境中运行,一般说来,它通常被用在2-3层deC/S模式de项目中,并被部署在服务端.在这种项目中,Web浏览器、或Java GUI程序充当者客户端.尽管我de焦点主要是集中在多层web应用,但实际上在一些基于命令行de应用中也可以使用Hibernate.并且,对Hibernatede配置在不同de环境下都会不同,Hibernate运行在两种环境下:可管理环境和不可管理环境
  · 可管理环境――这种环境可管理如下资源:池资源管理,诸如数据库连接池和,还有事务管理、安全定义.一些典型deJ2EE服务器(JBoss、Weblogic、WebSphere)已经实现了这些.
  · 不可管理环境――只是提供了一些基本de功能,诸如像Jetty或Tomcat这样deservlet容器环境.一个普通deJava桌面应用或命令行程序也可以认为是处于这种环境下.这种环境不能提供自动事务处理、资源管理或安全管理,这些都必须由应用程序自己来定义.
  Hibernatede设计者们将这两种环境设计了一个统一de抽象界面,因此对于开发者来说只有一种环境:可管理环境.如果实际项目是建立在诸如Tomcat这类不可管理de环境中时,那Hibernate将会使用它自己de事务处理相关代码和JDBC连接池,使其变为一个可管理环境.
  对于可管理de环境而言,Hibernate会将自己集成在这种环境中.对于开发者而言,您所要做de工作非常简单:只需从一个Configuration类中创建一个SessionFactory类就可以了.
   创建一个SessionFactory对象
  为了能创建一个SessionFactory对象,您必须在Hibernate初始化时创建一个Configuration类de实例,并将已写好de映射文件交由它处理.这样,Configuration对象就可以创建一个SessionFactory对象,当SessionFactory对象创建成功后,Configuration对象就没有用了,您可以简单地抛弃它.如下是示例相关代码:
  Configuration cfg = new Configuration();
  cfg.addResource(”hello/Message.hbm.xml”);
  cfg.setProperties( System.getProperties() );
  SessionFactory sessions = cfg.buildSessionFactory();
  在以上相关代码中,Message.hb.xml这个映射文件de位置比较特殊,它与当前declasspath相关.例如classpath包含当前目录,那在上述相关代码中deMessage.hbm.xml映射文件就可以保存在当前目录下dehello目录中.
  作为一种约定,Hibernatede映射文件默认以.htm.xml作为其扩展名.另一个约定是坚持为每一个持久类写一个配置文件,想一想如果您将所有持久类de映射写入一个单独de配置文件中de话,那这个配置文件肯定非常庞大,不易维护.但这里又出现了一个新问题:如果为每个类写一个配置文件de话,这么多de配置文件应该存放在哪里呢?
  Hibernate推荐您将每个映射文件保存在与持久类相同de目录下,并且与持久类同名.例如我第一个示例程序中deMessage持久类放在hello目录下,那您必须在这个目录下存放名为Message.hbm.xmlde映射文件.这样一个持久类都有自己de一个映射文件,避免了出现像struts项目中de“struts-config.xml地狱”de情况.如果您不遵循这种规定,那您必须手动地用addResource()方法将一个个de映射文件载入;但您如果遵循这种规定,那您可以方便地用addClass()方法同时将持久类和它de映射文件载入,以下是体现这种便利性de示例相关代码:
  SessionFactory sessions = new Configuration()
  .addClass(org.hibernate.auction.model.Item.class)
  .addClass(org.hibernate.auction.model.Category.class)
  .addClass(org.hibernate.auction.model.Bid.class)
  .setProperties( System.getProperties() )
  .buildSessionFactory();
  当然,Hibernatede映射文件还有很多其它de配置选项,比如数据库连接de设定,或是能够改变Hibernate运行时行为de一些设定.所有de设置可能是非常庞杂de,足以让您喘不过气来,但是不必担心,因为Hibernate为绝大多数值都设定了一个合理缺省值,您只需要修改这些配置文件中de极小一部分值.
  您可以通过以下几种方式来修改Hibernatede系统配置参数:
  · 将一个Java.util.Properties实例作为参数传给Configuration类desetProperties()方法.
  · 在Hibernate启动时用Java –Dproperty=valuede方式设置值.
  · 在classpath可以找到de路径下创建一个名为hibernate.propertiesde配置文件.
  · 在classpath可以找到de路径下创建一个名为hibernate.cfg.xmlde文件,并在其<property>标签中定义属性值.
  以上就是对Hibernatede一个大致介绍,如果您想知道得更多,那本文还是远远不够de,我将陆续推出更多关于Hibernatede资料.但有一点是毫无疑问de:它de确是一个非常优秀de持久层解决方案!

Tomcat5 Mssql server 2000数据库连接池配置之旅

星期一, 06月 2nd, 2008

Tomcat相信大家已经很熟悉了,作为一种免费而强大dejava web server,得到了很多java爱好者de青睐,最新版本detomcat5支持servlet2.4和jsp2.0,今天我将采用Tomcat5和Ms sqlserver 000一起来开始数据库连接池配置之旅.
需要de准备
1、jdk 我使用de版本1.4.01
2、Tomcat 5 我使用de是5.0.16版本 下载地址:http://jakarta.apache.org/site/binindex.cgi
3、Mssql server 2000 数据库
4、Mssql server 2000de官方jdbc driver ,可以到微软de官方网站免费下载

好了在安装完上面de软件之后,就进入配置实战了:)

一、找到jdbcde安装目录,把lib目录下面demsbase.jar和mssqlserver.jar、msutil.jar三个文件一起copy到$CATALINA_HOME/common/lib/($CATALINA_HOME代表de是您detomcat5de安装目录)

二、用文本编辑器,我这是使用editplus(她可是我de挚爱奥)打开$CATALINA_HOME/conf/server.xml文件,找到配置contextde地方,把下面de相关代码
粘贴到文件里面

<Context path=”/DBTest” docBase=”D:\rautinee work\db\”
debug=”5″ reloadable=”true” crossContext=”true”>

<Logger className=”org.apache.catalina.logger.FileLogger”
prefix=”localhost_DBTest_log.” suffix=”.txt”
timestamp=”true”/>

<Resource name=”jdbc/TestDB”
auth=”Container”
type=”javax.sql.DataSource”/>

<ResourceParams name=”jdbc/TestDB”>
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>

<!– Maximum number of dB connections in pool. Make sure you
configure your mysqld max_connections large enough to handle
all of your db connections. Set to 0 for no limit.
–>
<parameter>
<name>maxActive</name>
<value>100</value>
</parameter>

<!– Maximum number of idle dB connections to retain in pool.
Set to 0 for no limit.
–>
<parameter>
<name>maxIdle</name>
<value>30</value>
</parameter>

<!– Maximum time to wait for a dB connection to become available
in ms, in this example 10 seconds. An Exception is thrown if
this timeout is exceeded. Set to -1 to wait indefinitely.
–>
<parameter>
<name>maxWait</name>
<value>10000</value>
</parameter>

<!– MSSQLserver dB username and password for dB connections –>
<parameter>
<name>username</name>
<value>sa</value>
</parameter>
<parameter>
<name>password</name>
<value></value>
</parameter>

<!– Class name for mssqlserver JDBC driver –>
<parameter>
<name>driverClassName</name>
<value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
</parameter>

<!– The JDBC connection url for connecting to your mssqlserver dB.–>
<parameter>
<name>url</name>
<value>jdbc:microsoft:sqlserver://localhost:1433;databasename=Northwind</value>
</parameter>
</ResourceParams>
</Context>

注意:我本地de数据库desade密码为空,数据库使用de是Northwind,我de目录名DBTest,他de目录是D:\rautinee work\db\

打开DBTest下面deweb.xml文件,用下面de相关代码替换原来de内容

<?xml version=”1.0″ encoding=”ISO-8859-1″?>
<!DOCTYPE web-app PUBLIC
“-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN”
“http://java.sun.com/dtd/web-app_2_3.dtd”>
<web-app>
<description>MSSql server Test App</description>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>

ok,配置完成,下面de工作是需要编写两个文件测试一下,连接是否成功.

这里我用了http://jakarta.apache.org上面de例子

首先是bean文件

package foo;

import javax.naming.*;
import javax.sql.*;
import java.sql.*;

public class DBTest {

String foo = “Not Connected”;
int bar = -1;
public void init() {
try{
Context ctx = new InitialContext();
if(ctx == null )
throw new Exception(”Boom - No Context”);

DataSource ds = (DataSource)ctx.lookup(”java:comp/env/jdbc/TestDB”);

if (ds != null) {
Connection conn = ds.getConnection();
if(conn != null) {
foo = “Got Connection ” conn.toString();
Statement stmt = conn.createStatement();
ResultSet rst =
stmt.executeQuery(”select * from orders”);
if(rst.next()) {
foo=rst.getString(”CustomerID”);
bar=rst.getInt(”OrderID”);
}
conn.close();
}
}
}catch(Exception e) {
e.printStackTrace();
}
}

public String getFoo() { return foo; }
public int getBar() { return bar;}
}


然后是index.jsp文件

<html>
<head>
<title>DB Test</title>
</head>
<body>

<%
foo.DBTest tst = new foo.DBTest();
tst.init();
%>

<h2>Ms sql server 2000 java search Results</h2>
Foo <%= tst.getFoo() %><br/>
Bar <%= tst.getBar() %>

</body>
</html>
‘www.knowsky.com

编译运行,如果不出意外,应该检索到一条记录,

我deie中显示de是
Ms sql server 2000 java search Results
Foo VINET
Bar 10248

ok,配制成功!

参考文档:
http://jakarta.apache.org/tomcat/tomcat-5.0-doc/jndi-datasource-examples-howto.html 上面有mysql和oracle8ide连接教程,有兴趣de朋友可以上去看一下.

作者 海仔 email:rautinee@21cn.com http://www.tryitsoft.com

Windows下JSP开发环境的配置

星期一, 06月 2nd, 2008

  摘 要 要学习JSP开发,必须先搭建一个符合JSP规范de开发环境.本文以实用为原则,介绍了以Tomcat服务器为核心de3种配置JSP环境de方法.

  关键字 JSP引擎,Web服务器,配置
  Sun推出deJSP(Java Server Pages)是一种执行于服务器端de动态网页开发技术,它基于Java技术.执行JSP时需要在Web服务器上架设一个编译JSP网页de引擎.配置 JSP 环境可以有多种途径,但主要工作就是安装和配置Web服务器和JSP引擎.

  下面就以Tomcat作为JSP引擎,配合Tomcat、Apache、IIS这三种Web服务器来讲述3种搭建JSP运行环境de方案.

  一、相关软件介绍

  1、 J2SDK:Java2de软件开发工具,是Java应用程序de基础.JSP是基于Java技术de,所以配置JSP环境之前必须要安装J2SDK.

  2、 Apache服务器:Apache组织开发de一种常用Web服务器,提供Web服务.

  3、 Tomcat服务器:Apache组织开发de一种JSP引擎,本身具有Web服务器de功能,可以作为独立deWeb服务器来使用.但是,在作为Web服务器方面,Tomcat处理静态HTML页面时不如Apache迅速,也没有Apache健壮,所以我一般将Tomcat与Apache配合使用,让Apache对网站de静态页面请求提供服务,而Tomcat作为专用deJSP引擎,提供JSP解析,以得到更好de性能.并且Tomcat本身就是Apachede一个子项目,所以Tomcat对Apache提供了强有力de支持.对于初学者来说,Tomcat是一个很不错de选择.

  4、 mod_jk.dll:Apache组织Jakarta项目组开发de使Apache支持Tomcatde插件.有了这个插件,Tomcat能够和Apache进行无缝连接.

  5、 tc4ntiis.zip:Apache组织Jakarta项目组开发de使IIS支持Tomcatde插件.

  二、 软件下载

  1、j2sdk

  版本:j2sdk1.4.1(35.9MB)

  地址:http://java.sun.com/j2se/1.4.1/download.html

  2、Apache2

  版本:Apache2.0.43(6.69MB)

  地址:http://www.apache.inetcosmos.org/dist/httpd/binaries/win32/

  3、Tomcat4

  版本:4.1.21(8.33MB)

  地址:http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/

  4、mod_jk.dll: (136KB)

  地址:http://jakarta.apache.org/builds/jakarta-tomcat-connectors/jk/release/

  5、tc4ntiis.zip(220KB)

  地址:http://members.ozemail.com.au/~lampante/howto/tomcat/iisnt/tc4ntiis.zip

  以上均为免费软件.

  三、 配置前de准备

  (一)准备一个测试用deJSP网页

  打开文本编辑器,比如记事本,输入下列相关代码,并保存为test .jsp(注意扩展名为.jsp).

<HTML>
<HEAD>
<TITLE>JSP测试页面</TITLE>
</HEAD>
<BODY>
<%out.println(”<h1>Hello World! </h1>”);%>
</BODY>
</HTML>

  (二)安装J2SDK

  不管哪种方案,在安装和配置JSP引擎之前必须先完成J2SDKde安装.

  1、安装J2SDK

  在Windows下,直接运行下载dej2sdk-1_4_1_01-windows-i586.exe文件,根据安装向导安装到一个目录,例如安装到f:\j2sdk 1.4.1;

  2、 添加环境变量

  (1)如果您de操作系统是Win 98,可以用记事本直接编辑Autoexec.bat,添加下面命令行:

PATH=%PATH%;f:\j2sdk1.4.1\bin
SET JAVA_HOME=f:\j2sdk1.4.1
SET CLASSPATH=f:\j2sdk1.4.1\lib\tools.jar

  保存后,重新启动计算机,这样所添加de环境变量才会有效.

  (2)如果您de操作系统是Win2000,那么按如下方式配置环境变量.右键单击”我de电脑”,在弹出菜单中选择”属性”→”系统特性” →”高级” →”环境变量”, 弹出环境变量对话框,就可以编辑系统de环境变量了.添加PATH、JAVA_HOME和CLASSPATH三个变量,变量值同上.

  四、 JSP环境de配置方案

  (一)方案一:J2SDK+Tomcat

  在这种方案里Tomcat既作为JSP引擎又作为Web服务器,配置比较简单.

  1、安装Tomcat

  直接运行下载dejakarta-tomcat-4.0.1.exe,按照一般deWindows程序安装步骤即可安装好Tomcat,安装时它会自动寻找J2SDKde位置.例如安装到f:\tomcat4.

  2、配置Tomcatde环境变量

  添加一个新de环境变量TOMCAT_HOME,变量值为f:\tomcat4,添加方法同J2SDK环境变量de配置方法.

  3、测试默认服务

  设置完毕后就可以运行Tomcat服务器了.用f:\tomcat4\bin\startup.exe启动Tomcat,用f:\tomcat4\bin\shutdown.exe关闭.(如果在执行startup.exe或shutdown.exede时候提示Out of Environment Space错误,选择DOS 窗口de菜单中de”属性”→” 内存”→” 常规内存”, 把”初始环境”由”自动”修改成”2816″就可以了.)

  启动Tomcat后,打开浏览器,在地址栏中输入http://localhost:8080(Tomcat默认端口为8080),如果在浏览器中看到Tomcatde欢迎界面,表示Tomcat工作正常.

  4、测试项目

  把刚才准备好detest.jsp放在f:\Tomcat\webapps\examples\jsp目录下, 在地址栏中输入http://localhost:8080/examples/jsp/test.jsp,如果浏览器中显示”Hello World!”,则说明您deJSP环境配置成功了!

  由于Tomcat本身具有web服务器de功能,因此我不必安装Apache,当然它也可以与Apache集成到一起,下面介绍.

  (二)方案二:J2SDK+Apache+Tomcat

  虽然Tomcat也可以作Web服务器,但其处理静态HTMLde速度比不上Apache,且其作为Web服务器de功能远不如Apache,因此把Apache和Tomcat集成起来,用Apache充当Web服务器,而Tomcat作为专用deJSP引擎.这种方案de配置比较复杂,但是能让Apache和Tomcat完美整合,实现强大de功能.

  注意,因为IIS Web服务器默认使用80端口,而Apachede默认端口也是80,所以如果您使用de是Win2000操作系统,而且预装了IIS,为方便请在进行以下操作之前先将IIS服务停掉.

  1、安装Apache

  运行下载deapache_2.0.43-win32-x86-no_ssl.exe,按照向导安装到f:\Apache2.(注意,Apache2.0.43安装成功后,必须将f:\Apache2\htdocs目录下deindex.html.en改名为index.html,这样在测试默认服务时才会正常显示Apachede欢迎界面).

  2、测试Apache默认服务

  安装完后,Apache服务器就已经自动运行了.打开浏览器,在地址栏中输入:http://localhost (Tomcat默认端口为80),如果在浏览器中看到Apachede欢迎界面,说明Apache工作正常.

  3、 按照方案一de步骤安装Tomcat,并保证它正常运行.

  4、 将下载demod_jk-2.0.42.dll复制到f:\Apache2\modules目录下.

  5、 建立mod_jk模块工作所需要de工作文件.

  打开文本编辑器,输入下列语句:

workers.tomcat_home=f:\tomcat4 (让mod_jk模块知道Tomcat)
workers.java_home=f:\j2sdk1.4.1 (让mod_jk模块知道JSDK)
ps=\
worker.list=ajp13 (mod_jkde模块版本)
worker.ajp13.port=8009 (mod_jkde工作端口)
worker.ajp13.host=localhost
worker.ajp13.type=ajp13
worker.ajp13.lbfactor=1

  把上面de语句以workers.properties为文件名保存在f:\Tomcat4\conf目录下(注意:文件de扩展名是.properties).

  6、 配置Apache.

  用文本编辑器打开f:\Apache2\conf\httpd.conf

  1)找到”DirectoryIndex”,在index.html.var后面再添加index.jsp;

  2)在httpd.confde最后加入下面这段相关代码(括号里为解释)

LoadModule jk_module modules/mod_jk-2.0.42.dll
(装载mod_jk模块,用于处理Apache和Tomcatde连接)
JkWorkersFile “f:/tomcat4/conf/workers.properties”
(指出mod_jk模块工作所需要de工作文件workers.propertiesde位置)
JkMount /servlet/* ajp13
JkMount /*.jsp ajp13
(将所有servlet 和jsp请求通过Ajp13de协议送给Tomcat,让Tomcat来处理)

  3)添加完毕后保存.

  7、 配置Tomcat

  用文本编辑器打开f:\Tomcat4\conf\server.xml.因为Tomcat4默认不启用Ajp13,所以查找到如下这段相关代码:

<!–
<Connector className=”org.apache.ajp.tomcat4.Ajp13Connector”
port=”8009″ minProcessors=”5″ maxProcessors=”75″ acceptCount=”10″ debug=”0″/>
–>

  把注释符号<!– –> 删掉就可以启用Ajp13了.

  然后保存,现在Tomcat和Apachede整合配置基本完成了.

  8、 整体测试

  把test.jsp放在f:\Tomcat\webapps\examples\jsp 目录下,依次启动Apache2,Tomcat4.打开浏览器,在地址栏里输入http://localhost:8080/examples/jsp /test.jsp,如果浏览器中出现”Hello World!”,则Tomcat重新配置后工作正常;在地址栏中输入http://localhost/examples/jsp /test.jsp,若与http://localhost:8080/examples/jsp /test.jspde结果相同,那就表明Apache和Tomcat整合成功了!

  (三)方案三:J2SDK+IIS+Tomcat

  Windows平台下最常用deWeb服务器无疑是IIS,正常情况下IIS不支持JSP,我可以通过使用一个IIS到Tomcat重定向插件,使IIS能够将所有deJSP请求发送到Tomcat执行,可以使IIS增加处理JSPde功能.如果您已经习惯了使用IIS,那么可以尝试这种配置.(如果您已经安装过Apache服务器,为了便于后面de操作请先卸载Apache.)

  1、按照方案一de步骤安装Tomcat,并保证它正常运行.(例如安装到f:\tomcat4);

  2、将下载detc4ntiis.zip直接解压缩到f:\tomcat4目录下.查看配置所需要de文件,确保它们在以下位置:

f:\tomcat4\server\lib\ajp.jar
f:\tomcat4\server\lib\tomcat-util.jar f:\tomcat4\bin\native\isapi_redirect.dll f:\tomcat4\conf\ntiis\workers.properties f:\tomcat4\conf\ntiis\uriworkermap.properties f:\tomcat4\conf\ntiis\iis_redirect.reg
f:\tomcat4\log\iis_redirect.log

  3、用文本编辑器打开f:\tomcat4\conf\ntiis\workers.properties ,修改下列值为:

workers.tomcat_home=f:\tomcat4
workers.java_home=f:\j2sdk1.4.1


  4、双击f:\tomcat4\conf\ntiis\iis_redirect.reg ,将此注册文件内de信息添加到注册表中,但是要修改log_file、worker_file 、worker_mount_file这三个键de键值,以适合您de环境(比如本文中deTomcat就安装在f:\tomcat4,而不是默认dec:\tomcat4).添加并修改完毕后如下图.

  5、打开Internet服务管理器,在默认站点上添加一个新de虚拟目录,名称为jakarta,这个虚拟目录指向f:\tomcat4\bin\native ,并启动该默认站点.

  6、在Internet服务管理器中用鼠标右键单击服务器名,选择”属性”→主属性中”WWW服务”de”编辑” →”ISAPI筛选器”选项卡,添加一个ISAPI筛选器,名字为Jakarta Redirect,可执行文件指定为f:\Tomcat4\bin\native\isapi_redirector.dll.在添加ISAPI过滤器后, Jakarta Redirectde状态是一个红色de向下de箭头,重新启动IIS服务,就会变成绿色de箭头.

  7、编辑 server.xml 文件并保存(同方案二de第7步).

  8、重新启动IIS和Tomcat.

  9、测试项目:把test.jsp放在f:\Tomcat\webapps\examples\jsp 目录下.打开浏览器,在地址栏里输入http://localhost:8080/examples/jsp/test.jsp,如果浏览器中出现”Hello World!”,则Tomcat重新配置后工作正常;在地址栏中输入http://localhost/examples/jsp /test.jsp,若与http://localhost:8080/examples/jsp /test.jspde结果相同,那就表明IIS和Tomcat整合成功了!

  五、结束语

  搭建JSPde运行环境是学习JSP技术de基础,JSP引擎种类很多,配置方法也很多,而且软件de版本也在不断de升级,大家可以根据自己de需要和实际情况选择合适de配置方法.希望本文给出de几种JSP环境配置方案,对想学习JSPde人有所帮助.

win2000server IIS和tomcat5多站点配置

星期一, 06月 2nd, 2008

配置要求:IIS(win2000 server 自带)、Java 2 SDK 1.4.2 (或更高版本)、Tomcat Web Server 连接器、Tomcat 5.0.24 (或更高版本)

准备

一、Java 2 SDK 1.4.2 (或更高版本)
1、 www.java.sun.com/downloads/ 网站中下载,选择
2、 Java 2 Platform, Standard Edition (J2SE)
3、 在下拉列表框中选择All platforms
4、 J2SE v 1.4.2_04 SDK includes the JVM technology 下选择
5、 Download J2SE SDK
6、 选择accept后下载Windows Offline Installation, Multi-language (j2sdk-1_4_2_04-windows-i586-p.exe, 49.36 MB) 版本

二、Tomcat 5.0.24 (或更高版本)
1、http://jakarta.apache.org/site/binindex.cgi下载
2、在Downloads中选择Binaries
3、在Tomcat 5.0.25 KEYS 中选择5.0.25 exe PGP MD5 下载

三、Tomcat Web Server 连接器
1、http://jakarta.apache.org/site/binindex.cgi下载
2、在Downloads中选择Binaries
3、在Tomcat Web Server Connectors KEYS 中选择
4、JK 2
JK 2 Binary Releases
5、出现Index of/dist/jakarta/tomcat-connectors/jk2/binaries
界面,选择win32/然后选择下载
jakarta-tomcat-connectors-jk2.0.4-win32-IIS.zip
注意 这个目录列表显示de文件名称被截断,所以需要观察浏览器状态栏中de提示,确认您准备下载de文件应该是以\”…iis.zip\”为结尾de

安装

一、Java 2 SDK
运行j2sdk-1_4_2_04-windows-i586-p.exe 按照提示安装(可以更改安装路径到您习惯de地方).这里选择
d:\\jdk(jdk为自己新建de文件夹)

二、Tomcat 5
运行jakarta-tomcat-5.0.24.exe 按照提示安装(可以更改至其它路径).
这里选择d:\\tomcat5.0(tomcat5.0为自己新建de文件夹)
选择本地机器dejdk路径,一般情况下,安装文件会自动搜索并显示,如果没有正确显示,也可以手动更改
成功安装后,程序会提示启动tomcat并查看readme文档.
注意: 启动Tomcat之前要确定系统没有其它服务已经占用8080端口(Tomcat默认端口)和8009端口( Tomcat\’s AJP13 连接器端口)
Tomcat正常启动后会在系统栏加载图标
注意: tomcat5.0以下de版本必须设初始密码,tomcat5.0以上de可以不设

三、Tomcat JK2 IIS 连接器
解压缩jakarta-tomcat-connectors-jk2.0.4-win32-IIS.zip得到bin conf doc三个文件夹,进入\\bin\\后可见isapi_redirector2.dll.
剪切/复制isapi_redirector2.dll 文件到Tomcat\’s bin\\目录中
新建目录win32\\i386\\ 并粘贴isapi_redirector2.dll.
记住这个路径,稍后配置IISde时候还会用到.这个路径不是系统要求de,可改变!
现在可以删除jakarta-tomcat-connectors-jk2.0.4-win32-IIS目录,这里面de文件已经没用了.实际上在jakarta-tomcat-connectors-jk2.0.4-win32-IIS.zip中我只用到了isapi_redirector2.dll一个文件

设置
一、tomcat
进入 Tomcat\’s conf\\ 文件夹.
要支持 JK2 连接器, 您可能需要修改jk2.properties文件. 大多数情况下保留此文件de默认状态即可,本人de多次配置过程都没有修改过这个文件.

## THIS FILE MAY BE OVERRIDEN AT RUNTIME. MAKE SURE TOMCAT IS STOPED
## WHEN YOU EDIT THE FILE.

## COMMENTS WILL BE _LOST_

## DOCUMENTATION OF THE FORMAT IN JkMain javadoc.

# Set the desired handler list
# handler.list=apr,request,channelJni
# www.knowsky.com
# Override the default port for the socketChannel
# channelSocket.port=8019
# Default:
# channelUnix.file=${jkHome}/work/jk2.socket
# Just to check if the the config is working
# shm.file=${jkHome}/work/jk2.shm

# In order to enable jni use any channelJni directive
# channelJni.disabled = 0
# And one of the following directives:

# apr.jniModeSo=/opt/apache2/modules/mod_jk2.so

# If set to inprocess the mod_jk2 will Register natives itself
# This will enable the starting of the Tomcat from mod_jk2
# apr.jniModeSo=inprocess
request.tomcatAuthentication=false


设置环境变量tomcat_home.指向tomcatde安装目录d:\\Tomcat 5.0下.注意要求系统有可用JAVA_HOME环境变量

创建workers2.properties到d:\\Tomcat 5.0\\conf下.workers2.properties内容文件如下:
[shm]
file=\”d:/Tomcat 5.0/logs/jk2.shm\”
size=1048576

# Example socket channel, override port and host.
[channel.socket:localhost:8009]
port=8009
host=127.0.0.1

# define the worker
[ajp13:localhost:8009]
channel=channel.socket:localhost:8009

# Uri mapping
[uri:/*.jsp]
[uri:/servlet/*]
worker=ajp13:localhost:8009

三、Tomcat IIS 连接器
您已经放置isapi_redirector2.dll在您de路径下,本例子中是
d:\\Tomcat 5.0\\bin\\win32\\i386
现在需要添加一些必要de注册信息到注册表,redirector被IIS调用时会读到.建立一个.reg文件

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Apache Software Foundation\\Jakarta Isapi Redirector\\2.0]
\”workersFile\”=\”d:\\\\Tomcat 5.0\\\\conf\\\\workers2.properties\”
\”extensionUri\”=\”/jakarta/isapi_redirector2.dll\”
\”logLevel\”=\”debug\”
\”serverRoot\”=\”d:\\\\Tomcat 5.0\\\\\”
在记事本中写入上面de文字,并保存为 reg.reg
双击.reg文件,在注册表中de内容将会添加成功
HKEY_LOCAL_MACHINE\\SOFTWARE\\Apache Software Foundation\\Jakarta Isapi Redirector\\2.0中可以看到.

四、给Tomcat配制虚拟主机多个站点.
新建两个文件夹d:\\tomcat1和d:\\tomcat2.在两个文件夹里面再分别建立一个ROOT目录.

记事本打开d:\\Tomcat5.0\\conf\\server.xml文件.在文件server.xml中找到
标签;在标签之后新建如下信息:

www.tomcat1.com\” appBase=\”d:\\tomcat1\” >

www.tomcat2.com\” appBase=\”d:\\tomcat2\”>

主要就是新建两个虚拟主机www.tomcat1.com和www.tomcat2.com.站点目录分别是d:\\tomcat1和d:\\tomcat2.d:\\tomcat1\\ROOT和d:\\tomcat2\\ROOT.分别是两个站点de主目录.也建立了日志文件和访问日志文件.

五、打开tomcatde/servlet/*de映射.
记事本打开d:\\Tomcat 5.0\\conf\\web.xml文件.

invoker
org.apache.catalina.servlets.InvokerServlet

debug
0
2

invoker
/servlet/*
这两个相关代码段de注释去掉,使其生效.

六、在iis中建立两个站点tomcat1和tomcat2.建立时注意主机头分别设成www.tomcat1.com和www.tomcat2.com.主目录分别设成d:\\tomcat1\\ROOT和d:\\tomcat2\\ROOT.两个站点分别建立名称为jakartadeISAPI筛选器.可执行文件都指向d:\\Tomcat 5.0\\conf\\connector\\isapi_redirector2.dll.

两个站点分别新建虚拟目录别名都填:jakarta,目录选择指向:d:\\Tomcat 5.0\\bin\\win32\\i386在\”执行(例如ISAPI应用程序或CGI)\”一项打上勾,完成.

IIA筛选器
再进行筛选器de选择时,选用jakarta可执行文件为d:\\Tomcat 5.0\\bin\\win32\\i386
建筛选器所需要de虚拟目录
选择需要加载Tomcat服务站点,右键选择新建,再选择虚拟目录.创建虚拟目录,别名为jakarta.注意这个名字是固定值,不要拼写错误!指定目录为isapi_redirector2.dll所在目录. 本例子中是 d:\\Tomcat 5.0\\bin\\win32\\i386
重启tomcat和iis.

在tomcat1和tomcat2文件夹下最好放一个index.htm和一个index.jsp文件.方便测试.

JSP连接SQL Server 2000系统配置

星期一, 06月 2nd, 2008

  第一步:—-安装J2SDK:

  到SUN官方站点(http://java.sun.com)下载J2SDKde安装文件:j2sdk-1_4_2_04-windows-i586-p.exe,下载之后安装好J2SDK;安装完之后,设置环境变量:我de电脑—属性—高级—环境变量;

  选择—系统变量(S):
 
  设置JAVA_HOME环境变量:

  单击—新建,在变量名中输入:JAVA_HOME

  在变量值中输入:D:\Java

  (假设J2SDK安装在目录D:\Java下,反正就是J2SDKde安装目录.)

  然后—确定,到此已经设置好JAVA_HOME环境变量.

  设置CLASSPATH环境变量:

  单击—新建,在变量名中输入:CLASSPATH

  在变量值中输入:D:\Java\bin;.;D:\Java\lib;D:\Java\lib\dt.jar;D:\Java\lib\tools.jar

  (中间de点号“.”和分号“;”必不可少.)

  然后—确定,到此已经设置好CLASSPATH环境变量.

  设置PATH环境变量:

  单击—新建,在变量名中输入:PATH

  在变量值中输入:D:\Java;.;D:\Java\bin

  (中间de点号“.”和分号“;”必不可少.)

  然后—确定,到此已经设置好JAVA_HOME环境变量.

  三个环境变量设置好后,写一个简单dejava程序来测试J2SDK是否已安装成功:

  在D:\下新建一个目录test;然后写如下程序: 
  public class Test { 
  public static void main(String args[]) { 
    System.out.println(”This is a test program.”); 
   } 
  }

  将上面de这段程序保存为文件名为Test.javade文件,保存在目录D:\test下.

  然后打开命令提示符窗口,cd到您detest目录,然后键入下面de命令  

    javac Test.java 
    java Test 

  此时如果看到打印出来This is a test program.de话说明安装成功了,

  如果没有打印出这句话,您需要仔细检查一下您de配置情况. 

  如果上面deJ2SDK安装成功de话,接下来继续安装Tomcat:

  第二步:—-安装Tomcat:

   到tomcat官方站点(http://www.apache.org/dist/jakarta/tomcat-4/)下载tomcat:

   jakarta-tomcat-4.1.30.exe,下载之后安装.(比如安装在D:\Tomcat下.)

   安装完之后,设置环境变量:我de电脑—属性—高级—环境变量;

   选择—系统变量(S):

   设置CATALINA_HOME环境变量:

   单击—新建,在变量名中输入:CATALINA_HOME

   在变量值中输入:D:\Tomcat

   然后—确定,到此已经设置好CATALINA_HOME环境变量.

   设置CATALINA_BASE环境变量:

   单击—新建,在变量名中输入:CATALINA_BASE

   在变量值中输入:D:\Tomcat

   然后—确定,到此已经设置好CATALINA_BASE环境变量.

   然后修改环境变量中deCLASSPATH,把Tomat安装目录下decommon\lib下deservlet.jar追加到CLASSPATH中去,

   修改后deCLASSPATH如下: 

CLASSPATH=D:\Java\bin;.;D:\Java\lib;D:\Java\lib\dt.jar;D:\Java\lib\tools.jar;
D:\Tomcat\common\lib\servlet.jar 

   接着可以启动tomcat,在IE中访问http://localhost:8080,如果看到tomcatde欢迎页面de话说明安装成功了.

   如果上面detomcat安装成功de话,接下来继续安装JSP访问SQL Server 2000de驱动程序:

  第三步:—-安装JSP访问SQL Server 2000de驱动程序:

   从微软de网站上下载驱动程序:SQL Server 2000 For JDBC 驱动程序,在Google中随便搜索就有.

   然后将它安装好.(比如安装目录是D:\SQLDriverForJDBC.)

   然后必须将安装目录中delib目录下三个jar文件:

   msbase.jar,mssqlserver.jar,msutil.jar拷贝到Tomcat目录下common\lib目录下,之后,修改环境变量中deCLASSPATH,
把SQL Server 2000 For JDBC 驱动程序安装目录下de
D:\SQLDriverForJDBC\lib\msbase.jar;D:\SQLDriverForJDBC\lib\mssqlserver.jar;
D:\SQLDriverForJDBC\msutil.jar;
追加到CLASSPATH中去,修改后deCLASSPATH如下: 

CLASSPATH=D:\Java\bin;.;D:\Java\lib;D:\Java\lib\dt.jar;
_D:\Java\lib\tools.jar;D:\LubeeTomcat\common\lib\servlet.jar;
_D:\SQLDriverForJDBC\lib\msbase.jar;D:\SQLDriverForJDBC\lib\mssqlserver.jar;
D:\SQLDriverForJDBC\msutil.jar

    必须重新启动Tomcat!

    这样做de目de是,jsp页面在编译过程中不会出现找不到sql server driver类库de问题

  写一个简单de用来测试连接SQL Server 2000deJSP相关代码

  <%@ page import=”java.lang.*, java.io.*, java.sql.*, java.util.*” contentType=”text/html;charset=gb2312″ %>
  <html>
  <body>
  <% Class.forName(”com.microsoft.jdbc.sqlserver.SQLServerDriver”).newInstance();
   String url=”jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs”;
   //pubs 为您de数据库de
   String user=”sa”;
   String password=”admin”;
   Connection conn= DriverManager.getConnection(url,user,password);
   Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
   String sql=”select job_id,job_desc from jobs”;
   ResultSet rs=stmt.executeQuery(sql);
   while(rs.next()) { %>
    您de第一个字段内容为:<%=rs.getString(1)%><br>
    您de第二个字段内容为:<%=rs.getString(2)%><br>
  <% } %>
  <% out.print(”数据库操作成功,恭喜您”); %>
  <% rs.close();
   stmt.close();
   conn.close();
  %>
  </body>
  </html>

  将上面deJSP相关代码保存为sql_test.jsp,放在/Root目录下.

  在地址中输入:http://localhost:8080/sql_test.jsp,如果全部配置成功de话,将显示如下:

  您de第一个字段内容为:1
  您de第二个字段内容为:New Hire - Job not specified
  您de第一个字段内容为:2
  您de第二个字段内容为:Chief Executive Officer
  您de第一个字段内容为:3
  您de第二个字段内容为:Business Operations Manager
  您de第一个字段内容为:4
  您de第二个字段内容为:Chief Financial Officier
  您de第一个字段内容为:5
  您de第二个字段内容为:Publisher
  您de第一个字段内容为:6
  您de第二个字段内容为:Managing Editor
  您de第一个字段内容为:7
  您de第二个字段内容为:Marketing Manager
  您de第一个字段内容为:8
  您de第二个字段内容为:Public Relations Manager
  您de第一个字段内容为:9
  您de第二个字段内容为:Acquisitions Manager
  您de第一个字段内容为:10
  您de第二个字段内容为:Productions Manager
  您de第一个字段内容为:11
  您de第二个字段内容为:Operations Manager
  您de第一个字段内容为:12
  您de第二个字段内容为:Editor
  您de第一个字段内容为:13
  您de第二个字段内容为:Sales Representative
  您de第一个字段内容为:14
  您de第二个字段内容为:Designer
  数据库操作成功,恭喜您 
 
  以上所有de内容涉及de相关条件:

  操作系统:Window 2000 Server
  J2SDK版本:j2sdk-1_4_2_04-windows
  Tomcat版本:jakarta-tomcat-4.1.30
  本地数据库:SQL Server 2000

用定制标签库和配置文件实现对JSP页面元素的访问控制

星期一, 06月 2nd, 2008

控制客户端访问是开发一个基于B/Sde架构de系统de开发者必须考虑de问题.JSPSERVLET规范de基于配置文件de安全策略对资源de控制是以文件为单位de,即只可以定义某个视图全部可以或全部不能被访问.一个比较复杂de系统往往要要求对视图de一部分(如JSP页面里de一个按钮)提供访问控制,只允许被某种角色de用户访问.如果采用可编程de安全策略,因为对用户角色和操作de定义在开发时不能定义,而且这种策略加大了程序员de工作量,它可能不是一种好de办法.

我采用定制标签库和和配置文件来解决这个问题:把要权限控制deJSP页面元素如BUTTON,作为标签de内容.为受保护de内容起一个唯一de名称,把这个名称作为标签de一个属性.某个角色对某个页面元素或一组页面元素是否有权限,在XML配置文件中描述.

例如,下面deJSP页面有“详细”和“修改”两个按钮.

<%@ taglib uri=”http://mytag” prefix=”custTag” %>

<html>

<head>

<title>test</title>

</head>

<body >

<form name=”form1″ >

<table width=”600″ border=”0″ cellspacing=”0″ cellpadding=”2″ >

<tr>

<td>

<custTag:JspSecurity elementName=”employeedetail” >

<input type=”button” name=”detail” value=”详细” >

</custTag:JspSecurity>

<custTag:JspSecurity elementName=”employeemodify” >

<input type=”button” name=”modify” value=”修改” >

</custTag:JspSecurity>

</td>

</tr>

</table>

<br>

</form>

</body>

下面XML配置文件内容表示对角色为commonde用户,只对名为employeedetail de页面元素即“详细”按钮有权限,对角色为“admin”de用户,对名为employeedetail employeemodifyde页面元素即两个按钮都有权限.

<?xml version=”1.0″ encoding=”GB2312″?>

<security>

<htmlElement name=”employeedetail” >

<roleName name=”common” />

<roleName name=”admin” />

</htmlElement>

<htmlElement name=”employeemodify” >

<roleName name=”admin” />

</htmlElement>

</security>

定制标签类JspSecurityTag继承了BodyTagSupport类.BodyTagSupport有一个变量bodyContent指向起始标志和结束标志之间de内容.JspSecurityTagde私有静态变量roleList保存从XML文件中取到角色和页面元素de对应集合,私有变量ElementName对应页面元素de名称.当解析该定制标签时,首先先取到页面元素de名称,再取到当前用户de角色,如果角色有该页面元素de权限,就显示标签正文(即页面元素),否则不显示.

Pagekage com.presentation.viewhelper.JspSecurityTag;

import javax.servlet.jsp.tagext.*;

import javax.servlet.jsp.*;

import java.util.*;

import org.xml.sax.*;

import org.xml.sax.helpers.*;

import org.w3c.dom.*;

import java.io.*;

import javax.xml.parsers.*;

public class JspSecurityTag extends BodyTagSupport {

//保存从XML文件中取到角色和页面元素de对应集合

private static ArrayList roleList;

//页面元素de名称

private String elementName;

public void setElementName(String str)

{

this.elementName=str;

}

public int doAfterBody() throws JspException{

if(roleList==null)

{

roleList=getList();

}

try{

//如果认证通过就显示标签正文,否则跳过标签正文,就这么简单

if(isAuthentificated(elementName))

{

if(bodyContent != null){

JspWriter out=bodyContent.getEnclosingWriter();

bodyContent.writeOut(out);

}else

{

}

}

}catch(Exception e){

throw new JspException();

}

return SKIP_BODY;

}

//XML配置文件中取到角色和页面元素de对应,保存到静态deArrayList

private ArrayList getList()

{

DocumentBuilderFactory dbf =

DocumentBuilderFactory.newInstance();

DocumentBuilder db = null;

Document doc=null;

NodeList childlist = null;

String elementName;

String roleName;

int index;

ArrayList theList = new ArrayList();

try{

db = dbf.newDocumentBuilder();

}catch(Exception e)

{

e.printStackTrace();

}

try{

doc = db.parse(new File(”security.xml”));

}catch(Exception e)

{

e.printStackTrace();

}

//读取页面元素列表

NodeList elementList = doc.getElementsByTagName(”htmlElement”);

for(int i=0;i<elementList.getLength();i )

{

Element name = ((Element)elementList.item(i));

//页面元素de名称

elementName = name.getAttribute(”name”);

//该页面元素对应de有权限de角色de列表

NodeList rolNodeList = ((NodeList)name.getElementsByTagName(”roleName”));

for(int j=0;j<rolNodeList.getLength();j )

{

//有权限de角色de名称

//roleName = ((Element)rolNodeList.item(j)).getNodeValue();

roleName = ((Element)rolNodeList.item(j)).getAttribute(”name”);

theList.add(new ElementAndRole(elementName,roleName));

}

}

return theList;

}

//检查该角色是否有该页面元素de权限

private boolean isAuthentificated(String elementName)

{

String roleName = “”;

//在用户登陆时把该用户de角色保存到SESSION中,这里只是直接从SESSION中取用//户角色.

roleName=this.pageContext.getSession().getAttribute(”rolename”);

// roleList包含elementName属性为elementName,roleName属性为roleNamede//ElementAndRole对象,则该角色有该页面元素de权限

if(roleList.contains(new ElementAndRole(elementName,roleName)))

{

return true;

}

}

return false;

}

//表示角色和页面元素de对应de关系de内部类

class ElementAndRole{

String elementName;

String roleName;

public ElementAndRole(String elementName,String roleName)

{