posts - 120,  comments - 19,  trackbacks - 0
 
     摘要: 美洲豹 美洲豹汽车公司原是利兰汽车公司的分部,素以生产豪华的美洲豹 ( 又称捷豹 ...  阅读全文
posted @ 2006-05-23 08:47 阿成 阅读(249) | 评论 (0)编辑 收藏

用Validator(验证器)提供的丰富的内置验证方法简化Struts的开发过程。

Struts框架的一个主要好处是它提供了对接收到的表单数据进行验证的内置界面。如果有任何验证失败,则应用程序都会重新显示HTML表单,这样就可以改正无效的数据了。如果验证成功,则处理过程会继续进行。Struts框架的简单验证界面会减少与处理数据验证有关的令人头疼的事情,这样你就可以把精力集中到验证代码上,而不是放到捕获数据、重新显示不完整或无效数据的技巧上。

但是,Struts内置的验证界面也有缺点。例如,在整个应用程序中验证代码常常会大量重复,因为许多域需要相同的验证逻辑。对一些相似字段的验证逻辑进行任何修改都要求在几个地方修改代码,还要重新编译受影响的代码。为了解决这个问题并增强Struts验证界面的功能,作为Struts的第三方附加件创建了Validator框架。后来,Validator被集成到核心Struts代码库中,并从Struts中分离出来,现在它是一个独立的Jakarta Commons项目。虽然Validator是一个独立的框架,但它仍能与其他程序封装在一起后提供,并与Struts无缝集成。

Validator概述

没有Validator,你就不得不编写验证表单数据所需的全部代码,并把它放入Form Bean对象的validate( )方法中。对于想在其上进行数据验证的每个Form Bean域来说,都需要编写逻辑代码来实现验证。此外,你还必须编写代码来存储验证失败时的出错消息。

有了Validator,你就不必在Form Bean中编写用于验证或存储错误消息的任何代码。相反,Form Bean提供了Validator的一个ActionForm子类,它提供验证或存储错误消息的功能。

可把Validator框架作为一个可用于Form Bean验证的可插入的验证例行程序系统来进行安装。每个验证例行程序都只是一个Java方法,负责执行特定类型的验证任务,验证可能通过,也可能失败。 默认情况下,Validator与几个有用的验证例行程序封装在一起来提供,这些例行程序能满足大多数情况下的验证要求。但是,如果Validator框架没有提供你需要的验证例行程序,那么你可以自己创建定制的验证例行程序,并将它插入到该框架中。此外,Validator还支持服务器端和客户端(JavaScript)的验证,而Form Bean只提供服务器端验证界面。

Validator使用两个XML配置文件来分别确定安装哪个验证例行程序和如何将它们应用于给定的应用程序。第一个配置文件validator-rules.xml说明应该被插入到框架中的验证例行程序,并提供每个验证的逻辑的名称。validator-rules.xml文件还定义了每个验证例行程序的客户端JavaScript代码。可以配置Validator让它把这个JavaScript代码发送到浏览器上,这样验证就可以在客户端和服务器端进行了。

第二个配置文件validation.xml确定哪个验证例行程序应用到哪个Form Bean。文件中的定义使用struts-config.xml文件给出的Form Bean的逻辑名称以及validator-rules.xml文件给出的验证例行程序的逻辑名称,以便把二者关联起来。

使用Validator框架包括启用Validator插件、配置Validator的两个配置文件,以及创建提供Validator的ActionForm子类的Form Beans。下面详细解释如何配置和使用Validator。

启用Validator插件

虽然Validator框架是与Struts封装在一起提供的,但在默认状况下Validator并不被启用。为了启用Validator,要向你的应用程序的struts-config.xml文件中添加下面的插件定义。

<!-- Validator Configuration -->
<plug-in className="org.apache.struts
.validator.ValidatorPlugIn">
  <set-property property="pathnames"
               value="/WEB-INF/
  validator-rules.xml, /WEB-INF/

  validation.xml"/>
</plug-in>

该定义告诉Struts为你的应用程序加载并初始化Validator插件。在初始化时,该插件装入由路径名属性指定的、用逗号分隔的Validator配置文件清单。每个配置文件的路径应该用与Web应用程序的相关的路径来指定,如前面的例子所示。

请注意,你的应用程序的struts-config.xml文件必须与Struts Configuration Document Type Definition(Struts配置文档类型定义,DTD)一致,后者规定文件中元素出现的顺序。所以,你必须把Validator插件定义放到该文件的适当位置。确保文件中元素适当排列的最简便方法就是使用诸如Struts Console的工具,它自动格式化你的配置文件,以便与DTD保持一致。

配置validator-rules.xml

Validator框架可以设置为可插入系统,其验证例行程序仅仅是插入到该系统中执行具体验证的Java方法。validator-rules.xml文件说明性地插入Validator用于执行验证的验证例行程序中。Struts示例应用程序带有这个文件的预配置拷贝。在大多数情况下,你不必修改这个预配置拷贝,除非你要向该框架中添加自己定制的验证。

清单1 是一个示例validator-rules.xml文件,说明如何将验证例行程序插入到Validator中。validator-rules.xml文件中的每个验证例行程序都有自己的定义,它用validator标记声明,利用name属性为该验证例行程序指定逻辑名,并指定该例行程序的类和方法。该例行程序的逻辑名称供该文件中的其他例行程序以及validation.xml文件中的验证定义用于引用该例行程序。

请注意,validator标记放在javascript的标记中,javascript标记用于定义客户端JavaScript代码,以便在客户端执行与服务器端相同的验证。

提供的验证程序

默认情况下,Validator中包括几个基本验证例行程序,你可以用它们来处理大多数验证问题。这些例行程序具有逻辑名称,如required(用于输入要求的值)、CreditCard(用于输入信用卡号码值)、email(用于输入电子邮件地址值),等等。

创建Form Bean

为了使用Validator,你的应用程序的Form Bean必须归到Validator的ActionForm的某一子类,而不是ActionForm本身。Validator的ActionForm子类提供了ActionForm的validate( )方法(它嵌入到Validator框架中)的实施过程。你不必从头编写验证代码并把它投入validate( )方法中,相反,可以完全忽略该方法,因为Validator为你提供了验证代码。

与Struts提供的核心功能相类似,Validator提供给你两种可供选择的方法来创建Form Bean。 你可以选择的第一种方法就是像下面这样创建一个特定的Form Bean对象:

package com.jamesholmes.minihr;

import org.apache.struts.validator
.ValidatorForm;


public class LogonForm extends ValidatorForm {
  private String username;
  private String password;
  
  public String getUsername() {
    return username;
  }
  
  public void setUsername(String 
username) {
    this.username = username;
  }


  public String getPassword() {
    return password;
  }
public void setPassword(String 
password) {
    this.password = password;
  }
}

这个类与你不是用Validator所创建的类相似,但它提供ValidatorForm而不是ActionForm。这个类也不提供ActionForm的空reset( )和validate( )方法的实施过程,因为ValidatorForm提供了相应过程。

在struts-config.xml文件中配置这个特定Form Bean的方法与配置正则Form Bean的方法相同:

<form-beans>
  <form-bean name="logonForm"
            type="com.jamesholmes
  .minihr.LogonForm"/>
</form-beans>

用表单标记的name属性给特定Form Bean指定的逻辑名是在定义validation.xml文件中的验证时所使用的名称,如下所示:

<!DOCTYPE form-validation 
PUBLIC "-//Apache Software Foundation//
       DTD Commons Validator Rules
       Configuration 1.0//EN"
       "http://jakarta.apache.org/
      commons/dtds/validator_1_0.dtd">


<form-validation>
  <formset>
    <form name="logonForm">
      <field property="username" 
            depends="required">
        <arg0 key="prompt.username"/>
      </field>
    </form>
  </formset>
</form-validation>

Validator使用该表单标记的name属性的值将验证定义与要应用这些定义的Form Bean的名称相匹配。

创建Form Bean时可以选择的第二种方法是在struts-config.xml文件中定义一个动态Form Bean,如下所示:

<form-beans>
  <form-bean name="logonForm"
            type="org.apache
.struts.validator.DynaValidatorForm">
    <form-property name="username"
            type="java.lang.String"/>
    <form-property name="password"
            type="java.lang.String"/>
  </form-bean>
</form-beans>

动态Form Bean不要求创建特定的Form Bean对象;相反,要定义Form Bean应该具有的属性和类型,而Struts为你动态创建Form Bean。 Validator允许你使用这个概念,就像在核心Struts中使用这个概念一样。与使用Validator的惟一区别就是要指定Form Bean是org.apache.struts.validator.DynaValidatorForm类型,而不是org.apache.struts.action.DynaActionForm类型。

分配给动态Form Bean的逻辑名是在定义validation.xml文件中的验证时使用的名称。Validator使用与之相匹配的名称将这些验证与Form Bean联系在一起。

除了创建Form Bean的这两种标准方法之外,Validator还提供了一个高级特性,用于将多个验证定义与一个Form Bean定义联系起来。当你使用基于validatorForm或基于DynaValidatorForm的Form Bean时,Validator使用struts-config.xml文件中的Form Bean的逻辑名称,将Form Bean映射到validation.xml文件中的验证定义。这种机制在大多数情况下非常有用,但在某些时候,Form Bean要在多个操作中共享。 一个操作可能使用Form Bean的所有域(fields),而另一个操作可能只使用这些域的一个子集。因为验证定义被连接到Form Bean,所以只使用域的一个子集的操作就无法绕过对未使用域的验证。当验证Form Bean时,就会对未使用的域生成错误消息,因为Validator无从知道不去验证未使用的域,它只是简单地把它们看作缺失或无效。

为了解决这个问题,Validator提供了两个附加的ActionForm子类,它使你能够将验证与操作相关联,而不是与Form Bean相关联。这样你就可以根据哪个操作正在使用Form Bean来指定把哪些验证用于该Form Bean了。对于特定的Form Bean,你要像下面这样声明org.apache.struts.validator.ValidatorActionForm子类:

public class AddressForm extends ValidatorActionForm {
  ...
}

对于动态Form Bean,在struts-config.xml文件中为Form Bean定义指定org.apache.struts.validator.DynaValidatorActionForm的类型,如下所示:

<form-bean name="addressForm"
          type="org.apache.struts
.validator.DynaValidatorActionForm">
  ...
</form-bean>

在validation.xml文件中,把一组验证映射到一个操作路径,而不是映射到Form Bean名,因为如果你定义了Create Address和Edit Address两个操作(它们使用同一个Form Bean),那么每个操作都会有一个惟一的操作名,如下所示:

<action-mappings>
  <action path="/createAddress"
         type="com.jamesholmes
  .minihr.CreateAddressAction"
         name="addressForm"/>
  <action path="/editAddress"
         type="com.jamesholmes
  .minihr.EditAddressAction"
         name="addressForm"/>

</action-mappings>

下面的validation.xml文件片断显示了两组验证,它们用于同一个Form Bean,但却有不同的操作路径:

<formset>
  <form name="/createAddress">
    <field property="city"
          depends="required">
      <arg0 key="prompt.city"/>
    </field>
  </form>
  <form name="/editAddress">
    <field property="state"
          depends="required">
      <arg0 key="prompt.state"/>
    </field>
  </form>
</formset>

因为Form Bean要么属于ValidatorActionForm子类,要么属于DynaValidatorActionForm子类,所以Validator知道用一个操作路径代替Form Bean的逻辑名称来找出用于Form Bean的验证。

配置validation.xml文件

validation.xml文件用于声明将应用到Form Beans的一组验证。要验证的每个Form Bean在这个文件中都有自己的定义。在这个定义中,指定要应用到该Form Bean的各域的验证。下面是一个validation.xml文件的例子,说明如何定义验证:

<!DOCTYPE form-validation 
PUBLIC "-//Apache Software Foundation//
       DTD Commons Validator Rules
       Configuration 1.0//EN"
       "http://jakarta.apache.org/
      commons/dtds/validator_1_0.dtd">

<form-validation>
  <formset>
    <form name="logonForm">
      <field property="username"
            depends="required">
        <arg0 key="prompt.username"/>

      </field>
      <field property="password"
            depends="required">
        <arg0 key="prompt.password"/>
      </field>
    </form>
  </formset>
</form-validation>

validation.xml文件的第一个元素是form-validation。这个元素是该文件的主元素,而且只定义一次。在form-validation元素内定义form-set元素,它包括多个表单元素。一般来说,在文件中只定义一个form-set元素,但是如果要将验证国际化,那就要在每个地方单独使用一个form-set元素。

每个表单元素使用name属性将名称与其所包含的域验证集关联起来。Validator使用这个逻辑名称将这些验证映射到在struts-config.xml文件中定义的一个Form Bean。根据要验证的Form Bean的类型,Validator力求将该名称与Form Bean的逻辑名称或操作路径相匹配。在表单元素内,field元素定义要应用到Form Bean的特定域的验证。field元素的property属性对应于特定Form Bean中的域名。depends属性利用validator-rules.xml文件指定验证例行程序的逻辑名称,这些例行程序将应用到域验证中。

配置ApplicationResources.properties

Validator使用Struts的资源绑定(Resource Bundle)机制将错误消息具体化。不用在框架中对错误消息进行硬编码,Validator使你能在ApplicationResources.properties文件中为一个消息指定一个键值,如果验证失败则将返回该键值。validator-rules.xml文件中的每个验证例行程序都用validator标记的msg属性指定错误消息的键值,如下所示:

<validator name="required"
          classname="org.apache

.struts.validator.FieldChecks"
          method="validateRequired"
          methodParams="java.lang
.Object, org.apache.commons.validator
.ValidatorAction, org.apache.commons
.validator.Field, org.apache.struts
.action.ActionErrors, javax.servlet
.http.HttpServletRequest"
          msg="errors.required">

如果在验证例行程序运行时验证失败,则返回与msg属性指定的键值对应的消息。

下面的片段显示来自ApplicationResources.properties文件的验证出错时的默认消息集,它们由Struts示例应用程序提供。每个消息的键值对应于每个由validator-rules.xml文件中的验证例行程序所指定的消息,它们由Struts示例应用程序提供。

# Error messages for Validator framework validations
errors.required={0} is required.
errors.minlength={0} cannot be less than {1} characters.
errors.maxlength={0} cannot be greater than {2} characters.
errors.invalid={0} is invalid.
errors.byte={0} must be a byte.
errors.short={0} must be a short.
errors.integer={0} must be an integer.
errors.long={0} must be a long.0.   errors.float={0} must be a float.

errors.double={0} must be a double.
errors.date={0} is not a date.
errors.range={0} is not in the range {1} through {2}.
errors.creditcard={0} is not a valid credit card number.
errors.email={0} is an invalid e-mail address.

请注意,每条消息都有占位符,形式为{0}、{1}或{2}。在运行期间,占位符被另一个值代替,如所验证的域的名称。这一特性特别有用,它使你能够创建可被几个不同的域重复使用的通用验证错误消息。

例如,下面给出required验证的错误消息errors.required:

errors.required={0} is required.

当你使用validation.xml文件中的该required验证时,必须定义用于替换该错误消息中的{0}的值,如下所示:

<form name="auctionForm">
  <field property="bid" depends="required">
    <arg0 key="prompt.bid"/>
  </field>
</form>

错误消息最多可以有4个占位符:{0}和{3}。这些占位符分别称为arg0到arg3,你可以通过使用arg0~arg3标记来指定它们。在上面的例子中,arg0标记指定了用于替换{0}占位符的值。该标记的key属性指定来自ApplicationResources.properties文件的一个消息键值,它的值用于替换占位符,如下所示:

下一步

阅读
关于Validator的更多文章
jakarta.apache.org/commons/validator

关于Struts Console的更多文章
www.jamesholmes.com/struts

prompt.bid=Auction Bid

使用消息键值代替占位符的值,这一方法使你不必在validation.xml文件中对替换值反复硬编码。但是,如果你不想使用Resource Bundle的键值/值机制来指定占位符的值,则可以使用arg0标记的如下语法显式地指定占位符的值:

<arg0 key="Auction Bid" resource="false"/>

在这个例子中,resource属性的值设为false,以便通知Validator要把该key属性指定的值作为占位符的值,而不要作为ApplicationResources.properties文件中消息的一个键值。

启用客户端验证

Validator除了提供了简化服务器端表单数据验证过程的框架外,它还提供了执行客户端验证时易于使用的方法。在validator-rules.xml文件中定义的每一个验证例行程序都可以随意指定JavaScript代码,这些代码可以在浏览器(客户端上的)中运行,从而执行与服务器端进行的验证相同的验证过程。在客户端进行验证时,除非所有表单都通过验证,否则这些表单不允许被提交。

为了启用客户端验证,必须在每个需要验证的JSP中放上Struts HTML Tag Library(标记库)的javascript标记,如下所示:

<html:javascript formName="logonForm"/>

javascript标记要求使用formName属性来为想要对其执行验证的表单指定validation.xml文件中给出的表单定义名,如下所示:

<form name="logonForm">
  <field property="username"
        depends="required">
    <arg0 key="prompt.username"/>
  </field>
  <field property="password"
        depends="required">
    <arg0 key="prompt.password"/>
  </field>
</form>

为表单定义指定的服务器端的所有验证都将在客户端运行。由于客户端验证用JavaScript执行,所以可以有多种方法不去执行它。要确保验证过程总是能运行,不论你是否选择启用了客户端验证,Validator都在服务器端执行这些验证。

结论

Validator框架针对表单数据的验证提供了可配置的系统,从而为核心Struts框架添加了很多有价值的功能。通过把Validator框架用于你的应用程序,你可以节约时间并简化Struts应用程序的开发过程。

posted @ 2006-05-11 14:52 阿成 阅读(287) | 评论 (0)编辑 收藏

工厂模式定义:提供创建对象的接口.
为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,
我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来
创建实例对象的,所以以后new时就要多个心眼,是否可以考虑实用工厂模式,
虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少
的修改量。

我们以类Sample为例, 如果我们要创建Sample的实例对象:
 Sample sample=new Sample();
可是,实际情况是,通常我们都要在创建sample实例时做点初始化的工作,比如
赋值 查询数据库等。首先,我们想到的是,可以使用Sample的构造函数,这样
生成实例就写成:  Sample sample=new Sample(参数);
但是,如果创建sample实例时所做的初始化工作不是象赋值这样简单的事,可能
是很长一段代码,如果也写入构造函数中,那你的代码很难看了(就需要Refactor重整)。
为什么说代码很难看,初学者可能没有这种感觉,我们分析如下,初始化工作如果
是很长一段代码,说明要做的工作很多,将很多工作装入一个方法中,相当于将很多鸡
蛋放在一个篮子里,是很危险的,这也是有背于Java面向对象的原则,面向对象的
封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派“切割”成
每段,将每段再“封装”起来(减少段和段之间偶合联系性),这样,就会将风险分散,
以后如果需要修改,只要更改每段,不会再发生牵一动百的事情。
在本例中,首先,我们需要将创建实例的工作与使用实例的工作分开, 也就是说,
让创建实例所需要的大量初始化工作从Sample的构造函数中分离出去。
这时我们就需要Factory工厂模式来生成对象了,不能再用上面简单new Sample(参数)。
还有,如果Sample有个继承如MySample, 按照面向接口编程,我们需要将Sample抽象成一个
接口.现在Sample是接口,有两个子类MySample 和HisSample .我们要实例化他们时,如下:
Sample mysample=new MySample();
Sample hissample=new HisSample();
随着项目的深入,Sample可能还会"生出很多儿子出来", 那么我们要对这些儿子一个个
实例化,更糟糕的是,可能还要对以前的代码进行修改:加入后来生出儿子的实例.这在传
统程序中是无法避免的.
但如果你一开始就有意识使用了工厂模式,这些麻烦就没有了.
工厂方法
你会建立一个专门生产Sample实例的工厂:
public class Factory{
  public static Sample creator(int which){
  //getClass 产生Sample 一般可使用动态类装载装入类。
  if (which==1)
    return new SampleA();
  else if (which==2)
    return new SampleB();
  }
}
那么在你的程序中,如果要实例化Sample时.就使用
Sample sampleA=Factory.creator(1);
这样,在整个就不涉及到Sample的具体子类,达到封装效果,也就减少错误修改的机会,
这个原理可以用很通俗的话来比喻:就是具体事情做得越多,越容易范错误.这每个做
过具体工作的人都深有体会,相反,官做得越高,说出的话越抽象越笼统,范错误可能性
就越少.好象我们从编程序中也能悟出人生道理?呵呵.
使用工厂方法要注意几个角色,首先你要定义产品接口,如上面的Sample,产品接口
下有Sample接口的实现类,如SampleA,其次要有一个factory类,用来生成产品Sample。
进一步稍微复杂一点,就是在工厂类上进行拓展,工厂类也有继承它的实现类
concreteFactory了。
抽象工厂
工厂模式中有: 工厂方法(Factory Method) 抽象工厂(Abstract Factory).
这两个模式区别在于需要创建对象的复杂程度上。如果我们创建对象的方法变得复杂了,
如上面工厂方法中是创建一个对象Sample,如果我们还有新的产品接口Sample2.
这里假设:Sample有两个concrete类SampleA和SamleB,而Sample2也有两个concrete类
Sample2A和SampleB2,那么,我们就将上例中Factory变成抽象类,将共同部分封装在抽
象类中,不同部分使用子类实现,下面就是将上例中的Factory拓展成抽象工厂:
public abstract class Factory{
  public abstract Sample creator();
  public abstract Sample2 creator(String name);
}
public class SimpleFactory extends Factory{
  public Sample creator(){
    .........
    return new SampleA
  }
  public Sample2 creator(String name){
    .........
    return new Sample2A
  }
}
public class BombFactory extends Factory{
  public Sample creator(){
    ......
    return new SampleB
  }
  public Sample2 creator(String name){
    ......
    return new Sample2B
  }
}
从上面看到两个工厂各自生产出一套Sample和Sample2,也许你会疑问,为什么我
不可以使用两个工厂方法来分别生产Sample和Sample2?
抽象工厂还有另外一个关键要点,是因为 SimpleFactory内,生产Sample和生产
Sample2的方法之间有一定联系,所以才要将这两个方法捆绑在一个类中,这个工厂
类有其本身特征,也许制造过程是统一的,比如:制造工艺比较简单,所以名称
叫SimpleFactory。
在实际应用中,工厂方法用得比较多一些,而且是和动态类装入器组合在一起应用,
举例
我们以Jive的ForumFactory为例,这个例子在前面的Singleton模式中我们讨论过,
现在再讨论其工厂模式:
public abstract class ForumFactory {
  private static Object initLock = new Object();
  private static String className = "com.jivesoftware.forum.database.DbForumFactory";
  private static ForumFactory factory = null;
  public static ForumFactory getInstance(Authorization authorization) {
    //If no valid authorization passed in, return null.
    if (authorization == null) {
      return null;
    }
    //以下使用了Singleton 单态模式
    if (factory == null) {
      synchronized(initLock) {
        if (factory == null) {
            ......
          try {
              //动态转载类
              Class c = Class.forName(className);
              factory = (ForumFactory)c.newInstance();
          }
          catch (Exception e) {
              return null;
          }
        }
      }
    }

    //Now, 返回 proxy.用来限制授权对forum的访问
    return new ForumFactoryProxy(authorization, factory,
                    factory.getPermissions(authorization));
  }

  //真正创建forum的方法由继承forumfactory的子类去完成.
  public abstract Forum createForum(String name, String description)
  throws UnauthorizedException, ForumAlreadyExistsException;

  ....

}
因为现在的Jive是通过数据库系统存放论坛帖子等内容数据,如果希望更改为通过文件系统实现,这个工厂方法ForumFactory就提供了提供动态接口:

private static String className = "com.jivesoftware.forum.database.DbForumFactory";

你可以使用自己开发的创建forum的方法代替com.jivesoftware.forum.database.DbForumFactory就可以.

在上面的一段代码中一共用了三种模式,除了工厂模式外,还有Singleton单态模式,以及proxy模式,proxy模式主要用来授权用户对forum的访问,因为访问forum有两种人:一个是注册用户 一个是游客guest,那么那么相应的权限就不一样,而且这个权限是贯穿整个系统的,因此建立一个proxy,类似网关的概念,可以很好的达到这个效果. 

看看Java宠物店中的CatalogDAOFactory:

public class CatalogDAOFactory {

  /**

  * 本方法制定一个特别的子类来实现DAO模式。
  * 具体子类定义是在J2EE的部署描述器中。
  */

  public static CatalogDAO getDAO() throws CatalogDAOSysException {

    CatalogDAO catDao = null;

    try {

      InitialContext ic = new InitialContext();
      //动态装入CATALOG_DAO_CLASS
      //可以定义自己的CATALOG_DAO_CLASS,从而在无需变更太多代码
      //的前提下,完成系统的巨大变更。

      String className =(String) ic.lookup(JNDINames.CATALOG_DAO_CLASS);

      catDao = (CatalogDAO) Class.forName(className).newInstance();

    } catch (NamingException ne) {

      throw new CatalogDAOSysException("
        CatalogDAOFactory.getDAO: NamingException while
          getting DAO type : \n" + ne.getMessage());

    } catch (Exception se) {

      throw new CatalogDAOSysException("
        CatalogDAOFactory.getDAO: Exception while getting
          DAO type : \n" + se.getMessage());

    }

    return catDao;

  }

}

CatalogDAOFactory是典型的工厂方法,catDao是通过动态类装入器className获得CatalogDAOFactory具体实现子类,这个实现子类在Java宠物店是用来操作catalog数据库,用户可以根据数据库的类型不同,定制自己的具体实现子类,将自己的子类名给与CATALOG_DAO_CLASS变量就可以。

由此可见,工厂方法确实为系统结构提供了非常灵活强大的动态扩展机制,只要我们更换一下具体的工厂方法,系统其他地方无需一点变换,就有可能将系统功能进行改头换面的变化。

设计模式如何在具体项目中应用见《Java实用系统开发指南》

posted @ 2006-05-08 09:12 阿成 阅读(340) | 评论 (0)编辑 收藏

最近还算轻松,快到51了嘛,同事们回家的回家,不回家的想着去哪玩儿。

过两天我也回家了,这回可以好好玩儿和歇几天了。

posted @ 2006-04-29 08:34 阿成 阅读(193) | 评论 (0)编辑 收藏
EMF,GEF - Graphical Editor Framework,UML2,VE - Visual Editor都在这里下载
http://www.eclipse.org/downloads/index.php
 
lomboz J2EE插件,开发JSP,EJB
http://forge.objectweb.org/projects/lomboz


1.MyEclipse J2EE开发插件,支持SERVLET/JSP/EJB/数据库操纵等
http://www.myeclipseide.com
 
2.Properties Editor  编辑java的属性文件,并可以自动存盘为Unicode格式
http://propedit.sourceforge.jp/index_en.html
 
3.Colorer Take  为上百种类型的文件按语法着色
http://colorer.sourceforge.net/
 
4.XMLBuddy 编辑xml文件
http://www.xmlbuddy.com
 
5.Code Folding  加入多种代码折叠功能(比eclipse自带的更多)
http://www.coffee-bytes.com/servlet/PlatformSupport
 
6.Easy Explorer  从eclipse中访问选定文件、目录所在的文件夹
http://easystruts.sourceforge.net/
 
7.Fat Jar 打包插件,可以方便的完成各种打包任务,可以包含外部的包等
http://fjep.sourceforge.net/
 
8.RegEx Test 测试正则表达式
http://brosinski.com/stephan/archives/000028.php
 
9.JasperAssistant 报表插件(强,要钱的)
http://www.jasperassistant.com/
 
10.Jigloo GUI Builder JAVA的GUI编辑插件
http://cloudgarden.com/jigloo/
 
11.Profiler 性能跟踪、测量工具,能跟踪、测量BS程序
http://sourceforge.net/projects/eclipsecolorer/
 
12.AdvanQas 提供对if/else等条件语句的提示和快捷帮助(自动更改结构等)
http://eclipsecolorer.sourceforge.net/advanqas/index.html
 
13.Log4E Log4j插件,提供各种和Log4j相关的任务,如为方法、类添加一个logger等
http://log4e.jayefem.de/index.php/Main_Page
 
14.VSSPlugin VSS插件
http://sourceforge.net/projects/vssplugin
 
15.Implementors 提供跳转到一个方法的实现类,而不是接中的功能(实用!)
http://eclipse-tools.sourceforge.net/implementors/
 
16.Call Hierarchy 显示一个方法的调用层次(被哪些方法调,调了哪些方法)
http://eclipse-tools.sourceforge.net/call-hierarchy/index.html
 
17.EclipseTidy 检查和格式化HTML/XML文件
http://eclipsetidy.sourceforge.net/
 
18.Checkclipse 检查代码的风格、写法是否符合规范
http://www.mvmsoft.de/content/plugins/checkclipse/checkclipse.htm
 
19.Hibernate Synchronizer Hibernate插件,自动映射等
http://www.binamics.com/hibernatesync/
 
20.VeloEclipse  Velocity插件
http://propsorter.sourceforge.net/
 
21.EditorList 方便的列出所有打开的Editor
http://editorlist.sourceforge.net/
 
22.MemoryManager 内存占用率的监视
http://cloudgarden.com/memorymanager/
 
23.swt-designer java的GUI插件
http://www.swt-designer.com/
 
24.TomcatPlugin 支持Tomcat插件
http://www.sysdeo.com/eclipse/tomcatPlugin.html
 
25.XML Viewer
http://tabaquismo.freehosting.net/ignacio/eclipse/xmlview/index.html
 
26.quantum 数据库插件
http://quantum.sourceforge.net/
 
27.Dbedit 数据库插件
http://sourceforge.net/projects/dbedit
 
28.clay.core 可视化的数据库插件
http://www.azzurri.jp/en/software/index.jsp
http://www.azzurri.jp/eclipse/plugins
 
29.hiberclipse hibernate插件
http://hiberclipse.sourceforge.net
http://www.binamics.com/hibernatesync
 
30.struts-console Struts插件
http://www.jamesholmes.com/struts/console/
 
31.easystruts Struts插件
http://easystruts.sourceforge.net
 
32.veloedit Velocity插件
http://veloedit.sourceforge.net/
 
33.jalopy 代码整理插件
http://jalopy.sourceforge.net/
 
34.JDepend 包关系分析
http://andrei.gmxhome.de/jdepend4eclipse/links.html
 
35.Spring IDE Spring插件
http://springide-eclip.sourceforge.net/updatesite/
 
36.doclipse 可以产生xdoclet 的代码提示
http://beust.com/doclipse/

posted @ 2006-04-27 16:57 阿成 阅读(472) | 评论 (0)编辑 收藏

<html>
<head>
<title>打造下拉菜单</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style>
body,td { font-size:12px; font-family:宋体}
a:link {  color: #ffffff; text-decoration: none}
a:visited {  color: #ffffff; text-decoration: none}
a:hover {  color: #ff9933; text-decoration: none}
table {  border: #000000; border-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px}
</style>
<script language="JavaScript">
<!--
<!--
function MM_reloadPage(init) {  //reloads the window if Nav4 resized
  if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
    document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; onresize=MM_reloadPage; }}
  else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload();
}
MM_reloadPage(true);
// -->

function MM_findObj(n, d) { //v4.0
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && document.getElementById) x=document.getElementById(n); return x;
}

function MM_showHideLayers() { //v3.0
  var i,p,v,obj,args=MM_showHideLayers.arguments;
  for (i=0; i<(args.length-2); i+=3) if ((obj=MM_findObj(args[i]))!=null) { v=args[i+2];
    if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v='hide')?'hidden':v; }
    obj.visibility=v; }
}
//-->
</script>
</head>

<body bgcolor="#CCCCCC" text="#000000" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" scroll=auto>
<div id="title" style="position:absolute; left:8px; top:15px; width:240px; height:15px; z-index:1; background-color: #006699; layer-background-color: #006699; border: 1px none #000000">
  <table width="480" cellspacing="0" cellpadding="2">
    <tr>
      <td width="120" onMouseOver="MM_showHideLayers('menu1','','show')" onMouseOut="MM_showHideLayers('menu1','','hide')"><b><font color="#FFFFFF"><a href="#">■
        经典论坛</a></font></b> </td>
      <td width="120" onMouseOver="MM_showHideLayers('menu2','','show')" onMouseOut="MM_showHideLayers('menu2','','hide')"><b><font color="#FFFFFF"><a href="#">■
        天极网</a></font></b> </td>
      <td width="120" onMouseOver="MM_showHideLayers('menu2','','show')" onMouseOut="MM_showHideLayers('menu2','','hide')">&nbsp;</td>
      <td width="120" onMouseOver="MM_showHideLayers('menu2','','show')" onMouseOut="MM_showHideLayers('menu2','','hide')">&nbsp;</td>
    </tr>
  </table>
</div>
<div id="menu1" style="position:absolute; left:8px; top:34px; width:120px; height:80px; z-index:2; background-color: #999966; layer-background-color: #999966; border: 1px none #000000; visibility: hidden" onMouseOver="MM_showHideLayers('menu1','','show')" onMouseOut="MM_showHideLayers('menu1','','hide')">
  <table width="100%" cellspacing="0" cellpadding="2" height="80">
    <tr>
      <td>&nbsp;<a href="#">Dreamweaver 专栏</a></td>
    </tr>
    <tr>
      <td>&nbsp;<a href="#">Fireworks 专栏</a></td>
    </tr>
    <tr>
      <td>&nbsp;<a href="#">Flash 基本操作</a></td>
    </tr>
    <tr>
      <td>&nbsp;<a href="#">Flash 5 Action</a></td>
    </tr>
  </table>
</div>
<div id="menu2" style="position:absolute; left:127px; top:34px; width:120px; height:80px; z-index:2; background-color: #999966; layer-background-color: #999966; border: 1px none #000000; visibility: hidden" onMouseOver="MM_showHideLayers('menu2','','show')" onMouseOut="MM_showHideLayers('menu2','','hide')">
  <table width="100%" cellspacing="0" cellpadding="2" height="80">
    <tr>
      <td>&nbsp;<a href="#">新闻</a>&nbsp;</td>
    </tr>
    <tr>
      <td height="20">&nbsp;<a href="#">软件</a></td>
    </tr>
    <tr>
      <td>&nbsp;<a href="#">硬件</a>&nbsp;</td>
    </tr>
    <tr>
      <td>&nbsp;<a href="#">商城</a></td>
    </tr>
  </table>
</div>

</body>
</html>


http://www.blueidea.com/tech/web/2003/301.asp

posted @ 2006-04-25 14:43 阿成 阅读(626) | 评论 (0)编辑 收藏
前些日子编了一阵子程序,有点累。

最近工作稍微轻松了一些。现在每天晚上打篮球锻炼身体和技术

到5 ·1就可以回家好好玩会儿,休息休息了
posted @ 2006-04-19 10:03 阿成 阅读(203) | 评论 (0)编辑 收藏

Spring是一个非常优秀的轻量级框架,通过Spring的IoC容器,我们的关注点便放到了需要实现的业务逻辑上。对AOP的支持则能让我们动态增强业务方法。编写普通的业务逻辑Bean是非常容易而且易于测试的,因为它能脱离J2EE容器(如Servlet,JSP环境)单独进行单元测试。最后的一步便是在Spring框架中将这些业务Bean以XML配置文件的方式组织起来,它们就按照我们预定的目标正常工作了!非常容易!

本文将给出一个基本的Spring入门示例,并演示如何使用Spring的AOP将复杂的业务逻辑分离到每个方面中。

1.开发环境配置
2.编写Bean接口及其实现
3.在Spring中配置Bean并获得Bean的实例
4.编写Advisor以增强ServiceBean
5.总结

1.开发环境配置

首先,需要正确配置Java环境。推荐安装JDK1.4.2,并正确配置环境变量:

JAVA_HOME=<JDK安装目录>
CLASSPATH=.
Path=%JAVA_HOME%\bin;……

我们将使用免费的Eclipse 3.1作为IDE。新建一个Java Project,将Spring的发布包spring.jar以及commons-logging-1.0.4.jar复制到Project目录下,并在Project > Properties中配置好Java Build Path:

2.编写Bean接口及其实现

我们实现一个管理用户的业务Bean。首先定义一个ServiceBean接口,声明一些业务方法:

				/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit:
http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
				/**
 * Interface of service facade.
 *
 * @author Xuefeng
 */
public interface ServiceBean {
    void addUser(String username, String password);
    void deleteUser(String username);
    boolean findUser(String username);
    String getPassword(String username);
}

然后在MyServiceBean中实现接口:

				/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 *
 * For more information, please visit:
http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
				import java.util.*;
		
				public class MyServiceBean implements ServiceBean {
		
				    private String dir;
    private Map map = new HashMap();
				    public void setUserDir(String dir) {
        this.dir = dir;
        System.out.println("Set user dir to: " + dir);
    }
				    public void addUser(String username, String password) {
        if(!map.containsKey(username))
            map.put(username, password);
        else
            throw new RuntimeException("User already exist.");
    }
				    public void deleteUser(String username) {
        if(map.remove(username)==null)
            throw new RuntimeException("User not exist.");
    }
				    public boolean findUser(String username) {
        return map.containsKey(username);
    }
				    public String getPassword(String username) {
        return (String)map.get(username);
    }
}

为了简化逻辑,我们使用一个Map保存用户名和口令。

现在,我们已经有了一个业务Bean。要测试它非常容易,因为到目前为止,我们还没有涉及到Spring容器,也没有涉及到任何Web容器(假定这是一个Web应用程序关于用户管理的业务Bean)。完全可以直接进行Unit测试,或者,简单地写个main方法测试:

				/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit:
http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
				public class Main {
		
				    public static void main(String[] args) throws Exception {
        ServiceBean service = new MyServiceBean();
        service.addUser("bill", "hello");
        service.addUser("tom", "goodbye");
        service.addUser("tracy", "morning");
        System.out.println("tom's password is: " + service.getPassword("tom"));
        if(service.findUser("tom")) {
            service.deleteUser("tom");
        }
    }
}

执行结果:

3.在Spring中配置Bean并获得Bean的实例

我们已经在一个main方法中实现了业务,不过,将对象的生命周期交给容器管理是更好的办法,我们就不必为初始化对象和销毁对象进行硬编码,从而获得更大的灵活性和可测试性。

想要把ServiceBean交给Spring来管理,我们需要一个XML配置文件。新建一个beans.xml,放到src目录下,确保在classpath中能找到此配置文件,输入以下内容:

				<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"
http://www.springframework.org/dtd/spring-beans.dtd ">
<beans>
    <bean id="service" class="com.crackj2ee.example.spring.MyServiceBean" />
</beans>

以上XML声明了一个id为service的Bean,默认地,Spring为每个声明的Bean仅创建一个实例,并通过id来引用这个Bean。下面,我们修改main方法,让Spring来管理业务Bean:

				/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit:
http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
				import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
				public class Main {
		
				    public static void main(String[] args) throws Exception {
        // init factory:
        XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
        // use service bean:
        ServiceBean service = (ServiceBean)factory.getBean("service");
        service.addUser("bill", "hello");
        service.addUser("tom", "goodbye");
        service.addUser("tracy", "morning");
        System.out.println("tom's password is \"" + service.getPassword("tom") + "\"");
        if(service.findUser("tom")) {
            service.deleteUser("tom");
        }
        // close factory:
        factory.destroySingletons();
    }
}

执行结果:
 

由于我们要通过main方法启动Spring环境,因此,首先需要初始化一个BeanFactory。红色部分是初始化Spring的BeanFactory的典型代码,只需要保证beans.xml文件位于classpath中。

然后,在BeanFactory中通过id查找,即可获得相应的Bean的实例,并将其适当转型为合适的接口。

接着,实现一系列业务操作,在应用程序结束前,让Spring销毁所有的Bean实例。

对比上一个版本的Main,可以看出,最大的变化是不需要自己管理Bean的生命周期。另一个好处是在不更改实现类的前提下,动态地为应用程序增加功能。

4.编写Advisor以增强ServiceBean

所谓AOP即是将分散在各个方法处的公共代码提取到一处,并通过类似拦截器的机制实现代码的动态织入。可以简单地想象成,在某个方法的调用前、返回前、调用后和抛出异常时,动态插入自己的代码。在弄清楚Pointcut、Advice之类的术语前,不如编写一个最简单的AOP应用来体验一下。

考虑一下通常的Web应用程序都会有日志记录,我们来编写一个LogAdvisor,对每个业务方法调用前都作一个记录:

				/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit:
http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
				import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
				public class LogAdvisor implements MethodBeforeAdvice {
    public void before(Method m, Object[] args, Object target) throws Throwable {
        System.out.println("[Log] " + target.getClass().getName() + "." + m.getName() + "()");
    }
}

然后,修改beans.xml:

				<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"
http://www.springframework.org/dtd/spring-beans.dtd ">
				<beans>
    <bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" />
				    <bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" />
		
				    <bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces"><value>com.crackj2ee.example.spring.ServiceBean</value></property>
        <property name="target"><ref local="serviceTarget"/></property>
        <property name="interceptorNames">
            <list>
                <value>logAdvisor</value>
            </list>
        </property>
    </bean>
</beans>

注意观察修改后的配置文件,我们使用了一个ProxyFactoryBean作为service来与客户端打交道,而真正的业务Bean即MyServiceBean被声明为serviceTarget并作为参数对象传递给ProxyFactoryBean,proxyInterfaces指定了返回的接口类型。对于客户端而言,将感觉不出任何变化,但却动态加入了LogAdvisor,关系如下:
 

运行结果如下,可以很容易看到调用了哪些方法:
 

要截获指定的某些方法也是可以的。下面的例子将修改getPassword()方法的返回值:

				/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit:
http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
				import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
				public class PasswordAdvisor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object ret = invocation.proceed();
        if(ret==null)
            return null;
        String password = (String)ret;
        StringBuffer encrypt = new StringBuffer(password.length());
        for(int i=0; i<password.length(); i++)
            encrypt.append('*');
        return encrypt.toString();
    }
}

