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;
相关推荐
CQU_JIAKE15 分钟前
11.7[高体】
java·后端·spring
apcipot_rain1 小时前
C++转Java日记(04)
java·开发语言·c++
特立独行的猫A2 小时前
我给女儿写了个打字练习:一边敲键盘,一边把小学英语单词记牢
java·后端·python
憧憬成为java架构高手的小白3 小时前
LangGraph4j 实战(下)
java
天诰4 小时前
SA-K-11 检索会消失吗与四个未解问题
java·服务器·人工智能·python·机器学习·ai编程
这个昵称不容易7 小时前
SpringBoot「衣依」服装销售平台:144个Java文件180个接口,从挑衣服到收货评价整条链路都在
java·springboot·毕设
计算机毕设定制辅导-无忧学长8 小时前
《基于微信小程序的居家医疗陪护预约系统设计与实现》
java·spring boot·微信小程序·uniapp·居家医疗陪护预约系统
文丑颜不良啊9 小时前
LeetCode2221~2240题目解析
java·leetcode
秋饼9 小时前
Computer Use Agent Java 落地实战:感知-行动循环、执行器与安全围栏生产级实现
java·ai·技术分享·后端开发
文丑颜不良啊11 小时前
LeetCode2161~2180题目解析
java·leetcode