Java JSF:从自定义组件访问组件体的文本

Java JSF:从自定义组件访问组件体的文本,java,jsf-2,facelets,custom-component,Java,Jsf 2,Facelets,Custom Component,假设我有一个Java类格式化程序,它有一个静态方法格式,可以执行一些简单的文本处理。我想编写一个组件,将组件中的文本传递给Formatterformat方法,如下所示: <test:format> Hello, #{user.name}! </test:format> 我希望上面标记的渲染结果是HELLO,DANIEL 这是否可行?我需要做什么才能获得组件下的渲染文本内容,以便进行这样的处理?我已经找到了一种方法,但我怀疑这是一个难题。代码: @FacesCompo

假设我有一个Java类格式化程序,它有一个静态方法格式,可以执行一些简单的文本处理。我想编写一个组件,将组件中的文本传递给Formatterformat方法,如下所示:

<test:format>
  Hello, #{user.name}!
</test:format>
我希望上面标记的渲染结果是HELLO,DANIEL


这是否可行?我需要做什么才能获得组件下的渲染文本内容,以便进行这样的处理?

我已经找到了一种方法,但我怀疑这是一个难题。代码:

@FacesComponent("MyComponent")
public class MyComponent 
    extends UIComponentBase 
    implements NamingContainer {

  @Override public String getFamily() { 
    return UINamingContainer.COMPONENT_FAMILY; 
  }

  @Override public boolean getRendersChildren() { return true; }

  @Override public void encodeChildren(FacesContext fc) throws IOException {
    StringWriter writer = new StringWriter();
    ResponseWriter rw = fc.getResponseWriter();

    // create the response writer
    ResponseWriter replacement = rw.cloneWithWriter(writer);

    // this tag wrapping step is necessary for the MyFaces ResponseWriter to 
    // work correctly
    replacement.startDocument();
    replacement.startElement("div", this);

    // mask the response writer temporarily    
    fc.setResponseWriter(replacement);

    // perform the render to get the text in our string
    super.encodeChildren(fc);

    // unmask the response writer
    fc.setResponseWriter(rw);

    // finish the wrapping calls
    replacement.endElement("div");
    replacement.endDocument();

    // this strips the rendered <div> tag wrapper from the generated text.
    final String renderedText = writer.toString()
            .substring(5, writer.toString().length()-6);

    // process the text and send it out
    rw.append(Formatter.format(renderedText));
  }
}
这一切都取决于ResponseWritercloneWithWriter方法。但是,如果您只是将StringWriter插入其中并期望它消失,MyFaces将爆炸,您至少需要创建一个包装标签,为要呈现的文本创建一个安全上下文。我的格式化程序不需要包装元素,所以我在之后用一个粗大的子字符串删除它。除此之外,实现getRendersChildren似乎足以实现这一点。然后用taglib.xml将其连接起来

@FacesComponent("MyComponent")
public class MyComponent 
    extends UIComponentBase 
    implements NamingContainer {

  @Override public String getFamily() { 
    return UINamingContainer.COMPONENT_FAMILY; 
  }

  @Override public boolean getRendersChildren() { return true; }

  @Override public void encodeChildren(FacesContext fc) throws IOException {
    StringWriter writer = new StringWriter();
    ResponseWriter rw = fc.getResponseWriter();

    // create the response writer
    ResponseWriter replacement = rw.cloneWithWriter(writer);

    // this tag wrapping step is necessary for the MyFaces ResponseWriter to 
    // work correctly
    replacement.startDocument();
    replacement.startElement("div", this);

    // mask the response writer temporarily    
    fc.setResponseWriter(replacement);

    // perform the render to get the text in our string
    super.encodeChildren(fc);

    // unmask the response writer
    fc.setResponseWriter(rw);

    // finish the wrapping calls
    replacement.endElement("div");
    replacement.endDocument();

    // this strips the rendered <div> tag wrapper from the generated text.
    final String renderedText = writer.toString()
            .substring(5, writer.toString().length()-6);

    // process the text and send it out
    rw.append(Formatter.format(renderedText));
  }
}