使用fastjson需要注意的事项

       最近在测试举报项目的单聊和群聊时,出现了"$ref": "$.data.reportContent[0].feedInfo"这样的数据,之所以出现这样的问题是因为fastjson的JSON.toJSONString默认开启了"循环引用检测"特性,加载完第一个feedInfo对象后,当加载第二个feedInfo对象时fastjson检测到已经加载过该对象一次了,因此不再重复加载改数据,而只是将一个指向第一个feedInfo对象的地址赋给后面的对象,从而出现了我们看到的下面所示的数据形式。

{
    "data": {
        "handleDetail": {
            
        },
        "handleFeedId": "",
        "handleReason": "",
        "handleTime": 0,
        "hasHandled": 0,
        "illegalType": "0",
        "pics": [
            "http://scloud.toon.mobi/f/AIvQq8lwlGH4snhbwyu7Ndib5WbC-9AS4xAiApe+WUofG.jpg"
        ],
        "reasonId": "16",
        "reportContent": [
            {
                "contentOutput": {
                    "from": "c_1500459436330003",
                    "text": "不支持的文件类型",
                    "type": "nonsupport",
                    "url": "http://scloud.toon.mobi/f/0T-Org7zsW6A6+V9jKji2JxevaI8ixWW4ht4nZ6ArZcfG.jpg"
                },
                "feedInfo": {
                    "cardNo": "253607",
                    "feedId": "c_1500459436330003",
                    "title": "***"
                }
            },
            {
                "contentOutput": {
                    "from": "c_1500459436330003",
                    "text": "不支持的文件类型",
                    "type": "nonsupport"
                },
                "feedInfo": {
                    "$ref": "$.data.reportContent[0].feedInfo"
                }
            }
        ],
        "reportDesc": "",
        "reportId": "1157163647988614",
        "reportObject": "群聊",
        "reportPerson": [
            {
                "$ref": "$.data.reportContent[0].feedInfo"
            }
        ],
        "reportTime": 1516364798614,
        "toonType": "100",
        "type": 4
    },
    "meta": {
        "code": 0,
        "message": "success"
    }
}

为了避免这种现象发生,我们在使用JSON.toJSONString时需要人为关闭"循环引用检测"特性:

String data = JSON.toJSONString(result, SerializerFeature.DisableCircularReferenceDetect);
这样便可以解决该问题了。

