项目场景:
在处理json字符串时,遇到需要将标准格式的json转换为对应的JavaBean,因此进行如下尝试:
JSON字符串如下:
{
"uid": "4210030030001409999",
"city": "荆州市",
"geom": "{\"type\":\"Point\",\"coordinates\":[112.14885956,30.348678684]}",
"road": "九阳大道北",
"address": "湖北省荆州市荆州区九阳大道北16号",
"district": "荆州区",
"province": "湖北省",
"township": "城南街道",
"doorplate": 16,
"doorplate_sub": null
}
JavaBean如下:
@Data
public class DoorPlateElement implements Serializable {
private String uid;
private String address;
private String province;
private String city;
private String district;
private String road;
private String township;
private Integer doorplate;
private Integer doorplate_sub;
private String geom;
}
JavaBean结构和JSON是一一对应的。
使用工具
pom.xml依赖:
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
引用:
import net.sf.json.JSONObject;
代码:
使用JSONObject.toBean方法,将json字符串转为DoorPlateElement类。
JSONObject jsonObject = JSONObject.fromObject(jsonString);
DoorPlateElement doorPlateElement = (DoorPlateElement) JSONObject.toBean(jsonObject,DoorPlateElement.class);
System.out.println(doorPlateElement.getGeom());
报错:
java.lang.NoSuchMethodException: Unknown property ‘coordinates’ on class ‘class java.lang.String’
问题分析
:
报错在于json字符串中geom下有两层的json嵌套,但是在javabean中设置的格式为String,造成不匹配,因此需要修改javabean结构,改为JSONObject
或者Object
均可,考虑到后续空间数据入库一致性,这里修改geom
为Object
格式。
修改后JavaBean如下:
@Data
public class DoorPlateElement implements Serializable {
private String uid;
private String address;
private String province;
private String city;
private String district;
private String road;
private String township;
private Integer doorplate;
private Integer doorplate_sub;
private Object geom;
}
修改后输出,可以实现get()和set()
读写,但是读取geom属性时候,这里的geom为对象,需要转为字符串进行下一步入库。
因此,使用函数:
JSONObject.fromObject(doorPlateElement.getGeom())
输出:
发现新问题
:
JSONObject输出的浮点型精度损失严重,对于坐标串来说无法接受,因此需要新方法重新实现。
解决方法:
使用谷歌提供的json包gson解决
pom.xml依赖:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
引用:import com.google.gson.Gson;
代码:
DoorPlateElement doorPlateElement = new Gson().fromJson(jsonString.toString(), DoorPlateElement.class);
该方法输出的geom结果直接为原样的json字符串,不需要额外转换,可以直接使用。并且精度没有损失。
补充:JavaBean转JSON
补充1:Gson()转换java对象到JSON
Gson().toJson()方法
Gson gson =new Gson();
User user = new User(123,"hhhh");
String str = gson.toJson(user);
System.out.println(str);
补充2:JSONObject()转换java对象到JSON
Java对象->String类型->JSONObject
User user = new User(123,"hhhh");
String jsonString= JSONObject.toJSONString(user);
JSONObject jsonObject=JSONObject.parseObject(jsonString);
System.out.println(jsonObject);
java对象直接转JSONObject
User user = new User(123,"hhhh");
JSONObject jsonObject= (JSONObject) JSONObject.toJSON(user);
System.out.println(jsonObject);