JSF列表转换器

5
我该如何在JSF2中为类A的项目列表编写转换器?我已经为类A编写了一个转换器,但是使用默认的toString()函数显示项目:“A@ hashcode”。
我需要使用转换器而不是后备bean方法,以便进行验证(Hibernate Validator)。
更多信息:
这是我使用列表的方式:
<h:inputText id="destinations" value="#{rule.destinations}" converter="gr.panayk.vinyls.Destination"/>

当#{rule.destinations}是List<Destination>类型时,我期望得到一个逗号分隔的Destinations转换列表。

解决方案

我附上了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." );
        }
    }
}
1个回答

6

现在我得到了以下信息:java.lang.IllegalArgumentException: 无法将 [gr.panayk.vinyls.model.Destination@59c527be, gr.panayk.vinyls.model.Destination@679b622d] 对象转换为 DestinationConverter。这是由我的转换器抛出的消息。看起来它试图将列表转换为一个项目。我将添加更多关于我的用例的信息。 - Panayiotis Karabassis
顺便说一句,谢谢。我认为你是JSF方面的顶尖专家。如果您需要更多信息,请告诉我。 - Panayiotis Karabassis
1
你只需要编写相应的代码,在 getAsString()getAsObject() 中完成 List<Destination> <--> String 的转换工作(分别构建逗号分隔的字符串并在逗号处拆分)。然而,这是一个非常特定的用例,使得转换器无法重复使用于接受/返回多个单一项的普通输入。 - BalusC
没关系,我不会在其他地方使用List<Destination>。谢谢! - Panayiotis Karabassis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接