<o:importConstants
type="com.xxx.enums.UsState"
var="UsState" />
<b:selectOneMenu
id="homeStateSelectOneMenu"
value="#{contactPage.contact.homeState}"
label="Home State"
converter="DisplayableTextConverter">
<f:selectItem
id="selectOneUsStateSelectItem"
itemLabel="Select One"
noSelectionOption="true"
itemDisabled="true" />
<f:selectItems
id="usStateSelectItems"
value="#{UsState}" />
</b:selectOneMenu>
模型对象有以下字段:
@Enumerated(EnumType.STRING)
@Column(name = "home_state")
@NotNull //LYNCHPIN
private UsState homeState;
转换器:
@ApplicationScoped
@FacesConverter(value = "DisplayableTextConverter", managed = true)
public class DisplayableTextConverter implements Converter<DisplayableText> {
public static final String STATE_KEY = "DisplayableTextConverter.forClass";
@SuppressWarnings("unchecked")
@Override
public DisplayableText getAsObject(final FacesContext context, final UIComponent component, String text) {
text = trimToNull(text);
if (text != null) {
final String className = (String) component.getTransientStateHelper().getTransient(STATE_KEY);
try {
return DisplayableText.parseEnum(text, (Class<DisplayableText>) Class.forName(className));
} catch (final ClassNotFoundException e) {
throw new RuntimeException(e);
}
} else {
return null;
}
}
@Override
public String getAsString(final FacesContext context, final UIComponent component, final DisplayableText displayableText) {
if (displayableText != null) {
component.getTransientStateHelper().putTransient(STATE_KEY, displayableText.getClass().getName());
return displayableText.getDisplayText();
} else {
return null;
}
}
}
public enum UsState implements DisplayableText {
AL("Alabama"), AK("Alaska"), AZ("Arizona"), AR("Arkansas"), ....
public final String displayText;
@Override
public String getDisplayText() {
return displayText;
}
UsState(String specificDisplayValue) {
displayText = specificDisplayValue;
}
}
有趣的是如果我们把
@NotNull
,表单提交,如果我们添加它,提交失败。在堆栈跟踪中,当
在某些情况下,验证程序似乎在转换器之前被调用。为什么会这样?
@不为空
java.lang.IllegalArgumentException: Arkansas is not an instance of class com.xxx.UsState
at org.apache.bval.jsr.job.ValidateProperty.<init>(ValidateProperty.java:515)
at org.apache.bval.jsr.job.ValidationJobFactory.validateValue(ValidationJobFactory.java:76)
at org.apache.bval.jsr.ValidatorImpl.validateValue(ValidatorImpl.java:65)
at org.apache.bval.jsr.CascadingPropertyValidator.validateValue(CascadingPropertyValidator.java:99)
at javax.faces.validator.BeanValidator.validate(BeanValidator.java:218)
at javax.faces.component._ComponentUtils.callValidators(_ComponentUtils.java:291)
at javax.faces.component.UIInput.validateValue(UIInput.java:489)
at net.bootsfaces.component.selectOneMenu.SelectOneMenu.validateValue(SelectOneMenu.java:118)
at net.bootsfaces.component.selectOneMenu.SelectOneMenuRenderer.decode(SelectOneMenuRenderer.java:96)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:479)
at javax.faces.component.UIInput.decode(UIInput.java:371)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1408)
at javax.faces.component.UIInput.processDecodes(UIInput.java:207)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1402)
at javax.faces.component.UIForm.processDecodes(UIForm.java:154)
at org.apache.myfaces.context.servlet.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:775)
这里没有
@不为空
DisplayableTextConverter
):
at com.xxx.jsf.converter.DisplayableTextConverter.getAsObject(DisplayableTextConverter.java:21)
at com.xxx.jsf.converter.DisplayableTextConverter.getAsObject(DisplayableTextConverter.java:1)
at org.apache.myfaces.cdi.converter.FacesConverterCDIWrapper.getAsObject(FacesConverterCDIWrapper.java:63)
at net.bootsfaces.render.CoreRenderer.getConvertedValue(CoreRenderer.java:532)
at javax.faces.component.UIInput.getConvertedValue(UIInput.java:789)
at javax.faces.component.UIInput.validate(UIInput.java:708)
at javax.faces.component.UIInput.processValidators(UIInput.java:293)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1458)
at javax.faces.component.UIForm.processValidators(UIForm.java:210)
at org.apache.myfaces.context.servlet.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:779)
谢谢!它在ApacheTomee8.0.6上运行,但在MyFaces2.3.8和BootsFaces1.5.0上运行