2005年3月10日

  在Struts中大家可能对其页面有效性检查(校验)有比较深刻的印象,你只要在structs-config.xml中增加一个plugin的配置,然后定义一个检验配置的xml,然后在稍微改变一些代码,就可以自动完成页面的检验了。具体步骤如下:
第一步:建立校验配置文件validation.xml,咱们以登陆页面为例,该文件如下:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!--
    Validation Rules for the Struts Example Web Application

    $Id: validation.xml,v 1.1.1.1 2003/05/15 06:28:29 xiaogen Exp $
-->

<form-validation>
    <!-- ========== Default Language Form Definitions ===================== -->
    <formset>
        <form name="loginForm">
            <field property="username"
                    depends="required,minlength,maxlength">
                <arg0   key="login.username"/>
                <arg1   key="${var:minlength}" name="minlength" resource="false"/>
                <arg1   key="${var:maxlength}" name="maxlength" resource="false"/>
                <var>
                    <var-name>maxlength</var-name>
                    <var-value>16</var-value>
                </var>
                <var>
                    <var-name>minlength</var-name>
                    <var-value>3</var-value>
                </var>
            </field>
            <field property="passwd"
                    depends="required,minlength,maxlength">
                <arg0   key="login.passwd"/>
                <arg1   key="${var:minlength}" name="minlength"
                   resource="false"/>
                <arg1   key="${var:maxlength}" name="maxlength"
                   resource="false"/>
                <var>
                    <var-name>maxlength</var-name>
                    <var-value>16</var-value>
                </var>
                <var>
                    <var-name>minlength</var-name>
                    <var-value>6</var-value>
                </var>
            </field>
        </form>
     </formset>
</form-validation>
我向大家一看就能明白这个配置文件的含义,我们的JSP页面的名称叫loginForm, 这个登陆页面有两个字段,一个是用户名username,一个是密码passwd.在这里这两个字段都有三个约束,required,minlength,maxlength, 分别表示这两个字段需要用户输入,最小长度,最大长度。针对用户名,必须是从3到16个字符(包括3和16),而密码必须是不能少于6个字符,而且不能多于16个字符。

如果你需要增加其他form得校验配置,可以在formset中增加相应的form配置。

第二步:修改struts-config.xml文件,增加如下代码:
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
    <set-property property="pathnames" value="/WEB-INF/config/validator-rules.xml,/WEB-INF/config/validation.xml" />
  </plug-in>
这里校验规则文件是:validator-rules.xml

第三步:修改页面文件
在页面增加以下代码,告诉struts这个页面中要增加针对哪个form的配置的javascript页面校验代码:
<html:javascript formName="loginForm" />
然后在要校验的form中的onsubmit事件中增加return validateLoginForm(this);来进行校验,就像下面的代码:
<html:form method="post"
       action="/login.do"
       focus="username"
       onsubmit="return validateLoginForm(this);">

通过这三步你就可以直接使用定义好的一些页面校验功能,当然这是客户端校验,你也可以使用服务

段的后台校验。

当然如果在你的web程序中,你没有采用struts,或者你使用的是asp,asp.net什么的,你也想使用这么方便通用的页面校验功能,那怎么办呢?

其实,很简单,你只要把
validator-rules.xml中定义的规则拿出来,然后定义一个javascript的类,就可以达到这个目的了。下面我就列出这个类的一部分:
function validation(form)
{
    //------variable deifinition start---------------------------------------
    var form=form;
    var arrRequired=null;
    var arrMinLength=null;
    var arrMaxLength=null;
    var arrEmail=null;
    var arrMask=null;
    var arrDateValidation=null;
    var arrEqualValidation=null;
 //------variable deifinition end-----------------------------------------
 
 //------check argument start---------------------------------------------
 if(typeof form != "object" )
 {
  alert("The argument of validation must be a valid page form!");
  return;
 }
 //------check argument end-----------------------------------------------
 
 //------inner class definition start-------------------------------------
 function required(fieldname,msg)
 {
  this.fieldname=fieldname;
  this.msg=msg;
 }
this.validate=validate;
this.addRequired=addRequired;
/**
  *  Add field which must input data. The message will be shown to user if the field has no data.
  *  @param  fieldname   field name.
  *  @param  msg         The msg will be shown to user if the field is empty.
  */
 function addRequired(fieldname,msg)
 {
      if(null == arrRequired)
     {
             arrRequired=new Array();
     }
    var tmpLen=arrRequired.length;
    arrRequired[tmpLen]=new required(fieldname,msg);
 }
function validate()
 {
  var isValid=true;
  if(null != arrRequired)
  {
   isValid=isValid && validateRequired(form,arrRequired);
  }
}
}
/**
 * Validate fields in forms¡£
 * @param form           Form will be validated.
 * @param arrRequired    Array of fields which be setted.
 * @return   true or false. Return true if validation is passed,
 *           else return false.
 */
