Jsf p:选择ManyMenu和@FacesConverter(forClass=Clazz.class)

Jsf p:选择ManyMenu和@FacesConverter(forClass=Clazz.class),jsf,primefaces,converter,selectmanymenu,Jsf,Primefaces,Converter,Selectmanymenu,这似乎是泛型橡皮擦问题(在运行时删除列表的泛型类型参数,使其变为非类型的列表) color[]应该可以工作,但尝试时未调用action()方法本身 需要明确提及转换器的确切原因是什么 附加: 转换器: java.lang.ClassCastException: java.lang.String cannot be cast to com.example.Colour 这个问题是双重的 第一个问题是EL无法确定模型值类型,因为泛型类型信息在运行时丢失。它基本上变成了Object.class。您

这似乎是泛型橡皮擦问题(在运行时删除
列表
的泛型类型参数,使其变为非类型的
列表

color[]
应该可以工作,但尝试时未调用
action()
方法本身

需要明确提及转换器的确切原因是什么


附加:

转换器:

java.lang.ClassCastException: java.lang.String cannot be cast to com.example.Colour

这个问题是双重的

第一个问题是EL无法确定模型值类型,因为泛型类型信息在运行时丢失。它基本上变成了
Object.class
。您基本上需要用
color[]
替换
List
。这一问题的详细答案如下:

第二个问题是PrimeFaces有一个缺陷,在定位转换器之前,它没有考虑数组类型。下面的行号匹配5.2

public class Colour implements Serializable {

    private Long colourId;
    private String colourName;
    private String colourHex;
    private static final long serialVersionUID = 1L;

    public Colour() {}

    public Long getColourId() {
        return colourId;
    }

    public void setColourId(Long colourId) {
        this.colourId = colourId;
    }

    public String getColourName() {
        return colourName;
    }

    public void setColourName(String colourName) {
        this.colourName = colourName;
    }

    public String getColourHex() {
        return colourHex;
    }

    public void setColourHex(String colourHex) {
        this.colourHex = colourHex;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 47 * hash + Objects.hashCode(getColourId());
        return hash;
    }

    @Override
    public boolean equals(Object that) {
        if (!(that instanceof Colour)) {
            return false;
        }

        return this == that || Objects.equals(getColourId(), ((Colour) that).getColourId());
    }

    @Override
    public String toString() {
        return String.format("%s[colourId=%d]", getClass().getCanonicalName(), getColourId());
    }
}

您最好将此作为一个bug报告给PrimeFaces的家伙,同时报告它在标准组件(如
)中运行良好这一事实。同时,您最好只显式注册转换器。

这可以作为dupe接受吗?对除了使用
color[]
对我不起作用之外。未调用
action()
方法本身。是否发生转换/验证错误?注意
@Named
@facescoverter
是互斥的(即创建了两个独立的实例,一个由CDI管理,另一个由JSF管理)。除非您使用的是OmniFaces,
@Inject
在JSF托管的
@FacesConverter
实例中不起作用。
@Inject
由于类路径上的OmniFaces而起作用。我从转换器中删除了CDI标识。提交后,它将通过转换器。没有转换错误(
required=“true”
也被删除),但是当
List
变为
color[]
时,它没有到达
action()
方法。谁是守护进程/恶魔下载者?三年多来第一次,说了些关于反对票的话。许多业余和不成熟的人(即使他们达到了大学水平)每天都使用克隆人账户和/或代表他们的同事对自己的帖子投欺诈票。尽可能多地把你的反对票投给质量差的帖子。没有充分的理由,请不要打扰我。我已经够不安了。
java.lang.ClassCastException: java.lang.String cannot be cast to com.example.Colour
@Named
@ApplicationScoped
@FacesConverter(forClass = Colour.class)
public class ColourConverter implements Converter {

    @Inject
    private DataStore dataStore;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null || value.isEmpty()) {
            return null;
        }

        try {
            long parsedValue = Long.parseLong(value);

            if (parsedValue <= 0) {
                throw new ConverterException("FacesMessage");
            }

            Colour entity = dataStore.findColourById(parsedValue);

            if (entity == null) {
                throw new ConverterException("FacesMessage");
            }
            return entity;
        } catch (NumberFormatException e) {
            throw new ConverterException("FacesMessage", e);
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (value == null) {
            return "";
        }

        if (!(value instanceof Colour)) {
            throw new ConverterException("Message");
        }

        Long id = ((Colour) value).getColourId();
        return id != null ? id.toString() : "";
    }
}
@Named
@ApplicationScoped
public class DataStore {

    private List<Colour> colours;

    public DataStore() {}

    @PostConstruct
    private void init() {
        colours = new ArrayList<>();

        Colour colour = new Colour();
        colour.setColourId(1L);
        colour.setColourName("Red");
        colour.setColourHex("FF0000");
        colours.add(colour);

        colour = new Colour();
        colour.setColourId(3L);
        colour.setColourName("Green");
        colour.setColourHex("008000");
        colours.add(colour);

        colour = new Colour();
        colour.setColourId(2L);
        colour.setColourName("Blue");
        colour.setColourHex("0000FF");
        colours.add(colour);
    }

    public Colour findColourById(Long id) {
        for (Colour colour : colours) {
            if (colour.getColourId().equals(id)) {
                return colour;
            }
        }

        return null;
    }

    public List<Colour> getColours() {
        return colours;
    }
}
public class Colour implements Serializable {

    private Long colourId;
    private String colourName;
    private String colourHex;
    private static final long serialVersionUID = 1L;

    public Colour() {}

    public Long getColourId() {
        return colourId;
    }

    public void setColourId(Long colourId) {
        this.colourId = colourId;
    }

    public String getColourName() {
        return colourName;
    }

    public void setColourName(String colourName) {
        this.colourName = colourName;
    }

    public String getColourHex() {
        return colourHex;
    }

    public void setColourHex(String colourHex) {
        this.colourHex = colourHex;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 47 * hash + Objects.hashCode(getColourId());
        return hash;
    }

    @Override
    public boolean equals(Object that) {
        if (!(that instanceof Colour)) {
            return false;
        }

        return this == that || Objects.equals(getColourId(), ((Colour) that).getColourId());
    }

    @Override
    public String toString() {
        return String.format("%s[colourId=%d]", getClass().getCanonicalName(), getColourId());
    }
}
156    protected Converter findImplicitConverter(FacesContext context, UIComponent component) {
157        ValueExpression ve = component.getValueExpression("value");
158
159        if(ve != null) {
160            Class<?> valueType = ve.getType(context.getELContext());
161                
162            if(valueType != null)
163                return context.getApplication().createConverter(valueType);
164        }
165
166        return null;
167    }
if (valueType.isArray()) {
    valueType = valueType.getComponentType();
}