`

Jsf 验证 和 转换

    博客分类:
  • Jsf
阅读更多
JSF的转换与验证
2008年04月22日 星期二 下午 02:30
关注生命周期阶段
转换和验证阶段的 JSF 生命周期图
关于 immediate 属性
上图中描绘的转换和验证过程表示了将 UIInput 组件的 immediate 属性设置为 false 时的应用程序流程。 如果这个属性设置为 true,那么转换和验证会发生在生命周期更早的时期,即应用请求值阶段.
将 immediate 属性设置为 true
将 immediate 属性设置为 true 时的 JSF 生命周期图

JSF 转换
JSF 提供了许多标准数据转换器。也可以通过实现 Converter 接口插入 自定义转换器,但是这些将在后面进行介绍。下表显示了 JSF 进行简单数据转换所使用的转换器 id 及其对应的实现类。大多数数据转换是自动发生的。
javax.faces.BigDecimal javax.faces.convert.BigDecimalConverter
javax.faces.BigInteger javax.faces.convert.BigIntegerConverter
javax.faces.Boolean javax.faces.convert.BooleanConverter
javax.faces.Byte javax.faces.convert.ByteConverter
javax.faces.Character javax.faces.convert.CharacterConverter
javax.faces.DateTime javax.faces.convert.DateTimeConverter
javax.faces.Double javax.faces.convert.DoubleConverter
javax.faces.Float javax.faces.convert.FloatConverter
例子:用户年龄的默认转换。JSF 标签配置如下:
<!-- UserRegistration.jsp -->
h:inputText id="age" value="#{UserRegistration.user.age}"/>

默认转换
UserRegistration.user的age属性是个int型
对于基本型或者 BigInteger/
BigDecimal 的绑定,JSF 选择了标准转换器。不过,还可以通过
<f:converter/> 标签,利用一个特定的转换器来增加粒度:
<!-- UserRegistration.jsp -->
<h:inputText id="age" value="#{UserRegistration.user.age}">
             <f:converter id="javax.faces.Short"/>
</h:inputText>
使用 f:converter 标签
在这种情况下,虽然年龄实际上是一个有效的整数,但转换仍然会失败,因为该值不是短整型的

选择日期格式样式

尽管在默认情况下,JSF 可以很好地处理基本型及类似的类型,但是在处理 日期数据时,必须指定转换标签 <f:convertDateTime/>。 这个标签基于 java.text 包,并使用短、长和自定义样式。下面是一 个例子:

<!-- UserRegistration.jsp -->
<h:inputText id="birthDate" value="#{UserRegistration.user.birthDate}">
             <f:convertDateTime pattern="MM/yyyy"/>
</h:inputText>

这个例子展示了如何用 <f:convertDateTime/> 确保用户的生日可以转换为 格式为 MM/yyyy(月/年)的日期对象。请参阅 JSF 的 java.text.SimpleDataFormat (在 参考资料 中),以获取模式列表。

其他样式

除了可以转换日期和时间格式外,JSF 还 提供了处理像百分数或者货币数据这类值的特殊转换器。 这个转换器处理分组(如逗号)、小数、货币符号等。例如, 以下 <f:convertNumber/> 的用法就是处理货币的一种技巧:

<!-- UserRegistration.jsp -->
<h:inputText id="salary" value="#{UserRegistration.user.salary}">
             <f:convertNumber maxFractionDigits="2"
                       groupingUsed="true"
                       currencySymbol="$"
                       maxIntegerDigits="7"
                       type="currency"/>
</h:inputText>

在图 6 中,可以看到一些格式编排不正确的货币数据,以及所导致的转换错误。


图 6. 使用 f:convertNumber 标签
使用 f:convertNumber 标签

自定义转换

如果需要将字段数据转换为特定于应用程序的值对象,则需要自定义数据转换, 如下面例子所示:

  • String 转换为 PhoneNumber 对象 (PhoneNumber.areaCode、PhoneNumber.prefix、 ...)。
  • String 转换为 Name 对象 (Name.first、Name.last)。
  • String 转换为 ProductCode 对象 (ProductCode.partNum、ProductCode.rev、 ...)。

要创建自定义转换器,必须完成以步骤:

  1. 实现 Converter 接口(也就是 javax.faxes.convert.Converter)。
  2. 实现 getAsObject 方法,它将一个字段(字符串) 转换为一个对象(例如,PhoneNumber)。
  3. 实现 getAsString 方法,它将一个对象 (如 PhoneNumber)转换为一个字符串。
  4. Faces 上下文中注册自定义转换器。
  5. <f:converter/> 标签在 JSP 中插入这个转换器。

您可以自己看到如何在 JSF 应用程序生命周期中加入这些步骤。 在图 7 中,JSF 在应用请求值阶段调用自定义转换器的 getAsObject 方法。 转换器必须在这里将请求字符串转换为所需的对象类型,然后返回这个对象,将它存储在相应的 JSF 组件中。 如果该值被返回呈现在视图中,那么 JSF 将在呈现响应阶段调用 getAsString 方法。 这意味着转换器还要负责将对象数据转换回字符串表示形式。


图 7. 自定义转换器 getAsObject 和 getAsString 方法
getAsObject,getAsString 自定义转换器方法

创建自定义转换器

我们将使用一个案例分析来展示 Converter 接口、getAsObjectgetAsString 方法的实现,同时还将展示如何在 Faces 上下文中注册这个转换器。

这个案例分析的目的是将一个单字段字符串值转换为一个 PhoneNumber 对象。我们将一步一步地完成这个转换过程。

第 1 步:实现 Converter 接口

这一步实现 Converter 接口。

import javax.faces.convert.Converter;
import org.apache.commons.lang.StringUtils;
...
public class PhoneConverter implements Converter {
 ...
}

第 2 步:实现 getAsObject 方法

这一步将一个字段值转换为一个 PhoneNumber 对象。

public class PhoneConverter implements Converter {
 ...
 public Object getAsObject(FacesContext context, UIComponent component, String value) {
     if (StringUtils.isEmpty(value)){ return null;}
     PhoneNumber phone = new PhoneNumber();
     String [] phoneComps = StringUtils.split(value," ,()-");
     String countryCode = phoneComps[0];
     phone.setCountryCode(countryCode);
     if ("1".equals(countryCode)){
         String areaCode = phoneComps[1];
         String prefix = phoneComps[2];
         String number = phoneComps[3];
         phone.setAreaCode(areaCode);
         phone.setPrefix(prefix);
         phone.setNumber(number);
     }else {
         phone.setNumber(value);
     }
     return phone;
 } 
}

第 3 步:实现 getAsString 方法

这一步将一个 PhoneNumber 对象转换为一个字符串。

public class PhoneConverter implements Converter {
 ...
 public String getAsString(FacesContext context, 
         UIComponent component, Object value) {
  return value.toString();
 }
}
public class PhoneNumber implements Serializable {
 ...
 public String toString(){
  if (countryCode.equals("1")){
   return countryCode + " " + areaCode 
          + " " + prefix + " " + number;
  }else{
   return number;
  }
 }
}

第 4 步:在 faces 上下文中注册自定义转换器

第 4 步可以以两种方式执行。第一种选择使用(比如)arcmind.PhoneConverter 的 id 来注册 PhoneConverter 类。JSP 页中的 <f:converter/> 标签会使用这个 id。下面是 第 4 步的选项 1 的代码:

<converter>
  <converter-id>arcmind.PhoneConverter</converter-id>
  <converter-class>com.arcmind.converters.PhoneConverter</converter-class>
      
</converter>

另一种方法是注册 PhoneConverter 类来自动处理所有 PhoneNumber 对象,如下所示。

<converter>
  
  <converter-for-class>com.arcmind.value.PhoneNumber</converter-for-class>
  <converter-class>com.arcmind.converters.PhoneConverter</converter-class>
      
</converter>

第 5 步:在 JSP 中使用转换器标签?

自然,下一步的执行取决于所选的注册方法。如果选择使用 arcmind.PhoneConverter 的 id 来注册 PhoneConverter 类,那么就使用 <f:converter/> 标签,如下所示。

<h:inputText id="phone" value="#{UserRegistration.user.phone}">
        <f:converter  converterId="arcmind.PhoneConverter" />
</h:inputText>

如果选择注册 PhoneConverter 类来自动 处理所有 PhoneNumber,那么就不需要在 JSP 页 中使用 <f:converter/> 标签。下面是第 5 步的不带转换器标签的代码。

<h:inputText id="phone" value="#{UserRegistration.user.phone}">
        [Look mom no converter!]
</h:inputText>

这样,我们已经完成了这个示例应用程序的转换处理代码!到目前为止完成的应用程序如下所示。


图 8. 带有转换处理的示例应用程序
带有转换处理的示例应用程序

JSF 验证

如前所述,JSF 验证可以确保应用程序数据包含预期的内容,例如:

  • java.util.Date 为 MM/yyyy 格式。
  • Float 在 1.0 和 100.0 之间。

在 JSF 中有 4 种验证:

  • 自带验证组件。
  • 应用程序级验证。
  • 自定义验证组件(它实现了 Validator 接口)。
  • 在 backing bean 中的验证方法(内联)。

我们将在下面的讨论中介绍并展示每一种形式。

JSF 验证生命周期和组件

图 9 显示了用户注册表单中名字字段的生命周期案例分析。代码引用被有意解释为 伪代码(pseudo-code)。


图 9. JSF 生命周期中的验证
JSF 生命周期中的验证过程展示

下面是 JSF 提供的一组标准验证组件:

  • DoubleRangeValidator:组件的本地值必须为数字类型,必须 在由最小和/或最大值所指定的范围内。
  • LongRangeValidator:组件的本地值必须为数字类型,并且可以转换 为长整型,必须在由最小和/或最大值所指定的范围内。
  • LengthValidator:类型必须为字符串,长度必须在由最小和/或 最大值所指定的范围内。

标准验证

在我们的示例应用程序中,用户的年龄可以是任意有效的整数(byte、short、int)。 因为将年龄设置为(比如说)-2 是无意义的,所以可能要对这个字段添加一些验证。 下面是一些简单的验证代码,用以确保年龄字段中的数据模型完整性:

<h:inputText id="age" value="#{UserRegistration.user.age}">
          <f:validateLongRange maximum="150"
                                  minimum="0"/>
</h:inputText>

完成年龄字段后,可能希望指定对名字字段的长度加以限制。可以像这样编写这个验证:

<h:inputText id="firstName"
                value="#{UserRegistration.user.firstName}">
 <f:validateLength minimum="2" 
       maximum="25" />
</h:inputText>

图 10 显示了由上面标准验证示例所生成的默认详细验证消息。


图 10. 标准验证错误消息
带有标准验证错误消息的示例应用程序的屏幕快照

尽管 JSF 自带的验证在许多情况下都可以满足,但是它有一些局限性。 在处理电子邮件验证、电话号码、URL、日期等数据时,有时编写自己的验证 器会更好一些,不过我们将在稍后对此进行讨论。

在概念上,应用程序级验证实际上是业务逻辑验证。JSF 将表单和/或字段级 验证与业务逻辑验证分离开。应用程序级验证主要需要在 backing bean 中添加代码,用这个模型确定绑定到模型中的数据是否合格。对于购物车,表单级验证 可以验证输入的数量是否有效,但是需要使用业务逻辑验证检查用户是否超出了他或者 她的信用额度。这是在 JSF 中分离关注点的另一个例子。

例如,假定用户单击了绑定到某个操作方法的按钮,那么就会在调用应用程序阶段调用 这个方法(有关的细节,请参见上面的图 1)。假定在更新模型阶段进 行了更新,那么在对模型数据执行任何操纵之前,可以添加一些验证代码,根据应用程序的业务规则检查输入的数据是否有效。

例如,在这个示例应用程序中,用户单击了 Register 按钮,这个按钮被绑定到应用程序控制器的 register() 方法。 我们可以在 register() 方法中添加验证代码,以确定名字字段是否为 null。如果该字段为 null,那么还可以在 FacesContext 中添加一条消息,指示相关组件返回到当前页。

其实它现在并不是业务规则逻辑的一个好例子。更好的例子是检查用户是否 超出了她或者她的信用额度。在该例中,不是检查字段是否为空,我们可以调用模型对象的方法来确保当前用户已经不在系统中。

图 11 描绘了这个过程。


图 11. 应用程序级验证
应用程序级验证图

注意在 register() 方法中,消息是如何以 ${formId}:${fieldId} 的形式添加到 FacesContext 中的。 图 12 显示了消息与组件 id 之间的关系。


图 12. 验证消息
验证消息

应用程序级验证的优缺点

应用级验证非常直观并且容易实现。不过,这种形式的验证是在其他形式的验证 (标准、自定义、组件)之后发生的。

应用程序级验证的优点如下:

  • 容易实现。
  • 不需要单独的类(自定义验证器)。
  • 不需要页编写者指定验证器。

应用程序级验证的缺点如下:

  • 在其他形式的验证(标准、自定义)之后发生。
  • 验证逻辑局限于 backing bean 方法,使得重用性很有限。
  • 在大型应用程序和/或团队环境中可能难于管理。

最终,应用程序级验证只应该用于那些需要业务逻辑验证的环境中。

自定义验证组件

对于标准 JSF 验证器不支持的数据类型,则需要建立自己的自定义验证组件,其中包括电子邮件地址和邮政编码。如果需要明确控制显示给最终用户的消息, 那么还需要建立自己的验证器。在 JSF 中,可以创建可在整个 Web 应用程序中重复使用 的可插入验证组件。

MyFaces 是一个 JSF 的开放源代码实现,它提供了许多额外的验证器,其中包括一些 JSF 中所没有的验证器。要了解 MyFaces 的内容,请参阅参考资料

创建自定义验证器的步骤如下,我们将一步步地分析:

  1. 创建一个实现了 Validator 接口的类 (javax.faces.validator.Validator)。
  2. 实现 validate 方法。
  3. 在 faces-confix.xml 文件中注册自定义验证。
  4. 在 JSP 页中使用 <f:validator/> 标签。

下面是创建自定义验证器的分步示例代码。

第 1:实现 Validator 接口

第一步是实现 Validator 接口。

import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
...
public class ZipCodeValidator implements Validator{
 private boolean plus4Required;
 private boolean plus4Optional;
 /** Accepts zip codes like 85710 */
 private static final String ZIP_REGEX = "[0-9]{5}";
 
 /** Accepts zip code plus 4 extensions like "-1119" or " 1119" */
 private static final String PLUS4_REQUIRED_REGEX = "[ |-]{1}[0-9]{4}";
 
 /** Optionally accepts a plus 4 */
 private static final String PLUS4_OPTIONAL_REGEX = "([ |-]{1}[0-9]{4})?";
 ...
}

第 2 步:实现验证方法

接下来,需要实现 validate 方法。

public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
   
      /* Create the correct mask */
      Pattern mask =  null; 
   
      /* more on this method later */
      initProps(component);
      if (plus4Required){
            mask = Pattern.compile(ZIP_REGEX + PLUS4_REQUIRED_REGEX);
      } else if (plus4Optional){
            mask = Pattern.compile(ZIP_REGEX + PLUS4_OPTIONAL_REGEX);
      } else if (plus4Required && plus4Optional){
            throw new IllegalStateException("Plus 4 is either optional or required");
      }
      else {
            mask = Pattern.compile(ZIP_REGEX);
      }
            /* Get the string value of the current field */
      String zipField = (String)value; 
    
            /* Check to see if the value is a zip code */
    Matcher matcher = mask.matcher(zipField);
      
    if (!matcher.matches()){
       
       FacesMessage message = new FacesMessage();
       message.setDetail("Zip code not valid");
       message.setSummary("Zip code not valid");
       message.setSeverity(FacesMessage.SEVERITY_ERROR);
       throw new ValidatorException(message);
    }
 }

第 3 步:在 FacesContext 中注册自定义验证器

您现在应该熟悉在 FacesContext 中注册自定义验证器的代码了。

<validator>
    <validator-id>arcmind.zipCodeValidator</validator-id>
    <validator-class>com.arcmind.jsfquickstart.validation.ZipCodeValidator</validator-class>
  </validator>

第 4 步:在 JSP 中使用 <f:validator/> 标签

<f:validator/> 标签声明使用 zipCodeValidator<f:attribute/> 标签将 plus4Optional 属性设置为 true。 注意,它定义了 inputText 组件的属性,而不是 验证器的属性!

<h:inputText id="zipCode" value="#{UserRegistration.user.zipCode}">
      <f:validator validatorId="armind.zipCodeValidator"/>
      <f:attribute name="plus4Optional" value="true"/>
  </h:inputText>

为了读取 zipCode inputText 组件的 plus4Optional 属性,请完成以下步骤::

private void initProps(UIComponent component) {
  Boolean optional = Boolean.valueOf((String) component.getAttributes().
                                   get("plus4Optional"));
  Boolean required = Boolean.valueOf((String) component.getAttributes().
                                   get("plus4Required"));
  plus4Optional = optional==null ? plus4Optional : 
          optional.booleanValue();
  plus4Required = required==null ? plus4Optional : 
          required.booleanValue();
}

总体而言,创建自定义验证器是相当直观的,并且可以使该验证在许多应用程序中重复使用。缺点是必须创建一个类,并在 faces 上下文中管理验证器注册。 不过,通过创建一个使用这个验证器的自定义标签,使其看上去像是一个自带的验证,可以进一步实现自定义验证器。对于常见的验证问题,如电子邮件 验证,这种方法可以支持这样一种设计理念,即代码重用和一致的应用程序行为是 最重要的。

backing bean 中的验证方法

作为创建单独的验证器类的替代方法,可以只在 backing bean 的方法中实现自定义 验证,只要这个方法符合 Validator 接口的 validate 方法的参数签名即可。例如,可以编写以下方法:

[SomeBackingBean.java]
public void validateEmail(FacesContext context, 
                          UIComponent toValidate,
                          Object value) {
    String email = (String) value;
    if (email.indexOf('@') == -1) {
       ((UIInput)toValidate).setValid(false);
        FacesMessage message = new FacesMessage("Invalid Email");
        context.addMessage(toValidate.getClientId(context), message);
    }
}

之后,可通过如下所示的 validator 属性在 JSF 中使用这个方法:

<h:inputText id="email" 
               value="#{UserRegistration.user.email}"
               validator="#{UserRegistration.validateEmail}"   
               required="true">
  </h:inputText>

JSF 用 validateEmail 方法对绑定到 user.email 模型属性的 inputText 组件值进行自定义验证。如果电子邮件格式无效,那么就在相关组件的 faces 上下文中添加 消息。考虑到这种验证方法实际上是 backing bean 的一部分,为什么通常必须用某个值与相关组件的关联来评估该值,而不是直接检查本地 bean 属性呢?线索就在前面的生命周期图中。如果现在不能马上找到 答案,也不要担心,我们将在本文的最后对此加以说明。

默认验证

注意上面 email 标签的 required 属性。 利用 required 属性是一种默认 验证形式。如果这个属性是 true,那么相应的组件必须有一个值。一个重要的 说明:如果 required 属性为 false, 那么就不用对这个标签/组件指派验证,这样,JSF 将跳过对这个组件的验证,并让值和组件的状态保持不变。

图 13 概述了我们讨论过的验证形式。


图 13. 验证视图
JSF 中验证形式的一览图

   

自定义消息

您可能注意到了,JSF 提供的默认转换和验证消息非常长,这会让那些总是输入无效表单数据的最终用户感到困惑和恼火。幸运的是,您可以通过 创建自己的消息资源绑定来改变 JSF 提供的默认消息。jsf-impl.jar (或类似的文件中)中包含了一个 message.properties 文件,该文件包含图 14 所示的默认消息。


图 14. 默认 JSF 转换和验证消息
JSF 的默认转换和验证消息

通过创建自己的 message.properties 文件并断开指定场所的 faces 上下文中绑定 的消息资源,您可以更改默认消息,如图 15 所示。


图 15. 取消消息资源绑定
消息绑定

关于在 JSF 中创建自定义转换和验证消息的更多内容请参前阅 参考资料

处理 JSF 生命周期

我们在本文前面留下了一些问题让您考虑,现在可以解决它们了! 我们提到的一件事是对 UICommand 按钮使用 immediate 属性,比如 commandLink 或者 commandButtons。现在请您考虑希望在什么样的场景中跳过验证。

基本上只要用户需要输入数据,就需要对这个数据进行验证。不过,如果整个数据 项是可选的,那么就不需要进行验证。一种避免 JSF 生命周期的验证阶段的方法是利用 UICommand 组件的 immediate 属性,该属性可以在处理验证阶段之前 的应用请求值阶段期间(而不是在处理验证阶段 之后 的调用应用程序阶段) 强制调用这个操作。

immediate 属性允许您通过标准浏览规则控制 页流程,并绕过验证。可以针对特定的场景实现这项技术,比如带有可选步骤和/或表单的在线 向导(如当用户单击 Skip 按钮以进入下一视图),或者在用户因为某种原因而取消某个表单的情况下。

我们在本文中留下的第二个问题是:既然验证方法实际上是 backing bean 的 一部分,那么为什么通常必须利用组件关联来判断它的值。请参阅前面的 JSF 应用程序生命周期,看看您能否找到答案。

这里的密诀是:尽管 validateEmail 嵌入 验证方法是实际的 backing bean 的一部分,但是该方法必须通过组件关联来引用这,而不是直接访问本地属性来引用值。由于验证发生在组件值绑定到模型之前(在更新模型值阶段),所以模型处于未知状态。 因此,必须编写嵌入自定义验证逻辑,就像使用一个自定义 Validator 对象处理验证一样。这也解释了维护相同方法签名的需求。

这些尚待解决的枝节问题有什么意义呢,当然,它们最终将我们带回 JSF 应用程序生命周期。将这些问题汇总在一起,就能体现充分理解生命周期的重要性 —— 向后、向前或由内向外,这样您就可以在需要的时候操纵它。

分享到:
评论

相关推荐

    第7章 JSF转换器和验证器与实例程序

    第7章 JSF转换器和验证器与实例程序 JSF转换器和验证器(熊).ppt convertTest registraction validatorTest

    JSF 转换与验证 - 利用 JSF 的转换和验证框架来确保数据模型的完整性.rar

    JSF 转换与验证 - 利用 JSF 的转换和验证框架来确保数据模型的完整性.rar

    JSF自定义转换器验证器实例

    教你如何编写属于自己的JSF程序

    JSF(转换器+验证器)

    jsf转换器加上验证器,一个很好的原创代码啊,一定要好好学习

    JSF 转换与验证 .rar

    JSF 转换与验证 .rar

    JavaEE5学习笔记11-JSF转换器验证器使用经验总结

    JavaEE5学习笔记11-JSF转换器验证器使用经验总结。

    JSF培训教程

    JSF培训教程,主要内容:JSF简介、JSF入门、JSF标签、JSF数据验证和转换 、JSF表格、JSF与Struts的区别

    JSF基础教程 简体中文

    JSF入门如果您是从使用的角度来看JSF,则您不用理会HTTP、数据转换等细节,JSF将细节都隐藏起来了,无论您是网页设计人员或是应用程序设计人员,都可以使用自己熟悉的方式来看JSF。 入门 藉由以下的几个主题,可以...

    JavaServer Faces 2.0完全参考手册(JSF2.0中文版) 1/2

    8.2 转换和验证揭秘 8.3 Faces转换器系统 8.3.1 Date Time Converter 8.3.2 Number Converter 8.3.3 关联转换器与UI Component实例 8.3.4 转换器的生命周期 8.3.5 定制转换器 8.4 Faces验证系统 8.4.1 Long Range ...

    JSF入门教程

    jsf入门教程讲解了JSF入门,managed beans,数据转换与验证,事件处理

    JSF实战 练习 开发

    本书适合正在开发java web应用的架构师、应用开发人员阅读。 本书集教程、案例和参考于一身,讲解了何为jsf,它的工作...书中还讲解了标准组件、呈现器、转换器和验证器的各种细节,以及如何应用它们来构建实际应用。

    JSF入门pdf

    3. 数据转换与验证 3.1 标准转换器 3.2自定义转换器 3.3标准验证器 3.4自定义验证器 3.5错误信息处理 3.6 自定义转换, 验证标签 4. 事件处理 4.1 动作事件 4.2 即时事件 4.3 值变事件 4.4 Phase事件

    JSF教程入门

    再则Web应用程序面对网站上不同的使用者同时的存取,其执行线程安全问题以及数据验证、转换处理等问题,又是复杂且难以解决的。 另一方面,本质上是静态的HTML与本质上是动态的应用程序又是一项违背,

    Ajax4jsf

    Ajax4jsf 充分利用了JSF框架的优点,如: 生命周期, 验证, 转换的灵活性和受管理的静态和动态资源. 使用Ajax4jsf, 具有Ajax支持的富组件和高度可自定义的外观感觉可以很容易的与JSF结合起来.

    jsf1.2+spring3.0+hibernate3.3例子-单表增删改查

    使用jsf1.2+spring3.0+hibernate3.3实现集成,利用annotation实现自动对象管理注入,用户表的登录增删改查操作,包括验证码ajax集成,消息机制,国际化处理,自定义转换器,自定义验证器等 qq:38732796 欢迎讨论

    JSF入门环境配置XML配置和标签使用详细介绍以及发布部署

    JSF入门 JSF标签 JSF运行流程和生命周期 数据转换与验证 事件处理

    JSF框架使用示例.rar_JSF

    使用了JSF框架中的事件监听、转换器、验证器,实现了导航。

    jsf的使用和详细说明

    包含JSF的所有处理(配置文件、事件处理、转换_验证、标签说明、国际化等),全部以文本文档的形式

    ajxs4jsf用户指南

    Ajax4jsf 是一个添加Ajax...Ajax4jsf 充分利用了JSF框架的优点,如: 生命周期, 验证, 转换的灵活性和受管理的静态和动态资源. 使用Ajax4jsf, 具有Ajax支持的富组件和高度可自定义的外观感觉可以很容易的与JSF结合起来

    开发JSF应用程序(与Web有关)

    非 JSF Web 应用程序使用 HTML 控件来处理用户输入,但是由于 HTML控件本身没有任何“智能”,,因此开发人员必须编写代码来处理所有的错误、输入验证、字符串转换和格式化、页面流等等。JSF是一个为开发人员提供...

Global site tag (gtag.js) - Google Analytics