【问题标题】:Could not write JSON: Direct self-reference leading to cycle无法编写 JSON:直接自引用导致循环
【发布时间】:2020-01-17 05:08:36
【问题描述】:

收到此错误:

嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:直接 自引用导致循环(通过引用链: com.google.gson.JsonObject["asJsonObject"])

尝试这样做时:

 restTemplate.postForObject(url_final, convertedObject, Object[].class);

其中convertedObjectJSONObjecturlfinalString 网址。

有效载荷是:

"data" : [
  {"FILENAME":"EEC1.TXT",
   "ERRORDESCRIPTION":"FTD-07-INVALID CHARACTER FOUND IN THE FILE.",
   "LINENO":3},
  {"FILENAME":"SEC1.TXT",
   "ERRORDESCRIPTION":"26-FTD-07-INVALID CHARACTER FOUND IN THE FILE.",
    "LINENO":447}]

我的代码:

JSONObject output = new JSONObject(payload);
JSONArray jsonArray = output.getJSONArray("data");
JSONObject objects = jsonArray.getJSONObject(0);
String fileName = objects.getString("FILENAME");
int lineNumber = objects.getInt("LINENO");
String errordesc = objects.getString("ERRORDESCRIPTION");
String tempor = "{\"activityType\": \"trial.start\",\"aFileName\":\""  
              + fileName
              + "\",\"aLINENO\": \""
              + lineNumber
              + "\",\"aREFNO\": \"" 
              + TxnNo
              + "\",    \"aERRORDESCRIPTION\": \""+errordesc+"\"}";
JsonObject convertedObject = new Gson().fromJson(tempor, JsonObject.class);
restTemplate.postForObject(url_final, convertedObject, Object[].class);

【问题讨论】:

  • 你累的可以在这里添加代码sn-p吗
  • @DulajKulathunga :已添加。您现在可以查看吗?
  • 请包括完整的堆栈跟踪,而不仅仅是消息。
  • 异常消息和您的代码不相加。异常表明您正在使用 Jackson (com.fasterxml.jackson...) 而您的代码正在使用 Gson (new Gson())。你为什么要把两者混在一起?一般来说,您不应该将通用的 JsonObject 传递给不了解这些实现的解析器/格式化程序 - 而且 Jackson 和 Gson 不会知道彼此的类。
  • 为什么要手动创建 JSON,然后首先对其进行解析和重新序列化?你为什么不使用适当的 pojo 或至少一个然后被序列化的地图?

标签: java json jackson gson resttemplate


【解决方案1】:

在十行中,您混合了 3 个不同的 JSON 库:

  • JSONObject 来自org.json
  • Gson 来自 Google 的 gson
  • restTemplate 在幕后使用Jackson

您应该跳过前两个并仅使用Jackson。更改后的上述代码可能如下所示:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;

....

ObjectMapper mapper = JsonMapper.builder().build();

JsonNode output = mapper.readTree(payload);

ArrayNode jsonArray = (ArrayNode)output.get("data");
JsonNode objects = jsonArray.get(0);
String fileName = objects.get("FILENAME").asText();
int lineNumber = objects.get("LINENO").asInt();
String errordesc = objects.get("ERRORDESCRIPTION").asText();
String tempor = "{\"activityType\": \"trial.start\",\"aFileName\":\""
        + fileName
        + "\",\"aLINENO\": \""
        + lineNumber
        + "\",\"aREFNO\": \""
        + TxnNo
        + "\",    \"aERRORDESCRIPTION\": \""+errordesc+"\"}";
JsonNode convertedObject = mapper.readTree(tempor);

2.10.0 版本开始,您可以使用JsonMapper.builder().build(),但在以前的版本中,您可以通过new ObjectMapper() 创建新实例,这也很好。

【讨论】:

  • 通过这些修改,我们可以像上面一样使用 restTemplate.postForObject 了吗?
  • @Thira,是的,在代码的最后加上 restTemplate.postForObject(url_final, convertedObject, Object[].class); 行。
  • Ziober,我在尝试时遇到此错误:无法解析导入 com.fasterxml.jackson.databind.json.JsonMapper
  • @Thira,这就是为什么我写了你可以创建实例 ObjectMapper mapper = new ObjectMapper(); 并删除 import com.fasterxml.jackson.databind.json.JsonMapper; 行。
  • @Ziober :修复了问题。谢谢。
猜你喜欢
  • 2017-07-27
  • 1970-01-01
  • 2018-01-24
  • 1970-01-01
  • 2018-04-10
  • 1970-01-01
  • 2021-08-28
  • 2018-11-27
  • 1970-01-01
相关资源
最近更新 更多