使用转换器时未调用 SelectOneMenu setter
SelectOneMenu the setter is not being called when using a converter
我创建了一个简单的转换器,我正在读书,下面的代码应该可以工作,但是当我 select 一个项目时,它没有被设置为值。
我在 setter 上放置了一个断点,当 select selectOneMenu.
中的一个项目时,它没有被击中
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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></title>
</h:head>
<h:body>
<h:form>
dfdfd
<p:selectOneMenu value="#{selecaoController.selectedTag}" var="t"
converter="tagConverter">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{selecaoController.tagPojos}" var="tag"
itemLabel="#{tag.label}" itemValue="#{tag}" />
<p:column>
#{t.label} - #{t.value}
</p:column>
<p:column>
<p:graphicImage value="/resources/images/tags/#{t.value}.png"
width="32px" height="32px"/>
</p:column>
<p:ajax event="change" process="@this" update="msg" />
</p:selectOneMenu>
<p:outputLabel id="msg" value="#{selecaoController.selectedTag.label}" />
</h:form>
</h:body>
</html>
班级。
package com.packtpub.pfbg.controllers;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author diego
*/
@FacesConverter(value = "tagConverter")
public class TagConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value == null || value.trim().equals("")){
return null;
}
try{
Tag t1 = new Tag(1, "JavaScript", "javascript");
Tag t2 = new Tag(2, "C#", "C#");
Tag t3 = new Tag(3, "Java", "Java");
Tag t4 = new Tag(4, "Angular", "angular");
List<Tag> ts = new ArrayList<Tag>();
ts.add(t1);
ts.add(t2);
ts.add(t3);
ts.add(t4);
int id = Integer.parseInt(value);
List<Tag> tags = ts;
for(Tag t : tags){
if(t.getId() == id){
return t;
}
}
}
catch(NumberFormatException ex){
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "conversion erro", "Not a valid tag"));
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value == null || value.equals("")){
return "";
}else{
return String.valueOf(((Tag) value).getId());
}
}
}
超一流
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.packtpub.pfbg.controllers;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
/**
*
* @author diego
*/
@ManagedBean
@RequestScoped
public class SelecaoController {
private List<Tag> tagPojos;
private Tag selectedTag;
public SelecaoController(){
tagPojos = new ArrayList<Tag>();
tagPojos.add(new Tag(1, "JavaSE", "java-se", "Java Programming Language"));
tagPojos.add(new Tag(2, "JavaEE", "javaEE", "Java Enterprise"));
tagPojos.add(new Tag(3, "Spring", "Spring", "Spring Framework"));
}
public List<Tag> getTagPojos() {
return tagPojos;
}
public void setTagPojos(List<Tag> tagPojos) {
this.tagPojos = tagPojos;
}
public Tag getSelectedTag() {
return selectedTag;
}
public void setSelectedTag(Tag selectedTag) {
this.selectedTag = selectedTag;
}
}
如果您为字段添加 growl
或 message
或提高日志级别,您将在 select 项目后看到此错误:
Validation Error: Value is not valid
问题是 selected 值不在列表中。
在列表中搜索的 jsf 代码迭代 selectOneMenu
的所有子项并检查从转换器编辑的元素 return 是否等于其中任何一个。
您有很多方法可以让您的代码正常工作:
由于您正在使用另一个列表,您可以覆盖 Tag
class 中的 equals 方法,例如仅检查 id
值,如果它是键,以便即使没有相同的对象也能获得匹配
在转换器中迭代相同的列表,return 完全相同的对象
对于解决方案 2,如果您将控制器移动到 view scope
,此代码有效,但也有直接来自组件变量和 request scope
.
的方法
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
SelecaoController viewScopedBean = (SelecaoController) viewMap.get("selecaoController");
for (Tag t : viewScopedBean.getTagPojos()) {
if (t.getId() == id) {
return t;
}
}
我创建了一个简单的转换器,我正在读书,下面的代码应该可以工作,但是当我 select 一个项目时,它没有被设置为值。 我在 setter 上放置了一个断点,当 select selectOneMenu.
中的一个项目时,它没有被击中<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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></title>
</h:head>
<h:body>
<h:form>
dfdfd
<p:selectOneMenu value="#{selecaoController.selectedTag}" var="t"
converter="tagConverter">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{selecaoController.tagPojos}" var="tag"
itemLabel="#{tag.label}" itemValue="#{tag}" />
<p:column>
#{t.label} - #{t.value}
</p:column>
<p:column>
<p:graphicImage value="/resources/images/tags/#{t.value}.png"
width="32px" height="32px"/>
</p:column>
<p:ajax event="change" process="@this" update="msg" />
</p:selectOneMenu>
<p:outputLabel id="msg" value="#{selecaoController.selectedTag.label}" />
</h:form>
</h:body>
</html>
班级。
package com.packtpub.pfbg.controllers;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author diego
*/
@FacesConverter(value = "tagConverter")
public class TagConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value == null || value.trim().equals("")){
return null;
}
try{
Tag t1 = new Tag(1, "JavaScript", "javascript");
Tag t2 = new Tag(2, "C#", "C#");
Tag t3 = new Tag(3, "Java", "Java");
Tag t4 = new Tag(4, "Angular", "angular");
List<Tag> ts = new ArrayList<Tag>();
ts.add(t1);
ts.add(t2);
ts.add(t3);
ts.add(t4);
int id = Integer.parseInt(value);
List<Tag> tags = ts;
for(Tag t : tags){
if(t.getId() == id){
return t;
}
}
}
catch(NumberFormatException ex){
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "conversion erro", "Not a valid tag"));
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value == null || value.equals("")){
return "";
}else{
return String.valueOf(((Tag) value).getId());
}
}
}
超一流
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.packtpub.pfbg.controllers;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
/**
*
* @author diego
*/
@ManagedBean
@RequestScoped
public class SelecaoController {
private List<Tag> tagPojos;
private Tag selectedTag;
public SelecaoController(){
tagPojos = new ArrayList<Tag>();
tagPojos.add(new Tag(1, "JavaSE", "java-se", "Java Programming Language"));
tagPojos.add(new Tag(2, "JavaEE", "javaEE", "Java Enterprise"));
tagPojos.add(new Tag(3, "Spring", "Spring", "Spring Framework"));
}
public List<Tag> getTagPojos() {
return tagPojos;
}
public void setTagPojos(List<Tag> tagPojos) {
this.tagPojos = tagPojos;
}
public Tag getSelectedTag() {
return selectedTag;
}
public void setSelectedTag(Tag selectedTag) {
this.selectedTag = selectedTag;
}
}
如果您为字段添加 growl
或 message
或提高日志级别,您将在 select 项目后看到此错误:
Validation Error: Value is not valid
问题是 selected 值不在列表中。
在列表中搜索的 jsf 代码迭代 selectOneMenu
的所有子项并检查从转换器编辑的元素 return 是否等于其中任何一个。
您有很多方法可以让您的代码正常工作:
由于您正在使用另一个列表,您可以覆盖
Tag
class 中的 equals 方法,例如仅检查id
值,如果它是键,以便即使没有相同的对象也能获得匹配在转换器中迭代相同的列表,return 完全相同的对象
对于解决方案 2,如果您将控制器移动到 view scope
,此代码有效,但也有直接来自组件变量和 request scope
.
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
SelecaoController viewScopedBean = (SelecaoController) viewMap.get("selecaoController");
for (Tag t : viewScopedBean.getTagPojos()) {
if (t.getId() == id) {
return t;
}
}