`
alienj
  • 浏览: 79936 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

第10章 在Seam 中的JSF 表单校验

阅读更多

10 Seam 中的JSF 表单校验

 

在简单JSF中,校验被定义在视窗:

 

<h:form>

    <h:messages/>

    <div>

        Country:

        <h:inputText value="#{location.country}" required="true">

            <my:validateCountry/>

        </h:inputText>

    </div>

   

    <div>

        Zip code:

        <h:inputText value="#{location.zip}" required="true">

            <my:validateZip/>

        </h:inputText>

    </div>

    <h:commandButton/>

</h:form>

 

在实践中,这种方法通常违反DRYDon't Repeat Yourself)原则,因为实际上大部分“校验”执行的约束是数据模型的一部分,并且所有存在的方法下放到数据库方案(schema)定义。Seam提供对使用Hibernate校验器定义的基于模型约束的支持。

 

让我们开始在我们的Location类上定义我们的约束:

 

public class Location {

    private String country;

    private String zip;

   

    @NotNull

    @Length(max=30)

    public String getCountry() { return country; }

    public void setCountry(String c) { country = c; }

    @NotNull

    @Length(max=6)

    @Pattern("^\d*$")

    public String getZip() { return zip; }

    public void setZip(String z) { zip = z; }

}

 

好的,那是一个象样的首次收获,但是在实践中,使用自定义约束代替内建的Hibernate 校验器中的一个,可能是更优雅:

 

public class Location {

    private String country;

    private String zip;

   

    @NotNull

    @Country

    public String getCountry() { return country; }

    public void setCountry(String c) { country = c; }

    @NotNull

    @ZipCode

    public String getZip() { return zip; }

    public void setZip(String z) { zip = z; }

}

 

无论我们使用那一个方法,我不再需要指定被用在JSF页面的校验类型。作为替代,我们能使用<s:validate>,根据定义在模型对象上的约束进行校验。

 

<h:form>

    <h:messages/>

    <div>

        Country:

        <h:inputText value="#{location.country}" required="true">

            <s:validate/>

        </h:inputText>

    </div>

   

    <div>

        Zip code:

        <h:inputText value="#{location.zip}" required="true">

            <s:validate/>

        </h:inputText>

    </div>

   

    <h:commandButton/>

</h:form>

 

注意:在模型上指定@NotNull,并不能在显示控件上消除required="true"这个必要条件!这个由于一个JSF校验体系结构的限制。

 

这种方法在模型上定义约束,并且在视窗引入了约束违反——一个引人注目的更好的设计。

 

可是,它并不比我们开始使用的更少冗余,所以让我们试试<s:validateAll>

<h:form>

   

    <h:messages/>

    <s:validateAll>

        <div>

            Country:

            <h:inputText value="#{location.country}" required="true"/>

        </div>

        <div>

            Zip code:

            <h:inputText value="#{location.zip}" required="true"/>

        </div>

        <h:commandButton/>

    </s:validateAll>

</h:form>

 

这个标签对表单中的每一个输入只增加了一个<s:validate>。对大型表单而言,它能节省大量键入!

 

现在我们需要做一些事情,当校验失败时显示反馈给用户。通常,我们显示所有消息在表单的顶端。我们真正喜欢的是带着错误的消息紧挨着字段显示(在这简单JSF中这是可能的),高光显示字段和标签(这是不可能的),以及,再加上,紧挨着字段显示一些图像(也不可能)。我们也想为每一个必需的表单字段,紧挨标签显示一个彩色小星号。

 

对我们表单的每一个字段,那是相当多我们需要的功能。 我们不想为在表单上的每一个字段指定高光、图像层、消息和输入字段。

 

所以,作为替代,我们用一个facelets模板指定公共层:

 

<ui:composition xmlns="http://www.w3.org/1999/xhtml"

                xmlns:ui="http://java.sun.com/jsf/facelets"

                xmlns:h="http://java.sun.com/jsf/html"

                xmlns:f="http://java.sun.com/jsf/core"

                xmlns:s="http://jboss.com/products/seam/taglib">

                

    <div>

   

        <s:label styleClass="#{invalid?'error':''}">

            <ui:insert name="label"/>

            <s:span styleClass="required" rendered="#{required}">*</s:span>

        </s:label>

       

        <span class="#{invalid?'error':''}">

            <h:graphicImage value="/img/error.gif" rendered="#{invalid}"/>

            <s:validateAll>

                <ui:insert/>

            </s:validateAll>

        </span>

       

        <s:message styleClass="error"/>

        

    </div>

   

</ui:composition>

 

我们能使用<s:decorate>,为我们表单字段的每个包括这个模板。

 

<h:form>

    <h:messages globalOnly="true"/>

    <s:decorate template="edit.xhtml">

        <ui:define name="label">Country:</ui:define>

        <h:inputText value="#{location.country}" required="true"/>

    </s:decorate>

   

    <s:decorate template="edit.xhtml">

    <ui:define name="label">Zip code:</ui:define>

        <h:inputText value="#{location.zip}" required="true"/>

    </s:decorate>

    <h:commandButton/>

</h:form>

 

最后,当用户在表单的四处导航时,我们能使用RichFaces Ajax显示校验消息。

 

<h:form>

    <h:messages globalOnly="true"/>

    <s:decorate id="countryDecoration" template="edit.xhtml">

        <ui:define name="label">Country:</ui:define>

        <h:inputText value="#{location.country}" required="true">

            <a:support event="onblur" reRender="countryDecoration" bypassUpdates="true"/>

        </h:inputText>

    </s:decorate>

   

    <s:decorate id="zipDecoration" template="edit.xhtml">

        <ui:define name="label">Zip code:</ui:define>

        <h:inputText value="#{location.zip}" required="true">

            <a:support event="onblur" reRender="zipDecoration" bypassUpdates="true"/>

        </h:inputText>

    </s:decorate>

    <h:commandButton/>

</h:form>

 

为页面上重要的控件定义明确的id是好的风格,特别是如果你想使用一些Selenium类工具包来对UI做自动测试。如果你没有提供明确的idJSF会产生它们,但是,如果你改变了在页面上的任何事,产生的值也会改变。

 

<h:form id="form">

    <h:messages globalOnly="true"/>

    <s:decorate id="countryDecoration" template="edit.xhtml">

       <ui:define name="label">Country:</ui:define>

        <h:inputText id="country" value="#{location.country}" required="true">

            <a:support event="onblur" reRender="countryDecoration" bypassUpdates="true"/>

        </h:inputText>

    </s:decorate>

   

    <s:decorate id="zipDecoration" template="edit.xhtml">

        <ui:define name="label">Zip code:</ui:define>

        <h:inputText id="zip" value="#{location.zip}" required="true">

            <a:support event="onblur" reRender="zipDecoration" bypassUpdates="true"/>

        </h:inputText>

    </s:decorate>

    <h:commandButton/>

</h:form>

 

 

如果当校验失败时,你想指定一个不同的消息显示?你能和Hibernate校验器一起使用Seam消息束(所有象在消息内的EL表达式,每视窗消息束)???:

 

public class Location {

    private String name;

    private String zip;

   

    // Getters and setters for name

    @NotNull

    @Length(max=6)

    @ZipCode(message="#{messages['location.zipCode.invalid']}")

    public String getZip() { return zip; }

    public void setZip(String z) { zip = z; }

}

 

 

location.zipCode.invalid = The zip code is not valid for #{location.name}

分享到:
评论

相关推荐

    seam+jsf+richfaces+ajax4jsf 电子书

    Seam、JSF、RichFaces 和 Ajax4jsf 是四个重要的Java Web开发框架和技术,它们在构建现代、交互式Web应用程序中发挥着关键作用。让我们深入探讨这些技术及其结合使用时的知识点。 **1. Seam** Seam是一个开源的Java...

    seam,jsf,ajax4jsf的大全资料集合

    Seam、JSF(JavaServer Faces)和Ajax4jsf是Java Web开发中重要的技术框架,它们在构建富互联网应用程序(Rich Internet Applications, RIA)时发挥着关键作用。这里,我们将深入探讨这三个技术的核心概念、特点以及...

    seam+jsf+richfaces+ajax4jsf打包了

    通过学习Ajax4jsf的常用标签讲解,开发者可以掌握如何在JSF应用中集成和使用这些功能,提高应用的性能和用户体验。 综合这个压缩包中的内容,开发者可以从理论到实践全面掌握这四大技术的使用,无论是新手还是经验...

    JSF项目中seam的配置

    通过对`Conversation`的巧妙利用,可以避免在JSF中常见的数据丢失问题,特别是在处理复杂表单和导航时。同时,Seam与其他Java EE技术的集成也使得整个应用的架构更加灵活和强大。然而,由于Seam不断更新,开发者需要...

    jsf+seam+jpa实例

    在现代Web应用开发中,JavaServer Faces (JSF)、Seam框架和Java Persistence API (JPA)是三个关键的技术组件。本实例将深入探讨如何利用这三者进行联合开发,帮助开发者实现高效、可维护的业务逻辑和用户界面。 **...

    seam 框架整合hibernate+jsf

    在Seam中,JSF和Hibernate的整合主要体现在以下几个方面: 1. **数据绑定**:Seam支持JSF的数据绑定,使得JSF组件可以直接绑定到 Seam managed beans上的属性,这简化了视图和模型之间的通信。 2. **事件处理**:...

    Seam-无缝集成JSF

    此外,Seam的灵活性允许它在多种环境中运行,无论是与EJB3配合还是在纯POJO模式下使用。总之,对于正在寻找一种强大的、可扩展的Java Web应用程序框架的开发者来说,Seam无疑是一个值得深入探索的选择。

    Beginning JSF2 APIs and JBoss Seam

    - **EL表达式**:熟悉JSF中的表达式语言,能够更高效地进行数据绑定和条件渲染。 - **AJAX支持**:掌握如何利用JSF的内置AJAX支持来创建动态和交互式的用户界面。 #### 三、JBoss Seam **1. 概述** - **定义**:...

    jsf seam hibernate 初学者练习

    JSF和Seam的集成使得开发人员可以在JSF组件的基础上,利用Seam的强大功能,如依赖注入、事件处理和会话管理。Seam的Contexts and Dependency Injection (CDI)容器使得JSF组件可以轻松获取服务或数据,而不需要手动...

    seam jsf ejb 资源相关连部分

    - **直接访问Bean:**在JSF中,可以通过名字直接访问Bean,减少了额外的操作。 - **POJO管理Bean:**JSF的管理Bean本身就是POJO,易于理解和使用。 - **IDE支持:**随着JSF的发展,IDE对它的支持也逐渐增强。 - **...

    [JBoss] JSF & Facelets & JBoss Seam 核心技术 (英文版)

    [TipTec Development] JSF & Facelets & JBoss Seam 核心技术 (英文版) [TipTec Development] Essential JSF, Facelets & JBoss Seam (E-Book) ☆ 出版信息:☆ [作者信息] Kent Ka Iok Tong [出版机构] TipTec ...

    Seam项目源代码(基于JBoss和EJB3,JSF的项目源码)

    Seam是由Red Hat开发的一个集成框架,它将JSF、EJB3、CDI(Contexts and Dependency Injection)等Java EE技术融合在一起,旨在解决传统Java EE开发中的复杂性问题。Seam的核心特性包括: 1. **组件化**:Seam支持...

    Seam - 无缝集成 JSF

    在这个由三部分组成的新系列中的第一篇文章中,发现这两种框架之间的互补性。Dan Allen 介绍了 Seam 对 JSF 生命周期的增强,包括上下文状态管理、 RESTful URL、Ajax remoting、适当的异常处理和约定优于配置。

    seam 的eclipse工程例子3

    在这个"seam 的eclipse工程例子3"中,我们将探讨Seam与JSF的结合使用以及如何在Eclipse环境中创建和运行一个简单的示例。 首先,让我们深入了解Seam和JSF这两个关键概念。JavaServer Faces (JSF) 是一种用于构建Web...

    JSF+Seam帮助文档.rar

    通过阅读JSF入门.pdf,你可以掌握JSF的基本用法和原理,然后通过Seam_2.0_Reference_zh_CN.pdf深入探究Seam如何增强JSF的功能,以及如何在实际项目中运用这些技术。这将有助于你提升在J2EE环境下的开发能力,特别是...

    SEAM 中文开发指南

    ### SEAM 中文开发指南知识点概述 #### 一、SEAM 框架简介 - **SEAM**:SEAM 是一个基于 Java EE 的企业级应用框架,它简化了复杂的应用程序开发过程,并且提供了丰富的功能来支持业务逻辑的实现。 - **版本信息**...

    jboss seam 中文文档集合

    《JSF标签》简体中文版.pdf涵盖了JSF的各种组件、转换器、验证器以及与后台数据交互的方法,有助于提升开发者在JSF项目中的效率。 **4. A4J (Ajax for JSF)** A4J 是一个扩展JSF的库,提供了一套AJAX支持,允许...

    JBOSS SEAM组件中文手册

    1. **Faces Context增强**: 在Seam 2.0中,对JSF的Faces Context进行了扩展,提供了更多的上下文信息和操作。 2. **CDI支持**: 虽然Seam 2.0发布时,Contexts and Dependency Injection (CDI)规范还未正式发布,但...

Global site tag (gtag.js) - Google Analytics