【问题标题】:JSF: accessing text of component body from custom componentJSF:从自定义组件访问组件正文的文本
【发布时间】:2014-01-15 22:53:06
【问题描述】:

假设我有一个 Java 类 Formatter 和一个静态方法 format,它执行一些简单的文本处理。我想编写一个组件,将组件内的文本传递给Formatter#format 方法,如下所示:

<test:format>
  Hello, #{user.name}!
</test:format>

为了论证,假设 Formatter 看起来像这样(实际上它是一个 Markdown 库):

public class Formatter {
  public static format(String s) { return s.toUpperCase(); }
}

我希望上述标签的渲染结果为HELLO, DANIEL!

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

【问题讨论】:

    标签: java jsf-2 facelets custom-component


    【解决方案1】:

    我已经找到了一种方法来做到这一点,但我怀疑这是一个杂牌。代码:

    @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));
      }
    }
    

    这一切都取决于ResponseWriter#cloneWithWriter 方法。但是,如果您只是在其中添加一个 StringWriter 并期望它运行,MyFaces 将会崩溃——您至少需要创建一个包装标签来为要呈现的文本创建一个安全的上下文。我的格式化程序不期望包装元素,所以我之后用一个粗略的子字符串删除它。除此之外,实施getRendersChildren 似乎足以让这一切顺利进行。然后,您将其与 taglib.xml 挂钩。

    【讨论】:

      猜你喜欢
      • 2015-01-19
      • 1970-01-01
      • 2010-10-14
      • 2011-12-17
      • 2010-10-13
      • 2014-12-09
      • 1970-01-01
      • 2013-09-15
      • 2012-03-15
      相关资源
      最近更新 更多