#java #json #serialization #jackson
#java #json #сериализация #джексон
Вопрос:
Я пытаюсь сериализовать список отдельных объектов JSON, разделенных запятой, в какую-либо коллекцию на Java с использованием Jackson.
Правильно ли я понимаю, что это возможно только с использованием пользовательского картографа из-за того, как представлен JSON?
Ввод JSON:
{"_1":"186","_3":"In Stock"},{"_1":"187","_3":"In Stock"},{"_1":"188","_3":"In Stock"},{"_1":"189","_3":"In Stock"}
POJO
public class StockInfo {
private String _1;
private String _3;
@JsonProperty("_1")
public String get_1() {
return _1;
}
@JsonProperty("_1")
public void set_1(String _1) {
this._1 = _1;
}
@JsonProperty("_3")
public String get_3() {
return _3;
}
@JsonProperty("_3")
public void set_3(String _3) {
this._3 = _3;
}
}
Сериализация
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, true);
List<StockInfo> stockList = objectMapper.readValue(resultInputStream, new TypeReference<List<StockInfo>>(){});
Комментарии:
1. Что происходит при запуске кода?
2. Ваша входная строка должна быть массивом JSON (добавляйте
[
в начале и]
в конце).3. @lugiorgi @lugiorgi
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.util.ArrayList<com.domain.StockInfo> out of START_OBJECT token at [Source: (com.amazonaws.services.s3.model.SelectRecordsInputStream); line: 1, column: 1]
Ответ №1:
Джексон не сможет проанализировать это, поскольку это просто недопустимый формат JSON, если, например, объекты JSON не были в массиве JSON:
[{"_1":"186","_3":"In Stock"},{"_1":"187","_3":"In Stock"},{"_1":"188","_3":"In Stock"},{"_1":"189","_3":"In Stock"}]
Если у вас нет контроля над форматом, в котором вы получаете свои данные, вы можете просто заключить строку псевдо-JSON в квадратные скобки, превратив ее в массив JSON:
// Wrap the pseudo-JSON string in square brackets, making it a JSON array
String jsonArray = "[" pseudoJson "]";
// Parse like you intended
List<StockInfo> stockList = objectMapper.readValue(jsonArray, new TypeReference<>() {});
Или вы могли бы разделить строку, а затем попытаться проанализировать каждый объект по отдельности:
// Split the pseudo-JSON string at commas preceded by a closing curly bracket
String[] jsonObjects = pseudoJson.split("(?<=}),");
// Parse each JSON object to a StockInfo instance and add it to a List
List<StockInfo> stockList = new ArrayList<>();
for(String jsonObject : jsonObjects) {
StockInfo stockInfo = objectMapper.readValue(jsonObject, new TypeReference<>() {});
stockList.add(stockInfo);
}
Самое близкое, что предлагает Джексон DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY
, но в вашем случае вы получите только первый элемент.
Комментарии:
1. спасибо, я думал, что это будет так, я думал о том, чтобы заключить JSON в скобки, чтобы его можно было сериализовать, но результат возвращается как InputStream, и я бы предпочел не преобразовывать его в строку из-за размера результата. Я предполагаю, что это невозможно сделать, пока результатом является InputStream?