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;
相关推荐
土司大王2 分钟前
LeetCode hot100 回溯专题总结:Java 通用模板、决策树模型
java·算法·leetcode·决策树
Wang's Blog25 分钟前
Java框架快速入门:Spring Security+OAuth2之用户注册与唯一性校验实现
java·数据库·spring
Wang's Blog36 分钟前
Java框架快速入门: Spring Security+OAuth2之多因子认证与TOTP实战
java·spring·ui
滕州市燕猫虎计算机科技工作室个体工商户1 小时前
Java面试题汇总
java·开发语言
彧azz2 小时前
Git 入门实操实例:从安装到远程仓库全流程
大数据·笔记·git·学习·elasticsearch
2301_32241428042 小时前
活力孕康复APP 47737- 原创(免费领源码+部署教程+开发环境)
java·vue.js·spring boot·mysql·微信小程序·idea·微信开发者工具
君顾12 小时前
外卖CPS软件开发实战:从系统架构到部署全流程指南
java·开发语言·外卖
醉颜凉3 小时前
Canal 与 Elasticsearch 实时同步:增量索引更新、删除处理与全量重建方案
elasticsearch·canal·数据同步·增量更新·全量重建
vx_Biye_Design3 小时前
springboot游泳馆系统93765-计算机课程设计、毕业设计
java·javascript·spring boot·后端·python·spring·课程设计
名字还没想好☜3 小时前
Java NIO ByteBuffer 实战:flip/clear/compact 三个绕晕人的方法与 position/limit 心智模型
java·开发语言·后端·spring·nio