春季-返回原始JSON而无需双重序列化

时间:2018-10-04 18:16:14

标签: json spring-mvc spring-boot jackson

我知道还有其他与此类似的帖子,但是我没有找到任何可以帮助我找到此特定案例的解决方案的帖子。

我正在尝试从控制器中返回HashMap<String, Object>Object部分是JSON字符串,但已对其进行了双重序列化,并且未作为原始JSON字符串返回,因此不会以多余的引号和转义字符结尾。

控制器功能:

@RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public HashMap<String, Object> heartbeat(){
    String streamInfo = service.getStreamInfo();
    String streamCursorInfo = service.getStreamCursorInfo();
    String topicInfo = service.getTopicInfo();

    String greeting = "This is a sample app for using Spring Boot with MapR Streams.";

    HashMap<String, Object> results = new HashMap();
    results.put("greeting", greeting);
    results.put("streamInfo", streamInfo);
    results.put("streamCursorInfo", streamCursorInfo);
    results.put("topicInfo", topicInfo);

    return results;
}

服务功能:

private String performCURL(String[] command){
    StringBuilder stringBuilder = new StringBuilder();

    try{
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        Process p = processBuilder.start();

        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = null;
        while((line = reader.readLine()) != null){
            stringBuilder.append(line);
        }
    }
    catch(Exception e){
        LOGGER.error(ExceptionUtils.getRootCauseMessage(e));
    }

    return stringBuilder.toString();
}

我运行的cURL命令已经返回了原始JSON字符串。所以我只是试图将其添加到HashMap中以在心跳响应中返回。

但是每次运行此命令时,我的输出如下:

{
"greeting": "This is a sample app for using Spring Boot with MapR Streams.",
"streamCursorInfo": "{\"timestamp\":1538676344564,\"timeofday\":\"2018-10-04 02:05:44.564 GMT-0400 PM\",\"status\":\"OK\",\"total\":1,\"data\":[{\"consumergroup\":\"MapRDBConsumerGroup\",\"topic\":\"weightTags\",\"partitionid\":\"0\",\"produceroffset\":\"44707\",\"committedoffset\":\"10001\",\"producertimestamp\":\"2018-10-03T05:57:27.128-0400 PM\",\"consumertimestamp\":\"2018-09-21T12:35:51.654-0400 PM\",\"consumerlagmillis\":\"1056095474\"}]}",
...
}

如果我仅返回单个字符串,例如streamInfo,则它可以正常工作,并且不会添加多余的引号和转义字符。

有人能解释我为防止这种双重序列化而缺失或需要做什么吗?

2 个答案:

答案 0 :(得分:1)

创建如下对象,而不是返回HashMap

public class HeartbeatResult {
  private String greeting;
  ... //other fields here

  @JsonRawValue
  private String streamCursorInfo;

  ... //getters and setters here (or make the object immutable by having just a constructor and getters)
}

使用@JsonRawValue,Jackson将按原样对字符串进行序列化。有关更多信息,请参见https://www.baeldung.com/jackson-annotations

答案 1 :(得分:0)

streamCursorInfo是一个字符串,不是对象=>序列化将转义“字符。

如果您能够返回包含数据的对象,那么它将立即可用。如果您只有一个String,我建议将其序列化为JsonNode并将其添加到您的响应中

ObjectMapper objectMapper = new ObjectMapper();

JsonNode streamCursorInfo = objectMapper.readTree(service.getStreamInfo())

results.put("streamCursorInfo", streamCursorInfo);