MyBatis-plus自定义TypeHandler存储对象数组报错:JSONException: expect ‘[‘, but {, pos 2, line 1, column 3)

MyBatis-plus自定义TypeHandler存储对象数组报错:JSONException: expect '[', but {, pos 2, line 1, column 3

问题重现

业务需要存储某区域边缘的经纬度点集合,因此在DO中创建了List<Point(Double,Double)>对象属性进行经纬度点集的存储,意图将其以Json的形式存储于Mysql中。
DO属性

已知资料

首先使用FastjsonTypeHandler进行尝试,将List< Point >行和Point行加上注释@TableField(jdbcType = JdbcType.VARCHAR,typeHandler = FastjsonTypeHandler.class)。然而报错难以解析List< Point >。查找现有资料, MyBatis-plus处理存储json数据。发现由于FastjsonTypeHandler的parse方法默认使用JSON.parseObject,这只能适用于复制单个Json对象。因此考虑将其重写使用JSON.parseArray方法。然而报错如下图所示。
expect ‘[’, but {, pos 2, line 1, column 3[{“lat”:10.0,“lon”:10.0},{“lat”:11.0,“lon”:11.0}]
报错

问题分析

首先附上改进FastjsonTypeHandler的部分代码

public class MyJsonObjectListHandler extends FastjsonTypeHandler {
	private final Class<? extends Object> type;
    public MyJsonObjectListHandler(Class<?> type) {
        super(type);
        this.type = type;
    }
    @Override
    protected Object parse(String json) {
        return JSON.parseArray(json, type);
    }
}

进行断点分析,发现FastjsonTypeHandler中的parse在定于目标为List< Object > 时,其内部type为List。因此,JSON会以List< List >的形式进行类型转换。这也是其会将[{“lat”:10.0,“lon”:10.0},{“lat”:11.0,“lon”:11.0}]转换时报错expect ‘[’, but {, pos 2, line 1, column 3的原因,因为他认为我们需要的是数组的数组,因此[]中的还得是数组,而实际上我们需要的是对象的数组。
在这里插入图片描述

问题解决

找到了原因是type被误认为List< List >,而非List< Object >那么就想办法让type能够正确识别为Object。最终代码如下:

@Slf4j
@MappedTypes({Object.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class MyJsonObjectListHandler extends FastjsonTypeHandler {
    private final Class<? extends Object> type;
    public MyJsonObjectListHandler(Class<?> type) {
        super(type);
        this.type = type;
    }
    @Override
    protected Object parse(String json) {
        if (type.equals(List.class)) {
            Class<? extends Object> actualType=type.getComponentType();
            return JSON.parseArray(json, actualType);
        }
        return JSON.parseObject(json, type);
    }

    @Override
    protected String toJson(Object obj) {
        return super.toJson(obj);
    }
}

当我们所需类型为List型时,代码会从List中取到正确的Object类型。这一类型虽然默认为String,但将这一String转为我们所需的Object是JSON模块能做到了。将对象字段注释使用这一Handler后即可正确存读List< Object>对象了。
建库类型

库中存储
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值