这个PasswordAdvisor将截获ServiceBean的getPassword()方法的返回值,并将其改为"***"。继续修改beans.xml:

				<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"
http://www.springframework.org/dtd/spring-beans.dtd ">
<beans>
    <bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" />
				    <bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" />
		
				    <bean id="passwordAdvisorTarget" class="com.crackj2ee.example.spring.PasswordAdvisor" />
		
				    <bean id="passwordAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="advice">
            <ref local="passwordAdvisorTarget"/>
        </property>
        <property name="patterns">
            <list>
                <value>.*getPassword</value>
            </list>
        </property>
    </bean>
				    <bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces"><value>com.crackj2ee.example.spring.ServiceBean</value></property>
        <property name="target"><ref local="serviceTarget"/></property>
        <property name="interceptorNames">
            <list>
                <value>logAdvisor</value>
                <value>passwordAdvisor</value>
            </list>
        </property>
    </bean>
</beans>

利用Spring提供的一个RegexMethodPointcutAdvisor可以非常容易地指定要截获的方法。运行结果如下,可以看到返回结果变为"******":
 

还需要继续增强ServiceBean?我们编写一个ExceptionAdvisor,在业务方法抛出异常时能做一些处理:

				/**
 * Copyright_2006, Liao Xuefeng
 * Created on 2006-3-9
 * For more information, please visit:
http://www.crackj2ee.com
 */
