Bir nesne dizisinin serisini kaldırmak için Jackson nasıl kullanılır


779

Jackson veri bağlama belgeler Jackson destekler "tüm desteklenen türlerinin Dizileri" deserialising gösterir ama bunun için tam sözdizimi anlamaya olamaz.

Tek bir nesne için bunu yaparım:

//json input
{
    "id" : "junk",
    "stuff" : "things"
}

//Java
MyClass instance = objectMapper.readValue(json, MyClass.class);

Şimdi bir dizi için bunu yapmak istiyorum:

//json input
[{
    "id" : "junk",
    "stuff" : "things"
},
{
    "id" : "spam",
    "stuff" : "eggs"
}]

//Java
List<MyClass> entries = ?

Sihirli bir eksik komutun olup olmadığını bilen var mı? Değilse çözüm nedir?


2
JSON ile uğraşmak için Google'ın GSON kütüphanesini tercih ediyorum. Henüz denemediyseniz kontrol etmeye değer ... onunla çalışmayı çok kolay ve sezgisel hale getirir.
Jesse Webb

11
FWIW Gson ile ilgili bu özel probleme olası çözümler, Jackson'ın Veri Bağlama API'sinde mümkün olanla hemen hemen aynıdır.
Programcı Bruce

17
Gweebz - belki GSON'un neden (Jackson ile karşılaştırıldığında) daha iyi bir seçim olduğunu düşündüğünüzü açıklamak istersiniz?
StaxMan

Yanıtlar:


1656

Önce bir eşleyici oluşturun:

import com.fasterxml.jackson.databind.ObjectMapper;// in play 2.3
ObjectMapper mapper = new ObjectMapper();

Dizi olarak:

MyClass[] myObjects = mapper.readValue(json, MyClass[].class);

Liste Olarak:

List<MyClass> myObjects = mapper.readValue(jsonInput, new TypeReference<List<MyClass>>(){});

Liste türünü belirtmenin başka bir yolu:

List<MyClass> myObjects = mapper.readValue(jsonInput, mapper.getTypeFactory().constructCollectionType(List.class, MyClass.class));

43
Ek bir not, ayrıştırma gibi bir hata JsonMappingException: No suitable constructor found for typealırsanız, sınıfınıza varsayılan bir kurucu eklemeniz gerektiği anlamına gelir, bu benim için sabit bir özel argüman yapıcı ekleyerek.
SyntaxRules

12
@SyntaxRules, açık bir kurucunuz varsa açık kurucu eklemek gerekir - eğer değilse, derleyici otomatik olarak genel "boş" kurucu oluşturur. İyi bir nokta. Başka bir yaygın sorun, iç sınıfların olması gerektiğidir static- aksi takdirde asla sıfır arg yapıcıları yoktur.
StaxMan

244
Btw, List<MyClass> myObjects = Arrays.asList(mapper.readValue(json, MyClass[].class))TypeRefence'dan 10 kata kadar daha hızlı çalışır.

5
Genel tip bir sürüm arıyorum.
Stephane

1
@EugeneTskhovrebov senin yol inlining için en temiz. Diğerleri ise döküm veya beyan gerektirir. Vurgulamak ve size biraz yardımcı olmak için kendi cevabı olarak eklemenizi öneririm.
Erik B

190

Gönderen Eugene Tskhovrebov

List<MyClass> myObjects = Arrays.asList(mapper.readValue(json, MyClass[].class))

Bu çözüm benim için en iyisi gibi görünüyor


Java, Lotus Domino'da Ajanlar ile çalışanlar için bu yol. Diğer çözümlerden bazılarını denedim, ancak her zaman birResourceNotFoundException
John

Bizim için olduğu gibi bu çözüm için yukarıdaki cevabın yorumlarına SyntaxRules eklenmesi gerekebilir. Sadece eklemek istemedim, böylece kaybolmasın.
Rob

2
veyaArrays.asList(Json.fromJson(json.get("fieldName"), MyClass[].class))
Al-Mothafar

3
veyaList<MyClass> myObjects = Arrays.asList(mapper.treeToValue(jsonNode.get("fieldName"), MyClass[].class))
Collin Krawll

@CollinKrawll objectmapper.treetovalue ne yapar?
Eswar

35

Genel Uygulama için:

