PrimeFaces OrderList自定义转换器AJAX回传提交错误字符串问题
你遇到的核心问题是PrimeFaces OrderList在AJAX回传时,没有正确调用自定义转换器的getAsString方法将对象序列化为预期的JSON字符串,而是直接输出了[object Object],导致服务器端无法解析。结合你使用的Mojarra 2.2.12 + PrimeFaces 6.1环境,我们可以从以下几个方面排查修复:
1. 修复模型类的序列化问题
你的SampleModel类没有实现Serializable接口,但SampleBean是@ViewScoped且实现了Serializable,而list属性是List<SampleModel>——ViewScoped Bean的状态需要序列化到ViewState中,如果模型类不支持序列化,会导致ViewState保存异常,间接引发AJAX请求时的对象处理错误。
修改SampleModel类,让它实现Serializable:
public class SampleModel implements java.io.Serializable { private String name; private String uname; // 保留原有的getter和setter方法 }
2. 优化自定义转换器的JSON序列化逻辑
当前转换器的getAsString方法生成的JSON可能存在格式问题(比如换行、空格),导致PrimeFaces客户端无法正确识别为字符串,进而被当作对象处理输出[object Object]。我们可以使用BSON的JsonWriterSettings生成紧凑、标准的JSON字符串:
@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; Document doc = new Document() .append("name", model.getName()) .append("uname", model.getUname()); // 生成紧凑无格式的JSON,避免客户端解析问题 JsonWriterSettings settings = new JsonWriterSettings(); settings.outputMode(JsonMode.COMPACT); return doc.toJson(settings); } else { return "invalid"; } } }
3. 确认OrderList的配置正确性
检查你的OrderList标签配置,确保itemValue和var的绑定是正确的——你的当前配置没问题,再确认一遍:
<p:orderList id="rows" value="#{sampleBean.list}" converter="sample2" itemValue="#{row}" var="row"> <p:column> #{row.name} </p:column> </p:orderList>
这里itemValue="#{row}"正确绑定了列表中的每一项,converter="sample2"也正确指向了自定义转换器,无需修改。
4. 排查客户端AJAX提交细节
如果上述修改后仍有问题,可以通过Chrome开发者工具的Network面板,查看AJAX请求的Form Data部分:
- 如果还是
[object Object],说明PrimeFaces客户端没有调用转换器的getAsString方法,这可能是PrimeFaces 6.1的小bug。此时可以尝试升级PrimeFaces到6.2+版本,后续版本修复了不少OrderList的转换器相关问题; - 也可以临时改用基于唯一标识的转换器逻辑(比如给
SampleModel增加ID属性,getAsString返回ID,getAsObject根据ID重建对象),适配PrimeFaces的客户端处理逻辑。
按照上述步骤修改后,应该能解决AJAX回传时的序列化问题,让OrderList正确传递JSON字符串给服务器端转换器。
内容的提问来源于stack exchange,提问作者cpliu338