package com.crackj2ee.example.spring;
				import org.springframework.aop.ThrowsAdvice;
		
				public class ExceptionAdvisor implements ThrowsAdvice {
    public void afterThrowing(RuntimeException re) throws Throwable {
        System.out.println("[Exception] " + re.getMessage());
    }
}

将此Advice添加到beans.xml中,然后在业务Bean中删除一个不存在的用户,故意抛出异常:

				service.deleteUser("not-exist");
		

再次运行,注意到ExceptionAdvisor记录下了异常:
 

5.总结

利用Spring非常强大的IoC容器和AOP功能,我们能实现非常灵活的应用,让Spring容器管理业务对象的生命周期,利用AOP增强功能,却不影响业务接口,从而避免更改客户端代码。

为了实现这一目标,必须始终牢记:面向接口编程。而Spring默认的AOP代理也是通过Java的代理接口实现的。虽然Spring也可以用CGLIB实现对普通类的代理,但是,业务对象只要没有接口,就会变得难以扩展、维护和测试。

可以从此处下载完整的Eclipse工程:
http://www.crackj2ee.com/Article/UploadFiles/200604/SpringBasic.rar

posted @ 2006-04-18 17:28 阿成 阅读(2038) | 评论 (1)编辑 收藏

1.删除提示

1)<a  href="#" onclick="return(confirm('删除后无法恢复,您确定删除吗?'))">删除</a>