public static <T> List<T> parseJsonArray(String json,
                                         Class<T> classOnWhichArrayIsDefined) 
                                         throws IOException, ClassNotFoundException {
   ObjectMapper mapper = new ObjectMapper();
   Class<T[]> arrayClass = (Class<T[]>) Class.forName("[L" + classOnWhichArrayIsDefined.getName() + ";");
   T[] objects = mapper.readValue(json, arrayClass);
   return Arrays.asList(objects);
}

4
<T []> Sınıfının güzel yapısı. Bunu hiç görmedim. Bu konuda nereden bilgi buldun?
Roeland Van Heddegem

11

İlk olarak evre güvenliği olan bir ObjectReader örneği oluşturun.

ObjectMapper objectMapper = new ObjectMapper();
ObjectReader objectReader = objectMapper.reader().forType(new TypeReference<List<MyClass>>(){});

Sonra kullanın:

List<MyClass> result = objectReader.readValue(inputStream);

Bu benim sayesinde, arıyorum tam olarak ne
tek başına

biz - com.fasterxml.jackson.databind.JsonMappingException olsun: [Kaynak: java.io.FileInputStream@33fec21; satır: 1, sütun: 1]
Dinesh Kumar

7
try {
    ObjectMapper mapper = new ObjectMapper();
    JsonFactory f = new JsonFactory();
    List<User> lstUser = null;
    JsonParser jp = f.createJsonParser(new File("C:\\maven\\user.json"));
    TypeReference<List<User>> tRef = new TypeReference<List<User>>() {};
    lstUser = mapper.readValue(jp, tRef);
    for (User user : lstUser) {
        System.out.println(user.toString());
    }

} catch (JsonGenerationException e) {
    e.printStackTrace();
} catch (JsonMappingException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

3

Burada, ne olursa olsun pojo (varlık T) json2object veya Object2json dönüştürmek için bir yardımcı programdır

import java.io.IOException;
import java.io.StringWriter;
import java.util.List;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * 
 * @author TIAGO.MEDICI
 * 
 */
public class JsonUtils {

    public static boolean isJSONValid(String jsonInString) {
        try {
            final ObjectMapper mapper = new ObjectMapper();
            mapper.readTree(jsonInString);
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    public static String serializeAsJsonString(Object object) throws JsonGenerationException, JsonMappingException, IOException {
        ObjectMapper objMapper = new ObjectMapper();
        objMapper.enable(SerializationFeature.INDENT_OUTPUT);
        objMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        StringWriter sw = new StringWriter();
        objMapper.writeValue(sw, object);
        return sw.toString();
    }

    public static String serializeAsJsonString(Object object, boolean indent) throws JsonGenerationException, JsonMappingException, IOException {
        ObjectMapper objMapper = new ObjectMapper();
        if (indent == true) {
            objMapper.enable(SerializationFeature.INDENT_OUTPUT);
            objMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        }

        StringWriter stringWriter = new StringWriter();
        objMapper.writeValue(stringWriter, object);
        return stringWriter.toString();
    }

    public static <T> T jsonStringToObject(String content, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
        T obj = null;
        ObjectMapper objMapper = new ObjectMapper();
        obj = objMapper.readValue(content, clazz);
        return obj;
    }

    @SuppressWarnings("rawtypes")
    public static <T> T jsonStringToObjectArray(String content) throws JsonParseException, JsonMappingException, IOException {
        T obj = null;
        ObjectMapper mapper = new ObjectMapper();
        obj = mapper.readValue(content, new TypeReference<List>() {
        });
        return obj;
    }

    public static <T> T jsonStringToObjectArray(String content, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException {
        T obj = null;
        ObjectMapper mapper = new ObjectMapper();
        mapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        obj = mapper.readValue(content, mapper.getTypeFactory().constructCollectionType(List.class, clazz));
        return obj;
    }

0

ayrıca, aşağıdakileri içeren bir sınıf da oluşturabilirsiniz ArrayList:

public static class MyList extends ArrayList<Myclass> {}

ve sonra şöyle kullanın:

List<MyClass> list = objectMapper.readValue(json, MyList.class);

0

Bu cevabı kullanamadım çünkü linter'ım kontrolsüz dökümlere izin vermiyor.

İşte kullanabileceğiniz bir alternatif. Aslında daha temiz bir çözüm olduğunu hissediyorum.

public <T> List<T> parseJsonArray(String json, Class<T> clazz) throws JsonProcessingException {
  var tree = objectMapper.readTree(json);
  var list = new ArrayList<T>();
  for (JsonNode jsonNode : tree) {
    list.add(objectMapper.treeToValue(jsonNode, clazz));
  }
  return list;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.