function validateRequired(form,arrRequired)
{
 var isValid = true;
 var focusField = null;
 var i = 0;
 var fields = new Array();
 for (x in arrRequired)
 {
  var field = form[(arrRequired[x]).fieldname];

  if (field.type == 'text' ||
  field.type == 'textarea' ||
  field.type == 'file' ||
  field.type == 'select-one' ||
  field.type == 'radio' ||
  field.type == 'password')
  {

   var value = '';
   // get field's value
   if (field.type == "select-one")
   {
    var si = field.selectedIndex;
    if (si >= 0)
    {
     value = field.options[si].value;
    }
   }
   else
   {
    value = field.value;
   }

   if (trim(value).length == 0)
   {

    if (i == 0)
    {
     focusField = field;
    }
    fields[i++] = (arrRequired[x]).msg;
    isValid = false;
   }
  }
 }
 if (fields.length > 0)
 {
  focusField.focus();
  alert(fields.join('\n'));
 }
 return isValid;
}

这个类的完整文件已经被上传到我的blog中了。

然后在你的页面增加如下脚本就可以达到校验的目的了:
function check(form)
{
    var ovalidation=new validation(form);
   ovalidation.addRequired("username","User name is required!");
   ovalidation.addRequired("passwd","User password is required!");
   return ovalidation.validate();
}

然后在form的onsubmit事件中增加return check(this);就大功告成了。
(如需转载请署名出处)

posted @ 2005-03-10 17:30 SNOW NO Track 阅读(635) | 评论 (0)编辑 收藏
 

1、             范围

JCA1.0定义了在应用服务器和EIS(企业信息系统)之间系统级的一个标准的协议集合,这些协议集中于集成的系统级的重要方面:连接管理(connection management),事务管理(transaction management),安全管理(security management)。并且定义了客户端与多个企业信息系统交互的CCI(Common Client Interface)通用客户端接口,以及针对资源适配器的一个标准的配置发布及打包协议。

       JCA1.5定义了以下协议:

²       生命周期管理协议(Lifecycle management contract):这是应用服务器和资源适配器之间的一个协议,允许应用服务器来管理资源适配器的生命周期。这个协议为应用服务器在资源适配器在配置发布或应用服务器启动的时候提供一种启动资源适配器实例的机制,并且在资源适配器卸载或应用服务器关闭的时候通知资源适配器实例关闭。

²       工作管理协议(Work managerment contract):这是应用服务器和资源适配器之间的一个协议,该协议允许资源适配器通过提交工作实例给应用服务器来做一些工作(象监视网络端口,调用应用程序组件等)。然后应用服务器通过分配线程来执行提交的工作实例,这就避免了资源适配器为了执行一些任务来直接创建或者管理线程,并且可以使得应用服务器在运行时环境对线程池来实施更多更有效的控制管理。并且资源适配器能控制被执行的工作实例的安全上下文环境和事务上下文环境。

