JSF:selectOneRadio转换器问题
我在使用selectOneRadio组件时遇到问题。我在转换器的getAsString中得到一个NullPointerException。该异常在我看到该组件之前抛出 这就是它的样子:JSF:selectOneRadio转换器问题,jsf,converter,Jsf,Converter,我在使用selectOneRadio组件时遇到问题。我在转换器的getAsString中得到一个NullPointerException。该异常在我看到该组件之前抛出 这就是它的样子: <h:selectOneRadio id="bookA" value="#{bookHandler.compareBookA}"> <f:converter converterId="bookConvert
<h:selectOneRadio id="bookA"
value="#{bookHandler.compareBookA}">
<f:converter converterId="bookConverter" />
<f:selectItems value="#{bookHandler.selectedBooks}"
var="book" itemLabel="#{book.shortname}" itemValue="#{book}" />
</h:selectOneRadio>
我还覆盖了toString()
出于某种原因,如果我将组件更改为selectManyCheckbox(其余部分保持原样),则会呈现该组件
我将JSF2(MyFaces实现)与Tomcat上的Tomahawk一起使用
附加问题:为什么我首先需要一个转换器?如果我不使用转换器,组件将被渲染,但是我想将所选的书传递给某个动作方法,那么它就不会是一本书了
有什么想法吗?
谢谢 显然{bookHandler.compareBookA}
只是null
当Book
为null
时,不应该抛出ConverterException
,而应该放手
return (book != null) ? book.getShortname() : null;
至于奖金问题,您需要转换器,因为HTML响应基本上是一个大字符串。所有Java对象都需要转换为字符串才能嵌入到HTML响应中。此外,HTTP请求参数默认为字符串。
request.getParameter()
返回String
。HTML/HTTP完全不知道如何处理和传递完整的Java对象
另见:
{bookHandler.compareBookA}
只是null
当Book
为null
时,不应该抛出ConverterException
,而应该放手
return (book != null) ? book.getShortname() : null;
至于奖金问题,您需要转换器,因为HTML响应基本上是一个大字符串。所有Java对象都需要转换为字符串才能嵌入到HTML响应中。此外,HTTP请求参数默认为字符串。
request.getParameter()
返回String
。HTML/HTTP完全不知道如何处理和传递完整的Java对象
另见:
public interface Entity extends Serializable {
/**
* Return the primary key for this entity
*
* @return id
*/
public BigInteger getId();
}
然后,您可以创建一个约定,规定如何将所有实体转换为字符串并返回到对象。我通常连接类名和id,然后对它们进行Base64编码,以将对象转换为字符串,然后反转转换:
/*
* (non-Javadoc)
* @see javax.faces.convert.Converter#getAsObject(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.String)
*/
@SuppressWarnings("unchecked")
public Object getAsObject(FacesContext context, UIComponent component, String value) {
Object objectValue = null;
try {
BigInteger id = null;
value = this.unhash(value);
String[] array = value.split(CLASS_KEY_SEPARATOR);
if (array.length == 2) {
id = new BigInteger(array[1]);
}
Collection<UIComponent> childComponents = component.getChildren();
for (UIComponent childComponent : childComponents) {
if (childComponent.getClass().equals(UISelectItems.class)) {
Collection<Entity> values =
(Collection<Entity>) childComponent.getValueExpression("value").getValue(FacesContext.getCurrentInstance().getELContext());
for (Entity selectItemValue : values) {
if (id.equals(selectItemValue.getId())) {
return selectItemValue;
}
}
}
}
} catch (Exception ex) {
LOGGER.error(ex.getMessage(), ex);
}
return objectValue;
}
/*
*(非Javadoc)
*@see javax.faces.convert.Converter#getAsObject(javax.faces.context.FacesContext,javax.faces.component.UIComponent,java.lang.String)
*/
@抑制警告(“未选中”)
公共对象getAsObject(FacesContext上下文、UIComponent组件、字符串值){
objectValue=null;
试试{
BigInteger id=null;
value=this.unhash(值);
String[]数组=value.split(类\键\分隔符);
if(array.length==2){
id=新的BigInteger(数组[1]);
}
Collection childComponents=component.getChildren();
用于(UIComponent childComponent:childComponents){
if(childComponent.getClass().equals(UISelectItems.class)){
集合值=
(集合)childComponent.getValueExpression(“值”).getValue(FacesContext.getCurrentInstance().getELContext());
对于(实体selectItemValue:values){
if(id.equals(selectItemValue.getId())){
返回selectItemValue;
}
}
}
}
}捕获(例外情况除外){
LOGGER.error(例如getMessage(),例如);
}
返回objectValue;
}
您的实体结构可能与我的不同,但如果您遵循基本模式,您的应用程序中的所有POJO都会使用一个转换器,该转换器表示为SelectItems。转换器提供了一种机制,可以将POJO转换为字符串(HTML)表示,然后将该字符串转换回同一POJO的实例。在您的示例中,您不希望抛出异常,而只是在Book为null时返回null 我在应用程序中经常做的一件事是创建一个通用转换器,该转换器适用于我的所有selectItems。如果您的所有实体都实现了一个公共接口,例如id属性,那么这很容易
public interface Entity extends Serializable {
/**
* Return the primary key for this entity
*
* @return id
*/
public BigInteger getId();
}
然后,您可以创建一个约定,规定如何将所有实体转换为字符串并返回到对象。我通常连接类名和id,然后对它们进行Base64编码,以将对象转换为字符串,然后反转转换:
/*
* (non-Javadoc)
* @see javax.faces.convert.Converter#getAsObject(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.String)
*/
@SuppressWarnings("unchecked")
public Object getAsObject(FacesContext context, UIComponent component, String value) {
Object objectValue = null;
try {
BigInteger id = null;
value = this.unhash(value);
String[] array = value.split(CLASS_KEY_SEPARATOR);
if (array.length == 2) {
id = new BigInteger(array[1]);
}
Collection<UIComponent> childComponents = component.getChildren();
for (UIComponent childComponent : childComponents) {
if (childComponent.getClass().equals(UISelectItems.class)) {
Collection<Entity> values =
(Collection<Entity>) childComponent.getValueExpression("value").getValue(FacesContext.getCurrentInstance().getELContext());
for (Entity selectItemValue : values) {
if (id.equals(selectItemValue.getId())) {
return selectItemValue;
}
}
}
}
} catch (Exception ex) {
LOGGER.error(ex.getMessage(), ex);
}
return objectValue;
}
/*
*(非Javadoc)
*@see javax.faces.convert.Converter#getAsObject(javax.faces.context.FacesContext,javax.faces.component.UIComponent,java.lang.String)
*/
@抑制警告(“未选中”)
公共对象getAsObject(FacesContext上下文、UIComponent组件、字符串值){
objectValue=null;
试试{
BigInteger id=null;
value=this.unhash(值);
String[]数组=value.split(类\键\分隔符);
if(array.length==2){
id=新的BigInteger(数组[1]);
}
Collection childComponents=component.getChildren();
用于(UIComponent childComponent:childComponents){
if(childComponent.getClass().equals(UISelectItems.class)){
集合值=
(集合)childComponent.getValueExpression(“值”).getValue(FacesContext.getCurrentInstance().getELContext());
对于(实体),请选择ItemValue