easy-es Map类型字段序列化问题:Unexpected character (‘n‘ (code 110)):

java 复制代码
@Data
@IndexName("demo")
public class EasyEsDemo {

    @IndexId
    private String id;

    private String name;
    private int age;

    // 这个Map字段因为NameFilter过滤器,导致fastjson序列化后为{null:"value"}这种形式,insert报错
    private Map<String, Object> data;
}

上面Map类型字段保存报错如下:

java 复制代码
Caused by: ElasticsearchException[Elasticsearch exception [type=json_parse_exception, reason=Unexpected character ('n' (code 110)): was expecting double-quote to start field name
.....

此错误主要原因是:EntityInfoHelper中创建的NameFilter是一个匿名类,看上去主要功能就是过滤排除字段,但是针对Map类型字段就出现了问题,导致序列化时候Map的key字段变成了个null. 导致fastjson序列化后为{null:"value"}这种形式,insert报错。

EntityInfoHelper中NameFilter过滤器代码如下:这个过滤器导致序列化Map类型字段时,获取的key当成类的字段属性处理,而类中没有名字为key的字段,所以过滤器过滤完后key变成了null

java 复制代码
    /**
     * 添加fastjson字段过滤器
     *
     * @param entityInfo 实体信息
     */
    private static void addNameFilter(EntityInfo entityInfo, List<SerializeFilter> preFilters) {
        Map<String, String> mappingColumnMap = entityInfo.getMappingColumnMap();
        Map<Class<?>, Map<String, String>> nestedClassMappingColumnMap = entityInfo.getNestedClassMappingColumnMap();
        if (!mappingColumnMap.isEmpty()) {
            NameFilter nameFilter = (object, name, value) -> {
                Map<String, String> nestedMappingColumnMap = nestedClassMappingColumnMap.get(object.getClass());
                if (Objects.nonNull(nestedMappingColumnMap)) {
                    String nestedMappingColumn = nestedMappingColumnMap.get(name);
                    if (Objects.equals(nestedMappingColumn, name)) {
                        return name;
                    } else {
                        return nestedMappingColumn;
                    }
                }
                String mappingColumn = mappingColumnMap.get(name);
                if (Objects.equals(mappingColumn, name)) {
                    return name;
                }
                return mappingColumn;
            };
            preFilters.add(nameFilter);
        }
    }

不知道是个bug还是不推荐使用Map类型字段。或者说有别的处理方式。目前使用的处理方式如下:自定义一个Map的序列化器,并在Map类型字段增加注解

java 复制代码
    public static class MyMapSerializer extends MapSerializer {
        @Override
        protected String processKey(JSONSerializer jsonBeanDeser, Object object, String key, Object propertyValue) {
           // 删除了 jsonBeanDeser.nameFilters 的处理逻辑

            if (this.nameFilters != null) {
                for (NameFilter nameFilter : this.nameFilters) {
                    key = nameFilter.process(object, key, propertyValue);
                }
            }
            return key;
        }
    }


    // 手动指定自定义的序列化处理器

    @JSONField(serializeUsing = MyMapSerializer.class)
    private Map<String, Object> data;
相关推荐
毕设源码-赖学姐18 小时前
【开题答辩全过程】以 基于Android的校园快递互助APP为例,包含答辩的问题和答案
java·eclipse
damo0118 小时前
stripe 支付对接
java·stripe
麦麦鸡腿堡19 小时前
Java的单例设计模式-饿汉式
java·开发语言·设计模式
假客套19 小时前
Request method ‘POST‘ not supported,问题分析和解决
java
傻童:CPU19 小时前
C语言需要掌握的基础知识点之前缀和
java·c语言·算法
三口吃掉你19 小时前
Docker安装Elasticsearch、kibana、IK分词器
elasticsearch·docker·kibana·ik分词器
爱吃山竹的大肚肚19 小时前
@Valid校验 -(Spring 默认不支持直接校验 List<@Valid Entity>,需用包装类或手动校验。)
java·开发语言
雨夜之寂20 小时前
mcp java实战 第一章-第一节-MCP协议简介.md
java·后端
皮皮林55120 小时前
蚂蚁又开源了一个顶级 Java 项目!
java
吹晚风吧20 小时前
spring是如何解决循环依赖的(二级缓存不行吗)?
java·spring·循环依赖·三级缓存