2)JS
<a  href="#" >删除</a>

<script language="JavaScript" type="text/javascript">
function delete_confirm(){
 if(event.srcElement.outerText=="删除" || event.srcElement.value=="删除")
  event.returnValue=confirm("删除后将不能恢复,您确认执行删除操作么?");
 }
 document.onclick=delete_confirm;
</script>

2.点击按钮探出提示
 <input type=button value="reload" onclick="javascript:reload()">

<script type="text/javascript">
function reload() {
 
 if (confirm("确认?"))
 {
 var url="#";
 window.location.href=url;
 }
}
3.点击链接弹出提示

<a  href="确认后的连接地址" onclick="return(confirm('想要的提示信息?'))">显示信息</a>

4.onchange()用法
<select name="year" onchange="javascript:changeYear()">
 <OPTION OPTION>
</SELECT>

<SCRIPT language="javascript">
function changeYear(){
  var url = ....;
 window.location.href = url;
}
</SCRIPT>

4.根据选择的radio转向不同的URL
<input type="Radio" name="id" value="1" checked></td>
<input type="Radio" name="id" value="2" checked></td>
<input type="Radio" name="id" value="3" checked></td>

<SCRIPT language="javascript">
function WhichOneisChecked(obj) {
for (var i = 0;i < obj.elements.length;i++){
if (obj.elements[i].checked == true){
var weekLogId=obj.elements[i].value;
var url="......";
window.location.href = url;
}
}
}
</SCRIPT>

