Lotus教程、Java教程、Java虚拟机、Java软件综合开发社区

Lotus、Domino、Java、C#、Web、数据库综合开发教程、资料社区

JSF编码&JSF解码实例



Published by admin on 04月 30, 2009

JSF编码&JSF解码实例Component可以自己负责将物件资料编码为HTML文件或其它的输出文件,也可以将这个任务委託给 Renderer,这边先介绍的是让Component自己负责编码的动作。

  这边着重的是介绍完成自订元件所必须的流程,所以我们不设计太複杂的元件,这边将完成以下的元件,这个元件会有一个输入文字栏位以及一个送出按钮:



您要继承UIComponent或其子类别来自订Component,由于文字栏位是一个输入栏位,为了方便,您可以继承UIInput类别,这可以让您省去一些处理细节的功夫,在继承UIComponent或其子类别后,与编码相关的主要有三个方法:

encodeBegin()
encodeChildren()
encodeEnd()
  其中encodeChildren()是在包括子元件时必须定义,Component如果它的 getRendersChildren()方法传回true时会呼叫encodeChildren()方法,预设上, getRendersChildren()方法传回false。

  由于我们的自订元件相当简单,所以将编码的动作写在encodeBegin()或是encodeEnd()都可以,我们这边是定义encodeBegin ()方法:

UITextWithCmd.java


package onlyfun.caterpillar;

 import java.io.IOException;
 import java.util.Map;
 import javax.faces.component.UIInput;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;

 public class UITextWithCmd extends UIInput {
    private static final String TEXT = “.text”;
    private static final String CMD = “.cmd”;
   
    public UITextWithCmd() {
        setRendererType(null);  
    }
   
    public void encodeBegin(FacesContext context)
                                      throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        String clientId = getClientId(context);
       
        encodeTextField(writer, clientId);
        encodeCommand(writer, clientId);
    }
   
    public void decode(FacesContext context) {
        // …..
    }
   
    private void encodeTextField(ResponseWriter writer,
                        String clientId) throws IOException {
        writer.startElement(”input”, this);
        writer.writeAttribute(”name”, clientId + TEXT, null);
       
        Object value = getValue();
        if(value != null) {
            writer.writeAttribute(”value”,
                                  value.toString(), null);
        }
       
        String size = (String) getAttributes().get(”size”);
        if(size != null) {
            writer.writeAttribute(”size”, size, null);  
        }
       
        writer.endElement(”input”);
    }
   
    private void encodeCommand(ResponseWriter writer,
                        String clientId) throws IOException {
        writer.startElement(”input”, this);
        writer.writeAttribute(”type”, “submit”, null);
        writer.writeAttribute(”name”, clientId + CMD, null);
        writer.writeAttribute(”value”, “submit”, null);
        writer.endElement(”input”);
    }
 } 

 在encodeBegin()方法中,我们取得ResponseWriter物件,这个物件可以协助您输出HTML标籤、属性等,我们使用 getClientId()取得元件的id,这个id是每个元件的唯一识别,预设上如果您没有指定,则JSF会自动为您产生id值。

接着我们分别对输入文字栏位及送出钮作HTML标籤输出,在输出时,我们将name属性设成clientId与一个字串值的结合(即TEXT或CMD),这是为了方便在解码时,取得对应name属性的请求值。

  在encodeTextField中我们有呼叫getValue()方法,这个方法是从UIOutput继承下来的,getValue() 方法可以取得Component的设定值,这个值可能是静态的属性设定值,也可能是JSF Expression的绑定值,预设会先从元件的属性设定值开始找寻,如果找不到,再从绑定值(ValueBinding物件)中找寻,元件的属性值或绑定值的设定,是在定义Tag时要作的事。

  编碥的部份总结来说,是取得Component的值并作适当的HTML标籤输出,再来我们看看解码的部份,这是定义在decode()方法中,将下面的内容加入至上面的类别定义中:

….
    public void decode(FacesContext context) {
        Map reqParaMap = context.getExternalContext().
                                getRequestParameterMap();
        String clientId = getClientId(context);
       
        String submittedValue =
                   (String) reqParaMap.get(clientId + TEXT);
        setSubmittedValue(submittedValue);
        setValid(true);
    }
 ….

  我们必须先取得RequestParameterMap,这个Map物件中填入了所有客户端传来的请求参数, Component在这个方法中有机会查询这些请求参数中,是否有自己所想要取得的资料,记得我们之前解码时,是将输入栏位的name属性解码为 client id加上一个字串值(即TEXT设定的值),所以这时,我们尝试从RequestParameterMap中取得这个请求值。

  取得请求值之后,您可以将资料藉由setSumittedValue()设定给绑定的bean,最后呼叫setValid()方法,这个方法设定为 true时,表示元件正确的获得自己的值,没有任何的错误发生。

  由于我们先不使用Renderer,所以在建构函式中,我们设定RendererType为null,表示我们不使用Renderer进行解码输出:

public UITextWithCmd() {
        setRendererType(null);  
    } 

 在我们的例子中,我们都是处理字串物件,所以这边不需要转换器,如果您需要使用转换器,可以呼叫setConverter()方法加以设定,在不使用 Renderer的时候,Component要设定转换器来自行进行字串与物件的转换。


下一篇文章:JSF自定义组件的使用 »

【版权说明】:本网页上有部分内容来源于网上收集,但不能保证资料的完整性和准确性,仅提供参考和学习。如有侵权请立即通知我们,我们将立即删除,谢谢合作!

Comments are closed.