Java JSF列表转换器

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

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

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

更多信息 以下是我使用列表的方式:

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

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

解决方案 我附上BalusC提议的列表转换器

@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." );
        }
    }
}
@FacesConverter(value=“gr.panayk.vinyls.converter.DestinationList”)
公共类DestinationListConverter实现转换器
{
@凌驾
公共对象getAsObject(最终FacesContext上下文、最终UIComponent组件、最终字符串值)
{
最终验证器验证器=Validation.buildDefaultValidatorFactory().getValidator();
最终列表结果=新建ArrayList();
for(字符串值:values.split(“,”,-1))
{           
最终字符串trimmedValue=value.trim();
最终设置冲突=validator.validateValue(Destination.class,“data”,trimmedValue);
如果(!inflictions.isEmpty())
{
抛出新的ConverterException(新的FacesMessage(inflictions.iterator().next().getMessage());
}
结果.添加(新目的地(trimmedValue));
}       
最终设置冲突=validator.validateValue(Rule.class,“destinations”,result);
如果(!inflictions.isEmpty())
{
抛出新的ConverterException(新的FacesMessage(inflictions.iterator().next().getMessage());
}       
返回结果;
}
@凌驾
公共字符串getAsString(最终FacesContext上下文、最终UIComponent组件、最终对象值)
{
if(列表的值实例)
{
最终StringBuffer结果=新StringBuffer();
最终列表=(列表)值;
对于(int i=0;i
我已经为类a编写了一个转换器,但是这些项使用默认的toString()函数显示:A@hashcode“

如果没有在组件上显式声明转换器,则可能发生这种情况。例如,在
中,显式声明转换器是强制的,因为JSF/EL所知道的是值的类型是
列表
,而不是
列表
(在运行时会丢失泛型类型)。如果不声明转换器,则这些值将被视为
字符串
(这是HTML输出和HTTP请求参数值的默认值)

例如



当您使用诸如
之类的单项输入时,不需要显式声明上述转换器,因为
for class
无论如何都会与之匹配。

现在我得到:java.lang.IllegalArgumentException:无法转换[gr.panayk.vinyls.model]。Destination@59c527be,gr.panayk.vinyls.model。Destination@679b622d]对象在DestinationConverter中。这是我的转换器抛出的消息。它似乎正在尝试将列表转换为项目。我会在我的用例中添加更多信息。顺便说一句,谢谢。我认为你是JSF领域的顶级专家。如果您需要更多信息,请告诉我。您只需编写相应的代码,即可在
getAsString()
getAsObject()
中执行
列表
字符串
转换作业(分别构建逗号分隔的字符串和在逗号上拆分)。然而,这是一个非常特殊的用例,使得转换器对于多次获取/返回单个项目的正常输入不可用。没关系,我不会在其他任何地方使用列表。谢谢
@FacesConverter(value="aConverter", forClass=A.class)
public class AConverter implements Converter {

    // ...

}