【问题标题】:JSF List ConverterJSF 列表转换器
【发布时间】:2011-11-29 08:58:04
【问题描述】:

如何为 JSF2 中的 A 类项目列表编写转换器?我已经为 A 类编写了一个转换器,但这些项目使用默认的 toString() 函数显示:“A@hashcode”。

我需要使用转换器而不是支持 bean 方法,以便可以进行验证(Hibernate Validator)。

更多信息

这就是我使用列表的方式:

<h:inputText id="destinations" value="#{rule.destinations}" converter="gr.panayk.vinyls.Destination"/>

其中#{rule.destinations} 是List&lt;Destination&gt; 类型。我期待一个逗号分隔的已转换目的地列表。

解决方案

附上 BalusC 提出的 List 转换器。

@FacesConverter(value="gr.panayk.vinyls.converter.DestinationList")
public class DestinationListConverter implements Converter
{
    @Override
    public Object getAsObject(final FacesContext context, final UIComponent component, final String values)
    {
        final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

        final List<Destination> result = new ArrayList<Destination>(); 
        for (String value : values.split(",", -1))
        {           
            final String trimmedValue = value.trim();

            final Set<ConstraintViolation<Destination>> violations = validator.validateValue(Destination.class, "data", trimmedValue);
            if (!violations.isEmpty())
            {
                throw new ConverterException(new FacesMessage(violations.iterator().next().getMessage()));
            }

            result.add(new Destination(trimmedValue));
        }       

        final Set<ConstraintViolation<Rule>> violations = validator.validateValue(Rule.class, "destinations", result);
        if (!violations.isEmpty())
        {
            throw new ConverterException(new FacesMessage(violations.iterator().next().getMessage()));
        }       

        return result;
    }

    @Override
    public String getAsString(final FacesContext context, final UIComponent component, final Object value)
    {
        if (value instanceof List<?>)
        {
            final StringBuffer result = new StringBuffer();

            final List<?> list = (List<?>) value;

            for (int i = 0; i < list.size()-1; i++)
            {               
                if (list.get(i) instanceof Destination)
                {
                    result.append(((Destination) list.get(i)).getData());
                    result.append(", ");
                }
                else
                {
                    throw new IllegalArgumentException( "Cannot convert " + value + " object to Destination in DestinationConverter." );
                }
            }

            if (!list.isEmpty())
            {
                if (list.get(list.size()-1) instanceof Destination)
                {
                    result.append(((Destination) list.get(list.size()-1)).getData());
                }
                else
                {
                    throw new IllegalArgumentException( "Cannot convert " + value + " object to Destination in DestinationConverter." );
                }
            }

            return result.toString();
        }
        else
        {
            throw new IllegalArgumentException( "Cannot convert " + value + " object to List in DestinationConverter." );
        }
    }
}

【问题讨论】:

    标签: java jsf-2 converter


    【解决方案1】:

    我已经为 A 类编写了一个转换器,但这些项目使用默认的 toString() 函数显示:“A@hashcode”。

    如果您没有在组件上明确声明转换器,就会发生这种情况。例如 &lt;h:selectManyCheckbox&gt;&lt;h:selectManyListbox&gt; 明确声明转换器是强制性的,因为所有 JSF/EL 都知道该值的类型是 List,而不是 List&lt;A&gt;(通用类型在运行时丢失)。如果您不声明转换器,则这些值将被视为String(因为这是 HTML 输出和 HTTP 请求参数值的默认值)。

    例如

    <h:selectManyCheckbox converter="aConverter">
    

    @FacesConverter(value="aConverter", forClass=A.class)
    public class AConverter implements Converter {
    
        // ...
    
    }
    

    当您使用像&lt;h:selectOneMenu&gt; 这样的单项输入时,不需要显式声明上述转换器,因为forClass 无论如何都会匹配它。

    【讨论】:

    • 现在我得到:java.lang.IllegalArgumentException:无法在 DestinationConverter 中转换 [gr.panayk.vinyls.model.Destination@59c527be, gr.panayk.vinyls.model.Destination@679b622d] 对象。这是我的转换器抛出的消息。它似乎正在尝试将 list 转换为项目。我将在我的用例中添加更多信息。
    • 顺便说一句,谢谢。我认为你是 JSF 的顶级专家。如果您想了解更多信息,请告诉我。
    • 您只需要相应地编写代码来执行List&lt;Destination&gt; StringgetAsString()getAsObject() 中的转换工作(分别构建一个逗号分隔的字符串并在逗号上拆分) .然而,这是一个非常具体的用例,它使转换器无法用于多次获取/返回单个项目的正常输入。
    • 没关系,我不会在其他任何地方使用 List。谢谢!
    猜你喜欢
    • 2012-12-26
    • 2011-04-01
    • 1970-01-01
    • 2018-12-24
    • 2013-04-30
    • 2011-01-06
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多