5.radio 全选
function checkAll(e, itemName)
{
  var aa = document.getElementsByName(itemName);
  for (var i=0; i<aa.length; i++)
   aa[i].checked = e.checked;
}
function check(e, allName)
{
  var all = document.getElementsByName(allName)[0];
  if(!e.checked) all.checked = false;
  else
  {
    var aa = document.getElementsByName(e.name);
    for (var i=0; i<aa.length; i++)
     if(!aa[i].checked) return;
    all.checked = true;
  }
   
<input type=checkbox checked name=allTeams onclick="checkAll(this, 'teamIds')">

<input type="checkbox" name="teamIds" checked value="<%=.....%>" onclick="check(this, 'allTeams')">

6.显示、隐藏
链接实现
<script language="javascript">
  function showLay(divId){
        var objDiv = eval(divId);
        if (objDiv.style.display=="none"){
                eval("sp"+divId+".innerHTML='隐藏'");
                objDiv.style.display="";
        }else{
                eval("sp"+divId+".innerHTML='查看'");
                objDiv.style.display="none";
        }}
  </script>

   <td>
      <a href="#"  onclick="showLay('Layer1')"><span id="spLayer1">查看</span></a>
      <br>
      <div id="Layer1" style="display:none;">......</div>
     </td>

按钮实现
<SCRIPT LANGUAGE="JavaScript">
function hidden_show()
{
 var obj = document.getElementById("Layer1");
 if(obj.style.visibility == "")
  obj.style.visibility = "hidden";
 else
  obj.style.visibility = "";
}
</SCRIPT>
<td>
      <INPUT TYPE="button" onclick="hidden_show();" value="hidden/show">
     <br>
      <div id="Layer1" >
       <%=weekPlan%>
      </div>
     </td>

posted @ 2006-04-17 17:33 阿成 阅读(546) | 评论 (0)编辑 收藏
在计算机开发语言的历史中,从来没有哪种语言象Java那样受到如此众多厂商的支持,有如此多的开发工具,Java菜鸟们如初入大观园的刘姥姥,看花了眼,不知该何种选择。的确,这些工具各有所长,都没有绝对完美的,就算是老鸟也很难做出选择。在本文中我简要介绍了常见的十五种Java开发工具的特点,管中窥“器”,希望能对大家有所帮助。

   1、JDK (Java Development Kit)

  SUN的Java不仅提了一个丰富的语言和运行环境,而且还提了一个免费的Java开发工具集(JDK)。开发人员和最终用户可以利用这个工具来开发java程序。

   JDK简单易学,可以通过任何文本编辑器(如:Windows 记事本、UltrEdit、Editplus、FrontPage以及dreamweaver等)编写Java源文件,然后在DOS状况下利通过javac命令将Java源程序编译成字节码,通过Java命令来执行编译后的Java文件,这能带给DOS时代程序员美好的回忆。

  Java 初学者一般都采用这种开发工具。

  2、Java Workshop

1143135411556_3614.gif

      Sun MicroSystems公司于1996年3月26日推出了Java WorkShop 1.0,这是业界出现的第一个供Internet网使用的多平台开发工具,它可以满足各公司开发Internet和Intranet网应用软件的需要。Java WorkShop完全用Java语言编写,是当今市场上销售的第一个完全的Java开发环境,目前Java WorkShop的最性版本是3.0。Java Workshop的特点表现如下:

  1)结构易于创建:在创建平台中立的网格结构方面,Java Workshop比其他任何一种Java开发工具都要方便。

  2)可视化编程:Java Workshop的可视化编程特性是很基本的。Java Workshop允许程序员重新安排这些操作,甚至可以确定触发操作行为的过滤器。Java Workshop产生的模板带有许多注释,这对程序员是很有帮助的。

  此外,Java WorkShop支持JDK1.1.3以及JavaBeans组件模型,API和语言特征增加了编译Java应用程序的灵活性。 Java WorkShop开发环境由于完全用Java写成,所以可移植性极好,以致于多个平台都能支持,目前Java WorkShop支持Solaris操作环境SPARC及Intel 版)、Windows95、WindowsNT、以及HP/Ux等平台。适合于初学者进行一些简单的Java编程。Java WorkShop的缺点是Java Workshop中的每一个可视化对象都迟早会用到网格布局,这种设计方法是许多人不习惯的;Java Workdshop的调色板是较差的,仅仅能满足绝大部分应用的基本要求。

  3、NetBeans 与Sun Java Studio 5

