假设我有一个带有静态方法Formatter
的Java类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!
。
这可行吗?我需要做些什么来获取组件下的渲染文本内容才能像这样处理?
答案 0 :(得分:0)
我已经找到了一种方法来做到这一点,但我怀疑这是一个很好的方法。代码:
@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将其连接起来。