Я знаю, что есть похожие сообщения, похожие на это, но я не нашел ни одного, помогающего найти решение для этого конкретного случая.
Я пытаюсь вернуть HashMap<String, Object>
из моего контроллера. Часть Object
- это строка JSON, но ее двойная сериализация и не возвращается в виде строки JSON, поэтому она не заканчивается лишними цитатами и escape-символами.
Функция контроллера:
@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, который будет возвращен в ответ heartbeat.
Но каждый раз, когда я запускаю это, мой вывод выглядит так:
{
"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 ответа
Вместо того, чтобы возвращать 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
Джексон будет сериализовать строку как есть. Дополнительную информацию см. На странице https://www.baeldung.com/jackson-annotations .
streamCursorInfo - это строка, а не объект => сериализация приведет к «символу».
Если вы можете вернуть объект, содержащий данные, он будет работать из коробки. Если у вас есть только строка, я предлагаю сериализовать ее в JsonNode и добавить ее в ваш ответ
ObjectMapper objectMapper = new ObjectMapper();
JsonNode streamCursorInfo = objectMapper.readTree(service.getStreamInfo())
results.put("streamCursorInfo", streamCursorInfo);