²       事务流入协议(Transaction inflow contract:该协议是应用服务器和资源适配器之间的一个协议,它允许资源适配器来传递一个输入事务到应用服务器。这个协议也允许资源适配器来传递由企业信息系统初始化的事务完成和故障恢复调用,并且能确保被输入的事务的ACID(Atomicity原子性,Consistency一致性,Isolation隔离性 and Durability持久性)属性被保留。

²       消息流入协议(Message inflow contract):这是应用服务器和资源适配器之间一个标准的、通用的协议,它允许资源适配器以独立于发送消息所使用的具体消息格式、消息语义、消息结构的方式异步的发送消息到位于应用服务器中的消息端口。这个协议也允许更广泛消息提供者(象Java Message Service,Java API for XML Messaging等)通过资源适配器以插件的方式插入到J2EE兼容的应用服务器中。

²       针对不通类型(outbound only输出,inbound only输入,or both输入输出)的资源适配器描述对应的打包模式。

2、             生命周期管理

²      应用服务器实现javax.resource.spi.BootstrapContextjavax.resource.spi.WorkManager接口。资源适配器实现javax.resource.spi.ResourceAdapter接口。实现ResourceAdapter接口的类是在资源适配器的配置描述文件中指定的,并且这个实现类必须是一个JavaBean

当一个资源适配器被配置发布或者应用服务器启动的时候,应用服务器在它自己的地址空间启动一个资源适配器的实例。为了启动一个资源适配器实例,应用服务器必须使用配置了的ResourceAdapter接口的实现类,并且调用它的start方法,这个start方法调用是来自应用服务器的启动通知,并且这个start方法是被应用服务器的线程调用的。

一个应用服务器允许在同一个JVM中同时存在多个资源适配器实例,但这些实例不一定相等,判断这些实例是否相等,可以通过实例的equals方法,因此ResourceAdapter接口的实现类需要实现equals方法。

start方法调用中,资源适配器实例初始化自己,并且可能使用WorkManager来提交Work实例来执行。这个start方法调用应该及时返回,应该避免阻塞调用,如调用WorkManager实例的doWork方法就是阻塞调用。如果在start方法中调用了WorkManager实例的doWork方法或者任何阻塞的方法,应用服务器都可能抛出一个WorkRejectedException异常,为了强制start方法不被阻塞,强烈建议资源适配器实现使用WorkManagerstartWorkscheduleWork方法来代替doWork方法。

在调用start方法时抛出任何异常将导致应用服务器创建资源适配器实例失败,在JCA将来的版本中可能要增加两阶段启动过程。

ResourceAdapter JavaBean表示一个资源适配器实例,并且包含相对应资源适配器实例的配置信息,这个配置信息对ManagedConnectionFactory或者ActivationSpec JavaBean来说可能也被使用作为全局缺省的配置信息。

一个资源适配器实例对于多个企业信息系统实例来说可能提供双向的链接。一个ManagedConnectionFactory JavaBean能被使用来提供对单个的企业信息系统的输出连接。一个ActivationSpec JavaBean能被使用来提供来自企业信息系统的输入连接;一个资源适配器实例可能包括几个ManagedConnectionFactoryActivationSpec JavaBean

²      一个ManagedConnectionFactory JavaBean就表示通过资源适配器从应用到企业信息系统实例的一个输出链接。同时也包含相应的输出连接配置信息,该配置信息是是继承ResourceAdapter JavaBean的配置信息的,也就是说输出连接的配置信息是ResourceAdapter JavaBeanManagedConnectionFactory JavaBean两者配置信息的综合,并且ManagedConnectionFactory的配置信息可能覆盖ResourceAdapter的配置信息(在两者中都存在相同名称的配置信息时)。

²      输出连接是由应用服务器发起的,并且必须创建一个ManagedConnectionFactory JavaBeanResourceAdapter JavaBean之间的一个关联,建立关联是通过调用RsourceAdapterAssociation接口的setResourceAdapter方法来做到的,ResourceAdapterAssociation接口指明ManagedConnectionFactory JavaBeanResourceAdapter JavaBean之间的关联关系。setResourceAdapter至少要调用一次,也就是说这个关联也是可以改变的。

²      一个ActivationSpec JavaBean表示通过资源适配器实例从企业信息系统到应用服务器的输入连接,它也同样包含输入连接的配置信息,该配置信息也是ResourceAdapter JavaBeanActivationSpec JavaBean的综合。输入连接是由企业信息系统发起的。ActivationSpec JavaBean也必须和ResouceAdapter JavaBean关联,因为不管是输出连接还是输入连接都是通过ResourceAdapter这个中间桥梁来建立连接的。也是通过setResourceAdatper方法来达到关联的目的的。

²      资源适配器实例关闭需要经过两个阶段:第一阶段应用服务器停止所有使用此资源适配器实例的应用组件,直到所有的应用线程不在使用此资源适配器实例。第二阶段是调用ResourceAdapter JavaBeanstop方法来通知资源适配器实例停止服务。

3、             连接管理

A)     应用程序组件通过JNDI找到连接工厂ConnectionFactory

B)     ConnectionFactory将创建连接的请求传给ConnectionManager实例。