<think>好的,我现在需要帮助用户将给定的JSON字符串使用FastJSON2库转换为Java集合或对象列表。用户之前提供的JSON结构包含两个产品条目,每个条目有多个字段,其中一些字段是嵌套的,比如product_rating和groups。用户之前的问题中已经提到了使用Jackson库的方法,但现在用户希望改用FastJSON2,所以需要参考之前的引用内容,特别是引用[1]和[3]中的FastJSON示例。首先,我需要确认用户提供的JSON结构。用户给出的JSON顶层是一个包含"hits"键的对象,而"hits"的值是一个数组,里面包含两个产品对象。每个产品对象有多个属性,比如offer_code、sku、brand、price等,其中有些属性是对象或数组,例如product_rating是一个包含best_rating、count、value的对象,groups是一个包含group_code和count的对象的数组。接下来,用户的需求是将这个JSON字符串转换为Java中的集合或对象列表。使用FastJSON2的话,需要用到JSON.parseObject或JSON.parseArray方法。根据引用[1]中的示例,当解析列表时,可以使用TypeReference来指定类型,如List<Map<String, Object>>。但用户可能更倾向于使用具体的Java对象而是Map,这样更便于后续处理,尤其是当JSON结构较复杂时。 因此,我需要考虑两种方法:一种是直接解析为List<Map<String, Object>>,另一种是创建对应的Java类,然后解析为List<Product>。根据引用[3]中的例子,当解析复杂JSON时,推荐使用对象映射的方式,即先定义Java类结构,然后使用JSON.parseArray或JSON.parseObject进行转换。这样代码更清晰,也更容易维护。 首先,针对直接解析为Map的方式,用户提供的引用[1]中已经展示了如何将字符串转换为List<Map<String,Object>>,使用JSON.parseObject配合TypeReference。但需要注意FastJSON2的TypeReference用法可能与Jackson同,需要确认正确的语法。其次,如果用户希望转换为对象列表,需要创建对应的Java类。例如,定义一个Product类,包含所有字段,包括嵌套对象如ProductRating和Group。这样,可以使用JSON.parseArray方法直接将JSON数组转换为List<Product>。引用[3]中的例子使用JSON.parseArray来处理复杂JSON,并转换为UserGroup对象的列表,这应该适用于当前情况。 接下来,需要处理嵌套对象和数组。例如,product_rating字段对应的是一个ProductRating类,groups字段对应的是Group类的列表。在Java类中,这些字段需要声明为对应的对象类型或列表类型,FastJSON2会自动进行嵌套对象的转换。然后,需要验证用户提供的JSON结构是否正确。用户给出的JSON中,"hits"是一个数组,但整个JSON结构是一个对象,包含"hits"键。因此,正确的解析方式应该是先解析整个JSON对象,然后提取"hits"数组。例如,先使用JSON.parseObject解析整个字符串为一个Map,然后获取"hits"对应的值,这个值是一个List,再进一步处理。或者,可以创建一个顶层的Response类,包含一个List<Product>类型的hits字段,然后使用JSON.parseObject将整个JSON字符串解析为Response对象,从而直接获取hits列表。这种方式更结构化,推荐使用。最后,需要编写示例代码,展示这两种方法:使用Map的方式和使用对象映射的方式。同时,需要处理可能的异常,比如JSON格式错误,或者字段匹配的情况。引用[1]中还提到了增删改操作,但用户当前的问题主要集中在解析,所以可能需要涉及这些部分。 总结步骤:1.添加FastJSON2依赖。2.创建对应的Java类结构(如Response、Product、ProductRating、Group)。3.使用JSON.parseObject或JSON.parseArray进行解析。4.处理嵌套对象和数组。5.提供示例代码和注意事项,如处理异常、字段匹配等。</think>使用FastJSON2将JSON字符串转换为Java集合的完整实现步骤如下: ### 一、添加Maven依赖 ```xml <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.34</version> </dependency> ``` ### 二、两种解析方式对比 #### 方式1:直接解析为泛型集合 ```java import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.TypeReference; public class JsonParser { public static void parseWithMap(String jsonStr) { // 先解析顶层对象 Map<String, Object> root = JSON.parseObject(jsonStr); // 获取hits数组 List<Map<String, Object>> hits = (List<Map<String, Object>>) root.get("hits"); // 遍历处理嵌套对象 for (Map<String, Object> item : hits) { Map<String, Object> rating = (Map<String, Object>) item.get("product_rating"); System.out.println(rating.get("value")); // 输出4.8 } } } ``` #### 方式2:对象映射(推荐) 1. 定义实体类: ```java public class ProductResponse { private List<Product> hits; // getter/setter } public class Product { private String offer_code; private String sku; private ProductRating product_rating; private List<Group> groups; // getter/setter } public class ProductRating { private int best_rating; private int count; private double value; // getter/setter } public class Group { private int count; private String group_code; // getter/setter } ``` 2. 解析代码: ```java ProductResponse response = JSON.parseObject(jsonStr, ProductResponse.class); List<Product> products = response.getHits(); // 访问嵌套数据示例 products.get(0).getProduct_rating().getValue(); // 返回4.8 products.get(0).getGroups().get(0).getGroup_code(); // 返回"colour" ``` ### 三、特殊字段处理 #### 处理日期字段 ```java public class Product { @JSONField(format = "yyyy-MM-dd HH:mm:ss") private Date createTime; } ``` #### 处理JSON数组 ```java // 直接解析数组 String hitsArrayStr = JSON.parseObject(jsonStr).getJSONArray("hits").toJSONString(); List<Product> products = JSON.parseArray(hitsArrayStr, Product.class); ``` ### 四、性能优化建议 1. 开启`JSONFactory.setCacheSymbols(true)`启用符号缓存[^3] 2. 对频繁解析的类使用`JSON.register()`预注册 3. 避免在循环中重复创建`TypeReference`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值