在JSF项目中,我有一个由字符串值列表填充的SelectOneMenu,并连接到Integer值“yearStart”。 当我从列表中选择一个值时,转换器总是输出到控制台“stringVal = null”。 为什么所选项目的值不能转换为转换器?
我的网页包含以下内容:
<h:selectOneMenu value="#{applicantController.yearStart}">
<f:selectItems value="#{yearList.years}" />
<f:converter converterId="studyYearConverter"/>
</h:selectOneMenu>
它使用这个年份列表:
@ManagedBean
@ApplicationScoped
public class YearList implements Serializable {
private static final long serialVersionUID = 1L;
private final List<String> years = Arrays.asList("prior to 1990", "1990",
"1991", "1992", "1993", "1994", "1995", "1996", "1997", "1998",
"1999", "2000", "2001", "2002", "2003", "2004", "2005", "2006",
"2007", "2008", "2009", "2010", "2011", "2012", "2013");
public List<String> getYears() {
return years;
}
}
我的转换器类:
@FacesConverter(value = "studyYearConverter")
public class StudyYearConverter implements Converter {
private static final String PRIOR_TO_1990 = "prior to 1990";
@Override
public Object getAsObject(FacesContext context, UIComponent component,
String stringVal) {
if (PRIOR_TO_1990.equals(stringVal)) {
return -1;
} else {
System.out.println("stringVal = " + stringVal);
// Why is this alway null??
try {
return Integer.parseInt(stringVal);
} catch (NumberFormatException pe) {
FacesMessage message = new FacesMessage(
"Invalid date format. Valid format e.g. 2010-04");
throw new ConverterException(message);
}
}
}
@Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
if (value == null || !(value instanceof Integer)) {
return null;
} else {
Integer year = (Integer) value;
if (year == -1) {
return PRIOR_TO_1990;
} else {
return year.toString();
}
}
}
}
答案 0 :(得分:0)
您没有提供转换器所需的物品。
在呈现HTML响应期间使用getAsString()
方法。此时,(可能)复杂的Java对象需要转换为其唯一的String
表示,以便它们可以用HTML表示。在应用HTTP请求参数值期间使用getAsObject()
方法。 HTTP请求参数值可以像HTML输入值一样只表示为String
,为了获得复杂的Java对象,必须转换唯一的String
表示。
您有List<String>
个可用的项目值。因此,当每个项目即将呈现为HTML时,它将通过getAsString()
。但是,您正在执行instanceof Integer
检查,该检查始终会失败,因此会为每个项目返回null
。因此,您最终会在生成的HTML中获得无价值的<option>
,并以null
的形式提交。这就是为什么getAsObject()
最终得到null
的原因。
根据到目前为止的尝试,我的印象是#{applicantController.yearStart}
实际上是Integer
,您想要用年份设置,或-1
if“1990之前“被选中。如果您想保留转换器,那么您应该将可用项目更改为
private final List<Integer> years = Arrays.asList(-1, 1990,
1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012, 2013);
答案 1 :(得分:-1)
我知道哪个可能是解决方案。 您应该将列表和所选元素存储在属性中,并且只要使用该组件,就将它们保留在范围内。