1143135607062_8513.gif

    NetBeans是开放源码的Java集成开发环境(IDE),适用于各种客户机和Web应用。 Sun Java Studio是Sun公司最新发布的商用全功能Java IDE,支持Solaris、Linux和Windows平台,适于创建和部署2层Java Web应用和n层J2EE应用的企业开发人员使用。

  NetBeans是业界第一款支持创新型Java开发的开放源码IDE。开发人员可以利用业界强大的开发工具来构建桌面、Web或移动应用。同时,通过NetBeans和开放的API的模块化结构,第三方能够非常轻松地扩展或集成NetBeans平台。

  NetBeans3.5.1主要针对一般Java软件的开发者,而Java One Studio5则主要针对企业做网络服务等应用的开发者。Sun不久还将推出Project Rave,其目标是帮助企业的开发者进行软件开发。NetBeans 3.5.1版本与其他开发工具相比,最大区别在于不仅能够开发各种台式机上的应用,而且可以用来开发网络服务方面的应用,可以开发基于J2ME的移动设备上的应用等。在NetBeans 3.5.1基础上,Sun开发出了Java One Studio5,为用户提供了一个更加先进的企业编程环境。在新的Java One Studio5里有一个应用框架,开发者可以利用这些模块快速开发自己在网络服务方面的各种应用程序。

4.Borland 的JBuilder

  Jbuilder进入了Java集成开发环境的王国,它满足很多方面的应用,尤其是对于服务器方以及EJB开发者们来说。下面简单介绍一下Jbuilder的特点:

  1)Jbuilder支持最新的Java技术,包括Applets、JSP/Servlets、JavaBean以及EJB(Enterprise JavaBeans)的应用。

  2)用户可以自动地生成基于后端数据库表的EJB Java类,Jbuilder同时还简化了EJB的自动部署功能.此外它还支持CORBA,相应的向导程序有助于用户全面地管理IDL(分布应用程序所必需的接口定义语言Interface Definition Language)和控制远程对象。

  3)Jbuilder支持各种应用服务器。Jbuilder与Inprise Application Server紧密集成,同时支持WebLogic Server,支持EJB 1.1和EJB 2.0,可以快速开发J2EE的电子商务应用。

  4)Jbuilder能用Servlet和JSP开发和调试动态Web 应用。

  5)利用Jbuilder可创建(没有专有代码和标记)纯Java2应用。由于Jbuilder是用纯Java语言编写的,其代码不含任何专属代码和标记,它支持最新的Java标准。

  6)Jbuilder拥有专业化的图形调试介面,支持远程调试和多线程调试,调试器支持各种JDK版本,包括J2ME/J2SE/J2EE。

  JBuilder环境开发程序方便,它是纯的Java 开发环境,适合企业的J2EE开发;缺点是往往一开始人们难于把握整个程序各部分之间的关系,对机器的硬件要求较高,比较吃内存,这时运行速度显得较慢。

 5、Oracle 的JDeveloper

  Oracle9i JDeveloper(定为9.0版,最新为10g)为构建具有J2EE功能,XML和Web services的复杂的,多层的Java应用程序提供了一个完全集成的开发环境。它为运用Oracle9i数据库和应用服务器的开发人员提供特殊的功能和增强性能,除此以外,它也有资格成为用于多种用途Java开发的一个强大的工具。

  Oracle9i JDeveloper的主要特点如下:

  ① 具有UML(Unified Modeling Language,一体化建模语言)建模功能。可以将业务对象及e-business应用模型化。

  ② 配备有高速Java调试器(Debuger)、内置Profiling工具、提高代码质量的工具“CodeCoach”等。

  ③ 支持SOAP(Simple Object Access Protocol)“简单对象访问协议”、UDDI(Universal Description, Discovery and Integration)“统一描述、发现和集成协议”、WSDL(Web Services Description Language)“WEB服务描述语言”等Web服务标准。

  JDeveloper 不仅仅是很好的 Java 编程工具,而且是 Oracle Web 服务的延伸,支持 Apache SOAP,以及 9iAS ,可扩充的环境和 XML 和 WSDL 语言紧密相关。Oracle9i Jdeveloper完全利用Java编写,能够与以前的Oracle服务器软件以及其他厂商支持J2EE的应用服务器产品相兼容,而且在设计时着重针对Oracle9i,能够无缝化跨平台之间的应用开发,提供了业界第一个完整的、集成了J2EE和XML的开发环境,允许开发者快速开发可以通过Web、无线设备及语音界面访问的Web服务和交易应用,以往只能通过将传统Java编程技巧与最新模块化方式结合到一个单一集成的开发环境中之后才能完成J2EE应用开发生命周期管理的事实,从根本上得到改变。缺点就是对于初学者来说,较复杂,也比较难。

   6、IBM的Visual Age for Java

   Visual Age for Java是一个非常成熟的开发工具,它的特性以于IT开发者和业余的Java编程人员来说都是非常用有用的。它提供对可视化编程的广泛支持,支持利用CICS连接遗传大型机应用,支持EJB的开发应用,支持与Websphere的集成开发,方便的bean创建和良好的快速应用开发(RAD)支持和无文件式的文件处理。

  IBM为建设Web站点所推出的WebSphere Studio Advanced Edition及其包含的VisualAge for Java Professional Edition软件已全面转向以Java为中心,这样,Java开发人员对WebSphere全套工具的感觉或许会好了许多。Studio所提供的工具有:Web站点管理、快速开发 JDBC页向导程序、HTML编辑器和HTML语法检查等。这确实是个不错的HTML站点页面编辑环境。Studio和VisualAge集成度很高,菜单中提供了在两种软件包之间快速移动代码的选项。这就让使用Studio的Web页面设计人员和使用VisualAge的Java程序员可以嗷ソ换晃募⑿ぷ鳌?BR>
  Visual Age for Java支持团队开发,内置的代码库可以自动地根据用户做出改动而修改程序代码,这样就可以很方便地将目前代码和早期版本做出比较。与Visual Age紧密结合的Websphere Studio本身并不提供源代码和版本管理的支持,它只是包含了一个内置文件锁定系统,当编辑项目的时候可以防止其他人对这些文件的错误修改,软件还支持诸如Microsoft Visual SourceSafe这样的第三方源代码控制系统。Visual Age for Java完全面向对象的程序设计思想使得开发程序非常快速、高效。你可以不编写任何代码就可以设计出一个典型的应用程序框架。Visual Age for Java作为IBM电子商务解决方案其中产品之一,可以无缝地与其他IBM产品,如WebSphere、DB2融合, 迅速完成从设计、开发到部署应用的整个过程。

  Visual Age for Java独特的管理文件方式使其集成外部工具非常困难,你无法让Visual Age for Java与其他工具一起联合开发应用。

