Java JSF:从自定义组件访问组件体的文本
假设我有一个Java类格式化程序,它有一个静态方法格式,可以执行一些简单的文本处理。我想编写一个组件,将组件中的文本传递给Formatterformat方法,如下所示: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
<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));
}
}