GeoJsonPoint解析问题[BUG]
ocean23 opened this issue · comments
问题描述
简要描述您碰到的问题。
以下是json数据
{
"_id":
{
"$oid": "61a591ef96eb001a9437d6c4"
},
"gpsAddress":
{
"type": "Point",
"coordinates":
[
114.027285886961,
22.6741582981732
]
}
}
这是对应的Mapper对象的属性
private GeoJsonPoint gpsAddress;
对于1的版本,虽然调用JSON.parseObject解析出来的对象也是不正确的,内容都是0但是至少不会报错,但是2的版本后就直接报错了,是否考虑用1的解决方案假如找不到默认的构造函数就返回默认的内容就行,不要报错
环境信息
请填写以下信息:
- OS信息: [e.g.:CentOS 8.4.2105 4Core 3.10GHz 16 GB]
- JDK信息: [e.g.:Openjdk 1.8.0_312]
- 版本信息:[e.g.:Fastjson2 2.x.x]
报错信息
请复制并粘贴任何相关的日志输出。
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.AbstractList.add(AbstractList.java:153)
at java.base/java.util.AbstractList.add(AbstractList.java:111)
at com.alibaba.fastjson2.reader.FieldReaderCollectionMethodReadOnly.accept(FieldReaderCollectionMethodReadOnly.java:80)
at com.alibaba.fastjson2.reader.ObjectReaderNoneDefaultConstrutor.readObject(ObjectReaderNoneDefaultConstrutor.java:260)
at com.alibaba.fastjson2.reader.FieldReaderObjectMethod.readFieldValue(FieldReaderObjectMethod.java:78)
at com.alibaba.fastjson2.reader.ObjectReader.readObject(ObjectReader.java:371)
at com.alibaba.fastjson2.JSON.parseObject(JSON.java:146)
有问题的写法
CoreCompanyDO coreCompanyDO = JSON.parseObject(ss, CoreCompanyDO.class);
临时的解决方案
JSONObject jsonObject = JSON.parseObject(ss, JSONObject.class);
CoreCompanyDO coreCompanyDO = jsonObject.toJavaObject(CoreCompanyDO.class);
通过JSONObject中转一下就可以达到1.0版本的效果, 暂时先这样解决
GeoJsonPoint 这个类的代码能提供下么?
@wenshao hello温少,我想参与到fastjson2这个项目中来,可否大概说一下这个bug的思路吗?我尝试修复一下再发一个PR。因为之前没怎么看这个项目的源码。
这个我case有点特别,我还要想下怎么实现。这个JSON数据是怎么来的?
这个数据前端是通过百度地直获取经纬度然后塞进来的
GeoJsonPoint geoJsonPoint = new GeoJsonPoint(gpsAddress.getLongitude(), gpsAddress.getLatitude());
coreCompanyDO.setGpsAddress(geoJsonPoint);
在spring的框架下存储都是没问题的,因为针对GeoJsonPoint内置的对应的converter
private static void registerDeserializersIn(SimpleModule module) {
module.addDeserializer(GeoJsonPoint.class, new GeoJsonPointDeserializer());
module.addDeserializer(GeoJsonMultiPoint.class, new GeoJsonMultiPointDeserializer());
module.addDeserializer(GeoJsonLineString.class, new GeoJsonLineStringDeserializer());
module.addDeserializer(GeoJsonMultiLineString.class, new GeoJsonMultiLineStringDeserializer());
module.addDeserializer(GeoJsonPolygon.class, new GeoJsonPolygonDeserializer());
module.addDeserializer(GeoJsonMultiPolygon.class, new GeoJsonMultiPolygonDeserializer());
}
这段代码在这个类里面
现在出现问题是我们现在是监听mongodb的changestream没有通过spring,手动通过fastJson把json转为对象时出错了,因为在这个过程中没有经过converter。
https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/
你可以使用fastjson2-extension 2.0.4-SNAPSHOT版本验证下
需要加上如下依赖:
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2-extension</artifactId>
<version>2.0.4-SNAPSHOT</version>
</dependency>
public class Issue256 {
@BeforeEach
public void init() {
JSON.register(GeoJsonReaderModule.INSTANCE);
}
@Test
public void test() {
String str = "{\n" +
" \"_id\":\n" +
" {\n" +
" \"$oid\": \"61a591ef96eb001a9437d6c4\"\n" +
" },\n" +
" \"gpsAddress\":\n" +
" {\n" +
" \"type\": \"Point\",\n" +
" \"coordinates\":\n" +
" [\n" +
" 114.027285886961,\n" +
" 22.6741582981732\n" +
" ]\n" +
" }\n" +
"}";
Bean bean = JSON.parseObject(str, Bean.class);
assertNotNull(bean.gpsAddress);
assertEquals(114.027285886961D, bean.gpsAddress.getX());
assertEquals(22.6741582981732D, bean.gpsAddress.getY());
}
public static class Bean {
public GeoJsonPoint gpsAddress;
}
}
Cool 👍 可以了。因为是spring boot的项目,我计划下面的方式添加初始化,不知道有没有更好的方案,请指教哈 @wenshao
@Slf4j
@Component
public class JsonInit implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
JSON.register(GeoJsonReaderModule.INSTANCE);
}
}
@ocean23
最新版本的快照2.0.4-SNAPSHOT中,package从com.alibaba.fastjson2.support.spring.mongodb改为com.alibaba.fastjson2.support.spring.data.mongodb了
https://github.com/alibaba/fastjson2/releases/tag/2.0.4
问题已经在2.0.4版本中修复,请用新版本