7、BEA 的 WebLogic Workshop

    BEA WebLogic Workshop是一个统一、简化、可扩展的开发环境,使所有的开发人员都能在 BEA WebLogic Enterprise Platform之上构建基于标准的企业级应用,从而提高了开发部门的生产力水平,加快了价值的实现。

  WebLogic Workshop除了提供便捷的Web服务之外,它能够用于创建更多种类的应用。作为整个BEA WebLogic Platform的开发环境。不管是创建门户应用、编写工作流、还是创建Web应用,Workshop 8.1都可以帮助开发人员更快更好地完成。

  WebLogic Workshop的主要特点如下:

  ① 使 J2EE 开发切实可行,提高开发效率

  BEA WebLogic Workshop 使开发人员远离 J2EE 内在的复杂性,集中精力专注业务逻辑,无须操心单调乏味的基础结构代码。这种创新意味着,已被企业验证的 J2EE 的强大功能,最终被大多数不熟悉 Java 和 J2EE 的应用开发人员所掌握,从而使 IT 部门的工作效率提高一个数量级。

  可视化设计器以及直观的概念,如事件、属性和控件等,实现了基于事件的开发。Workshop 简化的程序设计模型,使开发人员不必掌握复杂的 J2EE API 和面向对象的程序设计原理。所有开发人员,包括 J2EE 专家和具有可视化和过程化语言技能的应用开发人员在内,都可以共同工作在 BEA WebLogic Enterprise Platform 之上。Workshop 的可视化开发环境,创建带有代码注释的标准 Java 文件,用来说明由运行时框架实施的企业级需求。J2EE 和其他高级开发人员,借助功能强大的代码编辑功能,可以访问 Java 源代码,从而弥补了可视化设计器的不足。

  ② 构建企业级应用

  通过在可伸缩、安全可靠的企业级架构上实施各种应用,BEA WebLogic Workshop 大大降低了开发风险。而且,所有应用的创建都使用标准的 J2EE 组件,既保护了您的技术投资,又保持了最大的灵活性。
BEA WebLogic Workshop 运行框架,是统一整个架构的汇聚层,使单一、简化的程序设计模型扩展到所有的 BEA WebLogic Enterprise Platform 应用类型。通过解释设计时创建的注释代码,运行时框架可以实现必要的 J2EE 组件,并且提取出与 J2EE 应用开发有关的所有底层细节。

  ③ 降低 IT 复杂性

  BEA WebLogic Workshop 提供各种 Java 控件,使得与 IT 资源的连接更轻而易举。另外,在构建任何 BEA WebLogic Platform 的应用中,Java 控件不仅可扩展而且完全相同。这种强大、有效的方法能够:降低 IT 技术的复杂性,优化信息的可用性,推动包含"最佳业务方案"的可重用服务的开发,使开发人员能以更低的成本、更短的时间实现更大的产出。

  利用 BEA WebLogic Workshop,任何开发人员都能以最大的生产效率,构建各种 Web 服务、Web 应用、门户和集成项目。BEA WebLogic Workshop是BEA的产品战略核心,它帮助客户接触和利用面向服务架构(SOA)的强大功能。BEA Weblogic Workshop 8.1极大简化了当前实际企业集成环境中企业级应用和服务的构建,并成为全面支持关键企业级应用(如异步、真正松耦合和粗粒度消息传送等)的自然选择。它的缺点就是过于复杂,对于初学者来说,理解起来较为困难。

8、WebGain 的Visual Cafe for Java

Visual Cafe 是只能在Symantec公司的Java虚拟机、Netscape公司的Java虚拟机和Microsoft虚拟机上工作的调试器。这对于开发者来讲是一个重要的特性,因为用户开发的Java代码中的许多软件bug就可能中会在某种特定的虚拟机上起作用。

  在修改后进行编译基继续进行调试时,Visual Cafe会自动将文件存盘,使用Visual Cafe创建的原生应用具有许多特点。除了明显的速度提高之外,Symantec使类库的二进制方式比正常的JDK小Visual Cafe为所指定的关系自动生成或更新必要的Java代码。利用Visual Cafe,用户可以从一个标准对象数据库中集合完整的Java应用程序和Applet,而不必再编写源代码。Visual Cafe还提供了一个扩充的源代码开发工具集。 

  Visual Cafe综合了Java软件的可视化源程序开发工具,它允许开发人员在可视化视图和源视图之间进行有效地转换。在可视化视图中进行的修改立即反映在源代码中。对源代码的改变自动更新可视化视图。

  Visual Cafe具有许多源文件方面的特性,如全局检索和替换。绝大多数Java开发工具的文献的问题在于简单地挨个介绍开发工具的每部分组件,但用户在开应用时还需要一个面向任务的手册,利用这个手册你可以不必知道工具每一部分的特定功能就可以开始创建自己的应用。Visual Cafe提供了非常全面的用户指南,它对最开始的安装到创建第一个Java应用和Applet都提供了全面的帮助,Visual Cafe将自动生成所指明关系的必要Java代码。Visual Cafe可以在Windows 95和Windows NT平台下运行,Symantec公司为Java开发工作提供一个在Macintosh操作系统下可以运行的RAD工具。Visual Cafe编译器速度很快,在国际化支持方面比较突出;缺点就是对于初学者来说,较复杂,也比较难。

9、Macromedia的JRUN

    Macromedia公司的JRun是一个具有最广阔适用性的Java引擎,用于开发及实施由Java Servlets和JavaServer Pages编写的服务器端Java应用。JRun是第一个完全支持JSP 1.0 规格书的商业化产品,全球有超过80,000名开发人员使用JRun在他们已有的Web服务器上添加服务器端Java的功能。其中Web服务器包括了Microsoft IIS,Netscape Enterprise Server,Apache等。

  JRun是开发实施服务器端Java的先进引擎。如果我们希望在我们的Web应用中添加服务器端Java功能,那么JRun将成为我们的正确选择。

  JRun目前有3个版本,它是第一个支持Java Server Pages(JSP)规格书1.0的商业化产品。JSP是一种强大的服务器端技术,它是用于创建复杂Web应用的一整套快速应用开发系统。JRun可以使我们开始开发并测试Java应用。它最多接受5个并发的连接并且包括全部Java Servlet API,支持JavaServer Pages(JSP),支持所有主要的Web servers和计算机平台。 JRun Pro能够在生产环境下承受大访问量的负载,帮助我们实施应用、服务或Web站点(包括内联网)。JRun Pro 支持无限量并发式连接运行多个Java虚拟机,包括多个并发的Java虚拟机(JVM)。提供一个远程管理applet以及一个远程可再分布式的管理applet。JRun Pro Unlimited包括了所有JRun Pro的功能,除次以外,还可以运行无限量的,并发的JVM。

  JRun依靠其内置的JRun Web Server可以单独运行。使用服务器端Java,用户可以开发出复杂的商业应用系统。最重要的一点是,由于servlets的平台独立性,以及更加简单的开发、更快速的实施、更经济的维护成本,它是CGI(Common Gateway Interface)或Perl scripts的极佳的替代产品。缺点就是对于初学者来说,较复杂,也比较难。

10、JCreator

    JCreator 是一个Java程序开发工具,也是一个Java集成开发环境(IDE)。无论你是要开发Java应用程序或者网页上的Applet元件都难不倒它。在功能上与Sun公司所公布的JDK等文字模式开发工具相较之下来得容易,还允许使用者自订义操作窗口界面及无限Undo/Redo等功能。

  JCreator为用户提供了相当强大的功能,例如项目管理功能,项目模板功能,可个性化设置语法高亮属性、行数、类浏览器、标签文档、多功能编绎器,向导功能以及完全可自定义的用户界面。通过JCreator,我们不用激活主文档而直接编绎或运行我们的JAVA程序。

  JCreator能自动找到包含主函数的文件或包含Applet的Html文件,然后它会运行适当的工具。在JCreator中,我们可以通过一个批处理同时编绎多个项目。JCreator的设计接近Windows界面风格,用户对它的界面比较熟悉。其最大特点是与我们机器中所装的JDK完美结合,是其它任何一款IDE所不能比拟的。它是一种初学者很容易上手的java开发工具,缺点是只能进行简单的程序开发,不能进行企业J2EE的开发应用。