C)     ConnectionManager接收到连接工厂的请求之后,查询由应用服务器提供的连接池,如果有符合要求的连接在池中就将匹配的ManagedConnection实例来满足连接请求,直接返回给连接工厂,然后连接工厂返回给应用组件,如果没有符合要求的连接在池中,应用服务器就使用ManagedConnectionFactory接口的实现类(在资源适配器中实现)来创建一个新的到企业信息系统的底层物理连接,应用服务器将这个新创建的ManagedConnection实例放到连接池中,并且注册一个ConnectionEventListener实现到ManagedConnection实例中,这个监听器可以使应用服务器得到关于ManagedConnection实例状态改变的通知。然后返回给应用组件。

posted @ 2005-03-10 16:39 SNOW NO Track 阅读(637) | 评论 (0)编辑 收藏
 
     摘要: 1、XLink的规格说明书是用来描述和创建在XML文档中资源之间的链接语言规范,目前W3C的此工作组由于工作已经完成所以已经解散了。这个规范定义了两种链接声明类型,即简单型的(类型为simple的)和扩展型的(类型为extended),其实简单型的链接是扩展型的链接的便于书写的简单形式。 2、要声明一个XML文档的链接,必须在这个所声明的链接的元素中定义这个命名空间:http://www.w3....  阅读全文
posted @ 2005-03-10 16:21 SNOW NO Track 阅读(593) | 评论 (0)编辑 收藏
 

1、XML Base提供了一种通过显式的指定一个基准URI(base URI),并通过此base URI来解析指向外部资源的相对URI的方式。具体是通过指定XML元素的xml:base属性来实现的。

2、目前只有三个有关XML的规范是基于XML Base的,将其作为他们标准引用的一部分:XLinkXML InfoSetCannonical XML。其他的很少或者基本上和XML Base无关。XML Namespace使用了URI但不是通过xml:base属性来解析的。XPath没有使用相对URI引用,所以也没有使用XML BaseXSLT使用了与XML Base不兼容的基URI的方式。

3、以下是一个例子:

<?xml version="1.0"?>
<doc xml:base="http://example.org/today/"
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <head>
    <title>Virtual Library</title>
  </head>
  <body>
    <paragraph>See <link xlink:type="simple" xlink:href="new.xml">what's  new</link>!</paragraph>
    <paragraph>Check out the hot picks of the day!</paragraph>
    <olist xml:base="/hotpicks/">
      <item>
        <link xlink:type="simple" xlink:href="pick1.xml">Hot Pick #1</link>
      </item>
      <item>
        <link xlink:type="simple" xlink:href="pick2.xml">Hot Pick #2</link>
      </item>
      <item>
        <link xlink:type="simple" xlink:href="pick3.xml">Hot Pick #3</link>
      </item>
    </olist>
  </body>
</doc>

本例中的URIs被解析为下列完整的URIs

Ø        "what's new"被解析为URI "http://example.org/today/new.xml"

Ø        "Hot Pick #1"被解析为URI "http://example.org/hotpicks/pick1.xml"

Ø        "Hot Pick #2"被解析为URI "http://example.org/hotpicks/pick2.xml"

Ø        "Hot Pick #3"被解析为URI "http://example.org/hotpicks/pick3.xml"

4、基准URI一定是绝对URI,是根据RFC 2396中的规则计算得到的URI,通过xml:base属性指定的值是基准URI信息,并且xml:base的值可以是绝对URI,也可以是相对URI

5、某个具体元素的基准URI是由该元素的xml:base属性指定的,如果该元素没有指定xml:base属性,则是由该元素的父元素的URI指定的,如果父元素也没有指定xml:base的话,则是由该文档的xml:base属性所指定的。

posted @ 2005-03-10 16:04 SNOW NO Track 阅读(580) | 评论 (0)编辑 收藏
 
     摘要: 1、关于include的用法 include元素可以将外部的定义和声明引入到文档中,并且作为新Schema文档的一部分,但必须注意的一点是,被包含成员的目标命名空间必须和包含的目标命名空间一样。具体写法例子是: <include schemaLocation=“http://www.example.com/schemas/address.xsd” /> 2、如果一个类型是从另一个...  阅读全文
posted @ 2005-03-10 15:59 SNOW NO Track 阅读(656) | 评论 (0)编辑 收藏
 
     摘要: 1、复杂类型和简单类型之间最根本的区别就是:复杂类型的内容中可以包含其他元素,也可以带有属性(Attribute),但简单类型既不能包含子元素,也不能带有任何属性。 <xsd:complexType name="CNAddress" >   <xsd:sequence>    <xsd:element name="name"&nbs...  阅读全文
posted @ 2005-03-10 13:21 SNOW NO Track 阅读(883) | 评论 (0)编辑 收藏