You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用omnifaces.ListConverter遇NotSerializableException问题求助(非MyFaces环境)

解决JSF 2.2 + PrimeFaces 6.1 + WebLogic 12.2.1下OmniFaces ListConverter序列化异常问题

问题复盘

你遇到的这个java.io.NotSerializableException: org.omnifaces.taghandler.Converter异常,场景很明确:在<p:dataTable>行编辑模式下,搭配使用OmniFaces的ListConverter和<p:autoComplete>时触发,而且BalusC针对MyFaces的方案不适用——毕竟你的项目用的是WebLogic默认的Mojarra实现。

先把典型的代码示例贴出来(方便后续分析):

常见代码场景

XHTML 片段

<p:dataTable value="#{entityBean.items}" var="item" editable="true">
    <p:column headerText="关联实体">
        <p:cellEditor>
            <f:facet name="output">#{item.relatedEntity.displayName}</f:facet>
            <f:facet name="input">
                <p:autoComplete value="#{item.relatedEntity}" 
                                completeMethod="#{entityBean.completeEntities}"
                                converter="omnifaces.ListConverter"
                                var="entity" itemLabel="#{entity.displayName}" itemValue="#{entity}">
                    <f:attribute name="list" value="#{entityBean.allEntities}" />
                </p:autoComplete>
            </f:facet>
        </p:cellEditor>
    </p:column>
    <p:column>
        <p:rowEditor />
    </p:column>
</p:dataTable>

Managed Bean 片段

@ManagedBean
@ViewScoped
public class EntityBean implements Serializable {
    private List<Item> items;
    private List<RelatedEntity> allEntities;

    // 初始化、getter/setter省略
    public List<RelatedEntity> completeEntities(String query) {
        return allEntities.stream()
                          .filter(e -> e.getDisplayName().toLowerCase().contains(query.toLowerCase()))
                          .collect(Collectors.toList());
    }
}

// 实体类示例
public class Item implements Serializable {
    private RelatedEntity relatedEntity;
    // getter/setter
}

public class RelatedEntity implements Serializable {
    private Long id;
    private String displayName;
    // getter/setter、equals/hashCode重写
}

异常根源分析

WebLogic 12.2.1的Mojarra实现,在处理视图状态序列化时,会把行编辑模式下的组件状态(包括绑定的Converter)存入会话。而OmniFaces的ListConverter内部依赖的org.omnifaces.taghandler.Converter类没有实现Serializable接口,当视图状态被序列化时,这个非序列化的依赖就会触发异常——这和MyFaces的bug场景不同,所以BalusC的MyFaces方案不适用。

针对性解决方案

方案1:自定义可序列化的ListConverter

最稳妥的方式是自己实现一个逻辑和OmniFaces ListConverter一致,但完全支持序列化的Converter:

@FacesConverter("serializableListConverter")
public class SerializableListConverter implements Converter, Serializable {

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

        @SuppressWarnings("unchecked")
        List<Object> targetList = (List<Object>) component.getAttributes().get("list");
        if (targetList == null) {
            throw new IllegalArgumentException("组件未绑定list属性,请检查<f:attribute name='list'/>配置");
        }

        // 匹配逻辑:用toString()对应(和OmniFaces ListConverter一致)
        return targetList.stream()
                         .filter(item -> value.equals(item.toString()))
                         .findFirst()
                         .orElse(null);
    }

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

然后把xhtml里的converter="omnifaces.ListConverter"替换成converter="serializableListConverter"即可,其他配置保持不变。

方案2:调整WebLogic序列化过滤规则

如果不想自定义Converter,可以尝试让WebLogic忽略这个非序列化类的检查:

  1. 打开WebLogic控制台,找到你的应用部署项
  2. 进入「配置」->「常规」,找到「序列化过滤」配置
  3. 添加org.omnifaces.taghandler.Converter到「允许的非序列化类」列表
  4. 或者在项目的weblogic.xml中添加如下配置:
<wls:application-param>
    <wls:param-name>weblogic.servlet.session.enableSerializationFilter</wls:param-name>
    <wls:param-value>false</wls:param-value>
</wls:application-param>

⚠️ 注意:关闭序列化过滤可能带来其他潜在的序列化问题,建议在测试环境充分验证后再上线。

方案3:升级OmniFaces版本

检查你当前使用的OmniFaces版本,如果是较旧的版本(比如2.x早期版本),可以尝试升级到兼容JSF 2.2的稳定版本(比如OmniFaces 3.14,它支持JSF 2.2+)——新版本可能已经修复了这个序列化相关的bug,让ListConverter不再依赖非序列化的taghandler类。

方案4:绕过Converter,直接绑定实体

如果场景允许,也可以尝试不用ListConverter:在<p:autoComplete>的itemValue直接绑定实体,同时确保你的RelatedEntity正确重写了equals()和hashCode()方法,PrimeFaces会自动处理实体的匹配逻辑,这样就避开了Converter序列化的问题。


内容的提问来源于stack exchange,提问作者VaazhgaV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:19:55