11、Microsoft VJ++
     Visual J++ 是Microsoft 公司推出的可视化的Java 语言集成开发环境(IDE),为Java 编程人员提供了一个新的开发环境,是一个相当出色的开发工具。无论集成性、编译速度、调试功能、还是易学易用性,都体现了Microsoft 的一惯风格。Visual J++ 具有下面的特点:

  1)Visual J++ 把Java 虚拟机(JVM)作为独立的操作系统组件放入Windows,使之从浏览器中独立出来。

  2)Microsoft 的应用基本类库(AFC,Application Foundation Class Library)对SUN 公司的JDK 作了扩展,使应用基本类库更加适合在Windows 下使用。

  3) Visual J++ 的调试器支持动态调试,包括单步执行、设置断点、观察变量数值等。

  4) Visual J++ 提供了一些程序向导(Wizards)和生成器(Builders),它们可以方便地帮助用户快速地生成Java 程序,帮助你在自己的工程中创建和修改文件。

  5) Visual J++ 界面友好,其代码编辑器具有智能感知、联机编译等功能,使程序编写十分方便。Visual J++ 中建立了Java 的WFC,这一新的应用程序框架能够直接访问Windows 应用程序接口(API),使你能够用Java 语言编写完全意义上的Windows 应用程序。

  6)Visual J++ 中表单设计器的快速应用开发特性使用WFC 创建基于表单的应用程序变得轻松、简单。通过WFC 可以方便地使用ActiveX 数据对象(ADO,ActiveX Data Objects)来检索数据和执行简单数据的绑定。通过在表单设计器中使用ActiveX 数据对象,可以快速地在表单中访问和显示数据。

  Visual J++能结合微软的一贯的编程风格,很方便进行Java 的应用开发,但它的移植性较差,不是纯的Java 开发环境。

12、Eclipse

    Eclipse是一种可扩展的开放源代码IDE。2001年11月,IBM公司捐出价值4,000万美元的源代码组建了Eclipse联盟,并由该联盟负责这种工具的后续开发。集成开发环境(IDE)经常将其应用范围限定在“开发、构建和调试”的周期之中。为了帮助集成开发环境(IDE)克服目前的局限性,业界厂商合作创建了Eclipse平台。Eclipse允许在同一IDE中集成来自不同供应商的工具,并实现了工具之间的互操作性,从而显著改变了项目工作流程,使开发者可以专注在实际的嵌入式目标上。

  Eclipse框架的这种灵活性来源于其扩展点。它们是在XML中定义的已知接口,并充当插件的耦合点。扩展点的范围包括从用在常规表述过滤器中的简单字符串,到一个Java类的描述。任何Eclipse插件定义的扩展点都能够被其它插件使用,反之,任何Eclipse插件也可以遵从其它插件定义的扩展点。除了解由扩展点定义的接口外,插件不知道它们通过扩展点提供的服务将如何被使用。

  利用Eclipse,我们可以将高级设计(也许是采用UML)与低级开发工具(如应用调试器等)结合在一起。如果这些互相补充的独立工具采用Eclipse扩展点彼此连接,那么当我们用调试器逐一检查应用时,UML对话框可以突出显示我们正在关注的器件。事实上,由于Eclipse并不了解开发语言,所以无论Java语言调试器、C/C++调试器还是汇编调试器都是有效的,并可以在相同的框架内同时瞄准不同的进程或节点。

  Eclipse的最大特点是它能接受由Java开发者自己编写的开放源代码插件,这类似于微软公司的Visual Studio和Sun微系统公司的NetBeans平台。Eclipse为工具开发商提供了更好的灵活性,使他们能更好地控制自己的软件技术。Eclipse联盟已经宣布将在2004年中期发布其3.0版软件。这是一款非常受欢迎的java开发工具,这国内的用户越来越多,实际上实用它java开发人员是最多的。缺点就是较复杂,对初学者来说,理解起来比较困难。

13、Ant

    Another Neat Tool(Ant)是一种基于Java的build工具。理论上来说,它有些类似于(Unix)C中的make ,但没有make的缺陷。因为Ant的原作者在多种(硬件)平台上开发软件时,无法忍受这些工具的限制和不便。类似于make的工具本质上是基于shell(语言)的:他们计算依赖关系,然后执行命令(这些命令与你在命令行敲的命令没太大区别)。这就意味着你可以很容易地通过使用OS特有的或编写新的(命令)程序扩展该工具;然而,这也意味着你将自己限制在了特定的OS,或特定的OS类型上,如Unix。Ant就不同了。与基于shell命令的扩展模式不同,Ant用Java的类来扩展。(用户)不必编写shell命令,配置文件是基于XML的,通过调用target树,就可执行各种task。每个task由实现了一个实现了特定Task接口的对象来运行。

  Ant支持一些可选task,一个可选task一般需要额外的库才能工作。可选task与Ant的内置task分开,单独打包。这个可选包可以从你下载Ant的同一个地方下载。ANT本身就是这样一个流程脚本引擎,用于自动化调用程序完成项目的编译,打包,测试等。除了基于JAVA是平台无关的外,脚本的格式是基于XML的,比make脚本来说还要好维护一些。Ant是Apache提供给Java开发人员的构建工具,它可以在Windows OS和Unix OS下运行,它不仅开放源码并且还是一个非常好用的工具。Ant是Apache Jakarta中一个很好用的Java开发工具,Ant配置文件采用XML文档编写,所以Java程序员对其语法相当熟悉,Ant是专用于Java项目平台,能够用纯Java来开发,它能够运行于Java安装的平台,即体现了它的跨平台功能。它的缺点显示执行结果只能是DOS字符界面,不能进行复杂的java程序开发。

14、IntelliJ

    Intellij IDEA是一款综合的Java 编程环境,被许多开发人员和行业专家誉为市场上最好的IDE。它提供了一系列最实用的的工具组合:智能编码辅助和自动控制,支持J2EE,Ant,JUnit和CVS集成,非平行的编码检查和创新的GUI设计器。IDEA把Java开发人员从一些耗时的常规工作中解放出来,显著地提高了开发效率。具有运行更快速,生成更好的代码;持续的重新设计和日常编码变得更加简易,与其它工具的完美集成;很高的性价比等特点。在4.0版本中支持Generics,BEA WebLogic集成,改良的CVS集成以及GUI设计器。

  IntelliJ IDEA能尽可能地促进程序员的编程速度。它包括了很多辅助的功能,并且与Java结合得相当好。不同的工具窗口围绕在主编程窗口周围,当鼠标点到时即可打开,无用时也可轻松关闭,使用户得到了最大化的有效屏幕范围。以技术为导向的IDEA集成了调试器,支持本地和远程的调试,即使我们需要修改一些设置上的东西使我们的工作顺利进展。另外,它还提供了通常的监视,分步调试以及手动设置断点功能,在这种断点模式下,我们可以自动地在断点之外设置现场访问,甚至可以浏览不同的变量的值。IDE支持多重的JVM设置,几个编译程序和Ant建造系统,并且,它使得设置多重的自定义的类途径变得简单。

  IntelliJ Idea是一个相对较新的Java IDE。它是Java开发环境中最为有用的一个。高度优化的IntelleJ Idea使普通任务变得相当容易,Idea支持很多整合功能,更重要的使它们设计的好容易使用。Idea支持XML中的代码实现,Idea同时还会校正XML,Idea支持JSP的结构。作用于普通Java代码的众多功能同样适用于JSP(比如整合功能),同时支持JSP调试;支持EJB,尽管它不包括对个别应用服务器的特殊支持。Idea支持Ant建立工具,不仅是运行目标它还支持编译与运行程序前后运行目标,另外也支持绑定键盘快捷键。在编辑一个Ant建立XML文件时,Idea还对组成Ant工程的XML部分提供支持。IntelliJ IDEA 被称为是最好的JAVA IDE开发平台,这套软件就是以其聪明的即时分析和方便的 refactoring 功能深获大家所喜爱。缺点是较复杂,对初学者来说,理解起来比较困难。

  小结

  现在常用的Java项目开发环境有:JBuilder、VisualAge for Java、Forte for Java, Visual Cafe、Eclipse、NetBeans IDE、JCreator +J2SDK、jdk+记事本、EditPlus+ J2SDK等等。一般开发J2EE项目时都需要安装各公司的应用服务器(中间件)和相应的开发工具,在使用这些开发工具之前,我们最好能熟知这些软件的优点和缺点,以便根据实际情况选择应用。编程工具只是工具,为了方便人们工作而开发的,各有特点,因此,选工具主要的依据自己将要从事的领域是什么,而不是盲目的认为那种工具好,那种工具不好。最后希望大家都能找到自己合适的java 开发工具。

posted @ 2006-04-05 13:37 阿成 阅读(216) | 评论 (0)编辑 收藏
仅列出标题
共10页: First 上一页 2 3 4 5 6 7 8 9 10 下一页