Json序列化时重复引用、循环引用的问题

更新时间:2023-07-25 21:04:04 阅读:21 评论:0

Json序列化时重复引⽤、循环引⽤的问题在项⽬中,⽤JSONObject.parArray(str, A.class)对Json字符串进⾏转换时,报以下错误:com.alibaba.fastjson.JSONException: parInt error, field : $ref
通过排查是循环引⽤/重复引⽤导致,问题复现:
1. Ur实体类
tity;
import java.util.List;
import java.util.Map;
public class Ur {
private String name;
private int age;
private List<Order> orders;
private Map<String, Object> map;
public String getName(){
return name;
}
public void tName(String name){
ted熊this.name = name;
}
public int getAge(){
return age;
}
public void tAge(int age){
this.age = age;
}怀疑英语
public List<Order>getOrders(){
return orders;
}
public void tOrders(List<Order> orders){
}
public Map<String, Object>getMap(){绵薄之力什么意思
return map;
}
public void tMap(Map<String, Object> map){
wonderwall什么意思
this.map = map;
}
}
2. Order实体类
tity;
import java.util.List;
public class Order {
private String id;
private String productName;
private Ur ur;
耆宿
public String getId(){
return id;
}
public void tId(String id){
this.id = id;
}
public String getProductName(){
return productName;
}
public void tProductName(String productName){
this.productName = productName;
}
public Ur getUr(){
return ur;
}
public void tUr(Ur ur){
this.ur = ur;
}
}
重复引⽤:某属性被多次设置值
;
电话营销开场白
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.rializer.ValueFilter;
import java.io.IOException;
import java.util.*;
public class A {
public static void main(String[] args)throws IOException {
Order order1 =new Order();
order1.tId("1");
order1.tProductName("iPhone");
Order order2 =new Order();
order2.tId("2");
order2.tProductName("iPad");
Ur ur =new Ur();
ur.tName("张三");
ur.tAge(23);
List<Order> orders =new ArrayList<Order>();
orders.add(order1);
orders.add(order1);
orders.add(order2);
ur.tOrders(orders);
Map<String, Object> map =new HashMap<String, Object>();
map.put("orders", orders);
String urStr = JSONString(ur);
System.out.println(urStr);
}
}
可以看到上⾯代码22、23⾏,25、28⾏共两处重复引⽤,打印结果为:
{
"age":23,
"name":"张三",
"orders":[{
"id":"1",
"productName":"iPhone"
},{
"$ref":"$.orders[0]"
only怎么读
},{
"id":"2",
"productName":"iPad"
}]
}
解决⽅法:
⽅案1:采⽤FastJson特性,JSONString(ur, SerializerFeature.DisableCircularReferenceDetect)
⽅案2:如果orders在业务中不需要被序列化,可以在实体类属性上加@JSONField(rialize=fal)注解-FastJson特性或transient属性-Java特性
⽅案3:在序列化时传⼊SerializeFilter接⼝实现对属性值进⾏属性过滤或值替换
String s = JSONString(ur,new ValueFilter(){
@Override
public Object process(Object o, String s, Object o1){
if(s.equals("orders")){
return"";
}
return o1;
}
});
⽅案4:使⽤Gson实现⽅案3类似效果
Gson gson =new GsonBuilder()
.addSerializationExclusionStrategy(new ExclusionStrategy(){
@Override
public boolean shouldSkipField(FieldAttributes f){
if("orders".Name()))return true;//排除count
return fal;
}
@Override
public boolean shouldSkipClass(Class<?> clazz){
// 直接排除某个类,return true为排除
return fal;
}
romantic是什么意思})
.
create();
String s = Json(ur);
⽅案5:对数据进⾏转换,new ⼀个新对象,然后赋值
⽅案6:产⽣这类问题的原因⼤多是代码逻辑问题,可以尽可能避免这类问题
循环引⽤:对象内部存在相互引⽤
;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.rializer.ValueFilter;
import java.io.IOException;
import java.util.*;
orgasm是什么意思public class A {
public static void main(String[] args)throws IOException {
Order order1 =new Order();
order1.tId("1");
order1.tProductName("iPhone");
Order order2 =new Order();
order2.tId("2");
order2.tProductName("iPad");
Ur ur =new Ur();
ur.tName("张三");
ur.tAge(23);
order1.tUr(ur);
List<Order> orders =new ArrayList<Order>();
orders.add(order1);
orders.add(order2);
ur.tOrders(orders);
Map<String, Object> map =new HashMap<String, Object>();
map.put("orders", orders);
String urStr = JSONString(ur);
System.out.println(urStr);
}
}
可以看到20⾏,order引⽤了ur,打印结果为:
{
"age":23,
"name":"张三",
"orders":[{
"id":"1",
"productName":"iPhone",
"ur":{
"$ref":"$"
}
},{
"id":"2",
"productName":"iPad"
}]
}
margaret thatcher这时采⽤JSONString(ur, SerializerFeature.DisableCircularReferenceDetect)来序列化会出现如下异常:
引⽤检测是FastJson提供的⼀种避免运⾏时异常的优良机制,如果关闭它会有很⼤可能导致循环引⽤时发⽣StackOverflowError异常。这也是FastJson默认开启引⽤检测的原因
Exception in thread "main" java.lang.StackOverflowError
at com.alibaba.fastjson.rializer.SerializeWriter.writeFieldValue(SerializeWriter.java:1746)
at com.alibaba.fastjson.rializer.ASMSerializer_1_Ur.writeDirectNonContext(Unknown Source)
at com.alibaba.fastjson.rializer.ASMSerializer_2_Order.writeDirectNonContext(Unknown Source)
at com.alibaba.fastjson.rializer.ASMSerializer_1_Ur.writeDirectNonContext(Unknown Source)
at com.alibaba.fastjson.rializer.ASMSerializer_2_Order.writeDirectNonContext(Unknown Source)
解决⽅法:
采⽤重新引⽤解决⽅法⾥的⽅案2、3、4、5、6,也可在反序列化前将JSONString中对应的字符串特殊处理掉。

本文发布于:2023-07-25 21:04:04,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/1117007.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:属性   问题   序列化   循环   字符串   检测
相关文章
留言与评论(共有 0 条评论)
昵称:
匿名发表 登录账号
         
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图