这只能通过自定义PartialViewContext 实现,您可以使用PartialViewContextFactory 将其加载到您的JSF 应用程序中。自定义PartialViewContext 应该反过来在PartialViewContext#getResponseWriter() 上返回自定义PartialResponseWriter。在这个自定义的PartialResponseWriter 中,您应该能够通过在endDocument() 中调用startExtension() 和endExtension() 来为XML 响应添加扩展。比如:
@Override
public void endDocument() throws IOException {
Map<String, String> attributes = new HashMap<String, String>();
attributes.put("name1", "value1");
attributes.put("name2", "value2");
startExtension(attributes);
write("lorem ipsum");
endExtension();
super.endDocument();
}
这将在 XML 响应中结束
<extension name1="value1" name2="value2">lorem ipsum</extension>
这可以通过data.responseXML 在jsf.ajax.addOnEvent() 函数中使用和遍历。
这是一个完整的启动示例,您可以如何在特定情况下使用它:
MyPartialViewContextFactory 提供自定义局部视图上下文:
public class MyPartialViewContextFactory extends PartialViewContextFactory {
private PartialViewContextFactory wrapped;
public MyPartialViewContextFactory(PartialViewContextFactory wrapped) {
this.wrapped = wrapped;
}
@Override
public PartialViewContext getPartialViewContext(FacesContext context) {
return new MyPartialViewContext(wrapped.getPartialViewContext(context));
}
}
MyPartialViewContext 提供自定义部分响应编写器:
public class MyPartialViewContext extends PartialViewContextWrapper {
private PartialViewContext wrapped;
private PartialResponseWriter writer;
public MyPartialViewContext(PartialViewContext wrapped) {
this.wrapped = wrapped;
this.writer = new MyPartialResponseWriter(wrapped.getPartialResponseWriter());
}
@Override
public PartialResponseWriter getPartialResponseWriter() {
return writer;
}
@Override
public void setPartialRequest(boolean isPartialRequest) {
wrapped.setPartialRequest(isPartialRequest);
}
@Override
public PartialViewContext getWrapped() {
return wrapped;
}
}
MyPartialResponseWriter 写入<extension id="myextension">,正文为 JSON):
public class MyPartialResponseWriter extends PartialResponseWriter {
public MyPartialResponseWriter(ResponseWriter wrapped) {
super(wrapped);
}
@Override
public void endDocument() throws IOException {
startExtension(Collections.singletonMap("id", "myextension"));
write("{\"validationFailed\": " + FacesContext.getCurrentInstance().isValidationFailed() + "}"); // Consider a JSON serializer, like Google Gson.
endExtension();
super.endDocument();
}
}
为了让它运行,在faces-config.xml注册工厂如下:
<factory>
<partial-view-context-factory>com.example.MyPartialViewContextFactory</partial-view-context-factory>
</factory>
以下是您在jsf.ajax.addOnEvent() 中访问、解析和使用<extension id="myextension"> 的方法:
jsf.ajax.addOnEvent(function(data) {
if (data.status == "success") {
var args = JSON.parse(data.responseXML.getElementById("myextension").firstChild.nodeValue);
if (args.validationFailed) {
// ...
}
else {
// ...
}
}
});
但是,您的特定功能需求可以通过不同的、可能更简单的方式来实现。只需让 ajax 请求更新按钮本身,并让按钮的disabled 属性评估true,当有成功回发的方法时。
<h:commandButton id="myButton" value="do" action="#{testBacking.do}"
disabled="#{facesContext.postback and not facesContext.validationFailed}">
<f:ajax execute="id1" render="@this id2" listener="#{testBacking.listener}"/>
</h:commandButton>