随笔-9  评论-168  文章-266  trackbacks-0

概述

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

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

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

  1. (1)实现 Converter 接口(也就是 javax.faxes.convert.Converter)。

          (2)也可以不实现 Converter 接口,  不用注册,  直接在Bean上取得转换器的方法.
                   package onlyfun.caterpillar;
                        import javax.faces.convert.Converter;

                       public class GuestBean {
                                private User user;
                                private Converter converter = new UserConverter();
                                    .........
    
                                public Converter getConverter() { return converter;
                                }
                        }                           

              <h:inputText id="userField" value="#{guest.user}" converter="#{guest.converter}"/>
  1. 实现 public Object getAsObject (FacesContext context, UIComponent component, String str)  方法:  它将接收由HTTP传来的客户端的字符串,  你可以将字符串转换为你自定义的对象类型(例如,PhoneNumber),  并且你自定义的对象类型将自动绑定到你指定的托管Bean中,  此方法运行在验证请求值阶段.

  2. 实现 public String getAsString (FacesContext context, UIComponent component, Object obj) 方法:  它将从你指定的托管Bean中得到对象,  你可以将其转换为字符串,  由HTTP回传给客户端,  此方法运行在渲染响应阶段.

  3. faces-config.xml 中注册自定义转换器。
        <converter>
            <converter-id>onlyfun.caterpillar.User</converter-id>
               <converter-class>
                   onlyfun.caterpillar.UserConverter
               </converter-class>
        </converter>

  4. (1)用 <f:converter converterId="onlyfun.caterpillar.User"/> 标签在 JSP 中插入这个转换器

          (2.1)用 <h:inputText id="userField" value="#{guest.user}" converter="onlyfun.caterpillar.User"/>
 
          (2.2)"onlyfun.caterpillar.User "也可以不实现 Converter 接口,直接是托管Bean的方法来调用转换.

在图 7 中,JSF 在应用请求值阶段调用自定义转换器的 getAsObject 方法。转换器在这里将请求字符串转换为所需的对象类型,然后返回这个对象,将它存储在相应的 JSF 组件中。如果该值被返回呈现在视图中,那么 JSF 将在呈现响应阶段调用 getAsString 方法。这意味着转换器还要负责将对象数据转换回字符串表示形式。


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

*******************************************************************************************

创建自定义转换器

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

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

第 1 步:实现 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. 带有转换处理的示例应用程序
带有转换处理的示例应用程序
posted on 2007-10-23 17:17 紫蝶∏飛揚↗ 阅读(785) 评论(0)  编辑  收藏 所属分类: JSF

只有注册用户登录后才能发表评论。


网站导航: