我正在使用 JSF 和我自己的自定义标签/我自己的 taglib,但目前我遇到了一个问题,通过 java 以编程方式添加“复合组件”实例。
我在这里上传了问题:http: //download.dynamicfiles.de/stackoverflow/insertCCprogramatically.zip
package de.dynamicfiles.projects.insertCCprogramatically;
import java.util.Map;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.application.Resource;
import javax.faces.component.UIComponent;
import javax.faces.component.UIPanel;
import javax.faces.context.FacesContext;
import javax.faces.view.facelets.FaceletContext;
/**
*
* @author FibreFoX
*/
public class JSFUtils {
private static final String JAVAX_FACES_GROUP = "javax.faces.Group";
/**
* Source:
* http://stackoverflow.com/questions/15828540/programmatically-create-and-add-composite-component-in-backing-bean
*
* @param parent
* @param libraryName
* @param resourceName
* @param id
*/
public static void includeCompositeComponent(UIComponent parent, String libraryName, String resourceName, String id, Map<String, String> valueExpressions) {
System.out.println("includeCompositeComponent > ");
System.out.println("libraryName > " + libraryName);
System.out.println("resourceName > " + resourceName);
System.out.println("parent-id > " + parent.getId());
System.out.println("id > " + id);
// Prepare.
FacesContext context = FacesContext.getCurrentInstance();
Application application = context.getApplication();
FaceletContext faceletContext = (FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
// This basically creates <ui:component> based on <composite:interface>.
Resource resource;
if (application.getResourceHandler().libraryExists(libraryName)) {
System.out.println("if the lib exists, load ressource from there");
resource = application.getResourceHandler().createResource(resourceName, libraryName);
} else {
System.out.println("if not, try to load without libname");
resource = application.getResourceHandler().createResource(resourceName);
}
UIComponent composite = application.createComponent(context, resource);
composite.setId(id); // Mandatory for the case composite is part of UIForm! Otherwise JSF can't find inputs.
// http://stackoverflow.com/a/16058002/1961102
if (valueExpressions != null && !valueExpressions.isEmpty()) {
ExpressionFactory factory = application.getExpressionFactory();
ELContext ctx = context.getELContext();
for (Map.Entry<String, String> entry : valueExpressions.entrySet()) {
ValueExpression expr = factory.createValueExpression(ctx, entry.getValue(), Object.class);
composite.setValueExpression(entry.getKey(), expr);
}
}
// This basically creates <composite:implementation>.
UIComponent implementation = application.createComponent(context, UIPanel.COMPONENT_TYPE, JAVAX_FACES_GROUP);
composite.getFacets().put(UIPanel.COMPOSITE_FACET_NAME, implementation);
// Now include the composite component file in the given parent.
parent.getChildren().add(composite);
parent.pushComponentToEL(context, composite); // This makes #{cc} available.
try {
faceletContext.includeFacelet(implementation, resource.getURL());
} catch (Exception e) {
e.printStackTrace(System.out);
//throw new FacesException(e);
} finally {
parent.popComponentFromEL(context);
}
}
}
当调用“includeCompositeComponent”时,我从 myfaces 得到一个令人沮丧的异常:
java.lang.NullPointerException
at org.apache.myfaces.view.facelets.impl.FaceletCompositionContextImpl.generateUniqueId(FaceletCompositionContextImpl.java:998)
at org.apache.myfaces.view.facelets.impl.DefaultFaceletContext.generateUniqueId(DefaultFaceletContext.java:321)
at org.apache.myfaces.view.facelets.compiler.UIInstructionHandler.apply(UIInstructionHandler.java:87)
at org.apache.myfaces.view.facelets.tag.composite.ImplementationHandler.apply(ImplementationHandler.java:67)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:49)
at org.apache.myfaces.view.facelets.tag.composite.CompositeComponentDefinitionTagHandler.apply(CompositeComponentDefinitionTagHandler.java:255)
at org.apache.myfaces.view.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:57)
at org.apache.myfaces.view.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:48)
at org.apache.myfaces.view.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:412)
at org.apache.myfaces.view.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:466)
at org.apache.myfaces.view.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:393)
at de.dynamicfiles.projects.insertCCprogramatically.JSFUtils.includeCompositeComponent(JSFUtils.java:76)
at de.dynamicfiles.projects.insertCCprogramatically.tag.insertCC.encodeChildren(insertCC.java:30)
我错过了什么?!