Можно ли сериализовать разделенный запятыми список отдельных объектов JSON в коллекцию на Java?

#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?