Primefaces orderlist custom converter submitting w

2019-08-23 02:37发布

问题:

I need to reshuffle the order of some data models in a list, so I use Primefaces orderlist. The facelet is:

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:p="http://primefaces.org/ui"
  xmlns:f="http://java.sun.com/jsf/core">
<h:head>
    <title>Facelet Title</title>
</h:head>
<h:body>
    <h:form id="main-form">
        <p:panelGrid id="grid" columns="3">
            <p:outputLabel value="Name" for="label"/> 
            <p:inputText id="label" value="#{sampleBean.obj.name}" />
            <p:message for="label"/>
        </p:panelGrid>
        <br/><p:commandButton value="Add" action="#{sampleBean.addToList()}" update="@form" />
        <br/>
        <p:orderList id="rows" value="#{sampleBean.list}" converter="sample2" 
                     itemValue="#{row}" var="row">
            <p:column>
                #{row.name}
            </p:column>
        </p:orderList>
        <br/><p:commandButton value="Export" action="#{sampleBean.export()}" update="@form" />
    </h:form>
    <p:messages autoUpdate="true"/>
</h:body>
</html>

The backing bean is:

@javax.inject.Named
@javax.faces.view.ViewScoped
public class SampleBean implements java.io.Serializable {
private List<SampleModel> list;
private SampleModel obj;

public SampleBean() {
    list = new ArrayList<>();
    obj = new SampleModel();
    obj.setName("");
}

public void addToList() {
    list.add(obj);
    obj = new SampleModel();
    obj.setName("");
}

public void export() {
    StringBuilder buf= new StringBuilder();
    for (SampleModel m: list) {
        buf.append(m.getName()).append(',');
    }
    FacesMessage msg = new FacesMessage(buf.toString());
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

public List<SampleModel> getList() {
    return list;
}

public void setList(List<SampleModel> list) {
    this.list = list;
}

public SampleModel getObj() {
    return obj;
}

public void setObj(SampleModel obj) {
    this.obj = obj;
}
}

The sample model is:

public class SampleModel {

private String name;
private String uname;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
    this.uname = name.toUpperCase();
}

public String getUname() {
    return uname;
}

public void setUname(String uname) {
    this.uname = uname;
}
}

Using a simple converter is OK. But since my real usage has a flexible structure, so the object will gonna be org.bson.Document. The following converter using a JSON representation does not work:

@FacesConverter("sample2")
public class Sample2Converter  implements Converter {

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    SampleModel model = new SampleModel();
    try {
        Document d = Document.parse(value);
        model.setName(d.getString("name"));
    }
    catch (RuntimeException ex) {
        model.setName("exception");
        Logger.getLogger("Sample2Converter").log(Level.SEVERE, null, ex);
    }
    return model;
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value instanceof SampleModel) {
        SampleModel model = (SampleModel)value;
        return new Document().append("name", model.getName()).append("uname", model.getUname()).toJson();
    }
    else
        return "invalid";
}

}

From Chrome browser debug, upon ajax post back, the list is submitting main-form:rows_values: [object Object] instead of main-form:rows_values: {"name":"apple"}

I am using Mojarra 2.2.12, Primefaces 6.1.

回答1:

Conversion to json fools the Primefaces script. As a work around, I use base64 encode/decode in the custom converter and solved the problem.