我试图在POJO中使用primefaces autoComplete组件
我知道我需要一个转换器。我很久以前就成功地使用过它。但这次我有一个特殊的要求
我需要POJO只向用户显示许多列,但是当它被选中时我只想得到他的一个属性(字符串),而不是POJO本身。
当我成功使用autoComplete时,它只有完整的POJO,我的意思是:使用POJO列表并在选择时也获得一个POJO(而不仅仅是他的一个属性)。
<p:autoComplete
value="#{testBean.selectedA.val2}"
completeMethod="#{testBean.testAutoComplete}"
var="varB"
itemLabel="#{varB.val10}"
itemValue="#{varB.val10}"
forceSelection="true" dropdown="true">
<p:column>
<h:outputText value="#{varB.val10}" />
</p:column>
<p:column>
<h:outputText value="#{varB.val11}" />
</p:column>
</p:autoComplete>
这里testBean.selectedA.val2的类型为String。实际上selectedA是一个DTO,所以在所有属性中都是基本类型或String类型,但没有其他POJO。
varB是POJO
varB.val10的类型为String
varB.val11的类型为String。
如果我的支持bean testBean.selectedA.val2为空/ null,则没有问题。 现在,如果我需要在支持bean中初始化此值(testBean.selectedA.val2)以向用户显示值,我会收到一个错误。 所以我不知道如何在链接到autoComplete的String属性中放置一个默认值
INFO [stdout] (default task-15) /test.xhtml @26,42 itemLabel="#{varB.val10}": The class 'java.lang.String' does not have the property 'val10'.
我认为我的问题是因为我将自动完成功能与POJO列表一起使用,但只希望将String属性作为结果。
问题看起来像这样:Is this a bug in primefaces autocomplete?
你有什么想法吗? 在这种情况下可以使用autoComplete吗? 提前感谢您的帮助。
以下是一些其他信息。
我的配置:
Primefaces 5.1.6
Wildfly 8.1
完整堆栈跟踪:
11:00:32,915 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (default task-15) Error Rendering View[/test.xhtml]: javax.el.PropertyNotFoundException: /test.xhtml @26,42 itemLabel="#{varB.val10}": The class 'java.lang.String' does not have the property 'val10'.
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111) [jsf-impl-2.2.6-jbossorg-4.jar:]
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194) [jboss-jsf-api_2.2_spec-2.2.6.jar:2.2.6]
at org.primefaces.component.autocomplete.AutoComplete.getItemLabel(AutoComplete.java:152) [primefaces-5.1.6.jar:5.1.6]
at org.primefaces.component.autocomplete.AutoCompleteRenderer.encodeInput(AutoCompleteRenderer.java:189) [primefaces-5.1.6.jar:5.1.6]
at org.primefaces.component.autocomplete.AutoCompleteRenderer.encodeSingleMarkup(AutoCompleteRenderer.java:146) [primefaces-5.1.6.jar:5.1.6]
at org.primefaces.component.autocomplete.AutoCompleteRenderer.encodeMarkup(AutoCompleteRenderer.java:129) [primefaces-5.1.6.jar:5.1.6]
at org.primefaces.component.autocomplete.AutoCompleteRenderer.encodeEnd(AutoCompleteRenderer.java:107) [primefaces-5.1.6.jar:5.1.6]
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919) [jboss-jsf-api_2.2_spec-2.2.6.jar:2.2.6]
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:312) [jsf-impl-2.2.6-jbossorg-4.jar:]
at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185) [jsf-impl-2.2.6-jbossorg-4.jar:]
at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129) [jsf-impl-2.2.6-jbossorg-4.jar:]
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:889) [jboss-jsf-api_2.2_spec-2.2.6.jar:2.2.6]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1857) [jboss-jsf-api_2.2_spec-2.2.6.jar:2.2.6]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1860) [jboss-jsf-api_2.2_spec-2.2.6.jar:2.2.6]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1860) [jboss-jsf-api_2.2_spec-2.2.6.jar:2.2.6]
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:461) [jsf-impl-2.2.6-jbossorg-4.jar:]
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133) [jsf-impl-2.2.6-jbossorg-4.jar:]
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [jboss-jsf-api_2.2_spec-2.2.6.jar:2.2.6]
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [jboss-jsf-api_2.2_spec-2.2.6.jar:2.2.6]
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [jboss-jsf-api_2.2_spec-2.2.6.jar:2.2.6]
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120) [jsf-impl-2.2.6-jbossorg-4.jar:]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.2.6-jbossorg-4.jar:]
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219) [jsf-impl-2.2.6-jbossorg-4.jar:]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647) [jboss-jsf-api_2.2_spec-2.2.6.jar:2.2.6]
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at fr.legrain.solstyce.webapp.AuthFilter.doFilter(AuthFilter.java:65) [classes:]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:177) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:727) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_25]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_25]
at java.lang.Thread.run(Thread.java:724) [rt.jar:1.7.0_25]
Caused by: javax.el.PropertyNotFoundException: The class 'java.lang.String' does not have the property 'val10'.
at javax.el.BeanELResolver.getBeanProperty(BeanELResolver.java:731) [jboss-el-api_3.0_spec-1.0.3.Final.jar:1.0.3.Final]
at javax.el.BeanELResolver.getValue(BeanELResolver.java:351) [jboss-el-api_3.0_spec-1.0.3.Final.jar:1.0.3.Final]
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176) [jsf-impl-2.2.6-jbossorg-4.jar:]
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203) [jsf-impl-2.2.6-jbossorg-4.jar:]
at com.sun.el.parser.AstValue.getValue(AstValue.java:140) [javax.el-3.0.0.jar:]
at com.sun.el.parser.AstValue.getValue(AstValue.java:204) [javax.el-3.0.0.jar:]
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226) [javax.el-3.0.0.jar:]
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50) [weld-core-impl-2.2.5.Final.jar:2014-09-15 07:54]
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50) [weld-core-impl-2.2.5.Final.jar:2014-09-15 07:54]
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109) [jsf-impl-2.2.6-jbossorg-4.jar:]
... 56 more
我试图在这里举一个简单的例子来说明我的问题 视图test.xhtml:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:panelGrid columns="2" cellpadding="10">
<p:outputLabel value="A.val1 : " />
<p:inputText value="#{testBean.selectedA.val1}"/>
<p:outputLabel value="A.val2 : " />
<p:autoComplete
value="#{testBean.selectedA.val2}"
completeMethod="#{testBean.testAutoComplete}"
var="varB"
itemLabel="#{varB.val10}"
itemValue="#{varB.val10}"
forceSelection="true" dropdown="true">
<p:column>
<h:outputText value="#{varB.val10}" />
</p:column>
<p:column>
<h:outputText value="#{varB.val11}" />
</p:column>
</p:autoComplete>
</h:panelGrid>
</h:body>
</html>
托管bean TestBean.java:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
public class TestBean implements Serializable {
private static final long serialVersionUID = 7752061447417566324L;
private A selectedA;
private BService bService;
@PostConstruct
public void init() {
bService = new BService();
selectedA = new A();
selectedA.setVal1("xxx");
selectedA.setVal2("bb2"); //comment this line and there is no more problem
}
public List<B> testAutoComplete(String query) {
List<B> allValues = bService.getAllValues();
List<B> filteredValues = new ArrayList<B>();
if(query==null || query.equals("")) {
return allValues;
} else {
for (int i = 0; i < allValues.size(); i++) {
B b = allValues.get(i);
if(b.getVal10().toLowerCase().contains(query.toLowerCase())) {
filteredValues.add(b);
}
}
return filteredValues;
}
}
public A getSelectedA() {
return selectedA;
}
public void setSelectedA(A selectedA) {
this.selectedA = selectedA;
}
}
服务BService.java:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class BService implements Serializable {
private static final long serialVersionUID = -7442506301755842723L;
private static final List<B> allValues = new ArrayList<B>();
public BService() {
init();
}
public void init() {
if(allValues.isEmpty()) {
allValues.add(new B("aa1", "ab"));
allValues.add(new B("bb2", "abc"));
allValues.add(new B("ab3", "abcd"));
}
}
public List<B> getAllValues() {
return allValues;
}
}
转换器BConverter.java:
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
@FacesConverter(forClass=B.class)
public class BConverter implements Converter {
private BService bService = new BService();
@Override
public String getAsString(FacesContext context, UIComponent component, Object valueToRender) {
if (valueToRender == null || valueToRender.equals("")) {
return "";
} else {
return String.valueOf(((B) valueToRender).getVal10());
}
}
@Override
public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
if (submittedValue.trim().equals("")) {
return null;
} else {
try {
//int number = Integer.parseInt(submittedValue);
return bService.getAllValues().get(bService.getAllValues().indexOf(submittedValue));
} catch (Exception e) {
e.printStackTrace();
}
}
return submittedValue;
}
}
A.java类:
public class A {
private String val1;
private String val2;
public A() {
}
public A(String val1, String val2) {
super();
this.val1 = val1;
this.val2 = val2;
}
public String getVal1() {
return val1;
}
public void setVal1(String val1) {
this.val1 = val1;
}
public String getVal2() {
return val2;
}
public void setVal2(String val2) {
this.val2 = val2;
}
}
班级B.java:
public class B {
private String val10;
private String val11;
public B() {
}
public B(String val10, String val11) {
super();
this.val10 = val10;
this.val11 = val11;
}
public String getVal10() {
return val10;
}
public void setVal10(String val10) {
this.val10 = val10;
}
public String getVal11() {
return val11;
}
public void setVal11(String val11) {
this.val11 = val11;
}
}
答案 0 :(得分:0)
你的问题在这里:
The class 'java.lang.String' does not have the property 'val10'.
这意味着您具有String
类型的值,并且您尝试从此val10
获取不存在的属性String
。
您的代码有错误itemValue="#{varB.val10}"
应由itemValue="#{varB}"
替换,itemLabel="#{varB.val10}"
可以删除,因为您使用:
`<p:column>
<h:outputText value="#{varB.val10}" />
</p:column>
<p:column>
<h:outputText value="#{varB.val11}" />
</p:column>`
显示值。考虑以这种方式重写代码:
<p:autoComplete
value="#{testBean.selectedA.val2}"
completeMethod="#{testBean.testAutoComplete}"
var="varB"
itemValue="#{varB}"
forceSelection="true" dropdown="true">
<p:column>
<h:outputText value="#{varB.val10}" />
</p:column>
<p:column>
<h:outputText value="#{varB.val11}" />
</p:column>
</p:autoComplete>
并且value="#{testBean.selectedA.val2}"
应该指向您从autocomplete
方法获得的相同类型的对象。