Konversi data JSON ke objek Java

262

Saya ingin dapat mengakses properti dari string JSON dalam metode tindakan Java saya. String tersedia hanya dengan mengatakan myJsonString = object.getJson(). Di bawah ini adalah contoh bentuk string:

{
    'title': 'ComputingandInformationsystems',
    'id': 1,
    'children': 'true',
    'groups': [{
        'title': 'LeveloneCIS',
        'id': 2,
        'children': 'true',
        'groups': [{
            'title': 'IntroToComputingandInternet',
            'id': 3,
            'children': 'false',
            'groups': []
        }]
    }]
}

Dalam string ini setiap objek JSON berisi larik objek JSON lainnya. Tujuannya adalah untuk mengekstrak daftar ID di mana objek tertentu yang memiliki properti grup yang berisi objek JSON lainnya. Saya melihat Google Gson sebagai plugin JSON potensial. Adakah yang bisa menawarkan beberapa bentuk panduan tentang bagaimana saya dapat menghasilkan Java dari string JSON ini?

Faiyet
sumber

Jawaban:

329

Saya melihat Google Gson sebagai plugin JSON potensial. Adakah yang bisa menawarkan beberapa bentuk panduan tentang bagaimana saya dapat menghasilkan Java dari string JSON ini?

Google Gson mendukung obat generik dan kacang bersarang. Dalam []JSON mewakili array dan harus memetakan ke koleksi Java seperti Listatau hanya array Java biasa. Dalam {}JSON mewakili objek dan harus memetakan ke Jawa Mapatau hanya beberapa kelas JavaBean.

Anda memiliki objek JSON dengan beberapa properti yang groupspropertinya mewakili array objek bersarang dengan tipe yang sama. Ini dapat diuraikan dengan Gson dengan cara berikut:

package com.stackoverflow.q1688099;

import java.util.List;
import com.google.gson.Gson;

public class Test {

    public static void main(String... args) throws Exception {
        String json = 
            "{"
                + "'title': 'Computing and Information systems',"
                + "'id' : 1,"
                + "'children' : 'true',"
                + "'groups' : [{"
                    + "'title' : 'Level one CIS',"
                    + "'id' : 2,"
                    + "'children' : 'true',"
                    + "'groups' : [{"
                        + "'title' : 'Intro To Computing and Internet',"
                        + "'id' : 3,"
                        + "'children': 'false',"
                        + "'groups':[]"
                    + "}]" 
                + "}]"
            + "}";

        // Now do the magic.
        Data data = new Gson().fromJson(json, Data.class);

        // Show it.
        System.out.println(data);
    }

}

class Data {
    private String title;
    private Long id;
    private Boolean children;
    private List<Data> groups;

    public String getTitle() { return title; }
    public Long getId() { return id; }
    public Boolean getChildren() { return children; }
    public List<Data> getGroups() { return groups; }

    public void setTitle(String title) { this.title = title; }
    public void setId(Long id) { this.id = id; }
    public void setChildren(Boolean children) { this.children = children; }
    public void setGroups(List<Data> groups) { this.groups = groups; }
    
    public String toString() {
        return String.format("title:%s,id:%d,children:%s,groups:%s", title, id, children, groups);
    }
}

Cukup sederhana, bukan? Hanya memiliki JavaBean yang cocok dan panggilan Gson#fromJson().

Lihat juga:

BalusC
sumber
4
Penampil? Sudahkah Anda mengukurnya? Sementara GSON memiliki set fitur yang masuk akal, saya pikir kinerja adalah semacam titik lemah (sesuai [ cowtowncoder.com/blog/archives/2009/09/entry_326.html] ) Sebagai contoh: Saya pikir GSON tidak benar-benar membutuhkan setter, dan didasarkan pada bidang. Jadi kode bisa disederhanakan sedikit.
StaxMan
3
Saya menggunakannya di aplikasi android. Ini bukan solusi tercepat yang mungkin tetapi cukup sederhana untuk memprogram untuk membenarkan kurangnya kinerja bagi pengguna sampai sekarang. Mungkin dalam versi aplikasi yang lebih lama, itu akan dihapus untuk solusi yang lebih cepat.
Janusz
1
Kecepatan Wrt, jika cukup cepat, cukup cepat. Saya baru saja berkomentar tentang kinerja yang diharapkan baik. Fitur-set bijaksana Jackson menangani semua bersarang, layering, generik yang sama, sehingga bukan dari mana perbedaan kecepatan berasal. Memiliki getter dan setter tidak memengaruhi kinerja dengan cara yang terukur (untuk paket yang saya ketahui), jadi pasti dapat memilikinya di sana.
StaxMan
97
+1 untuk "package com.stackoverflow.q1688099;". Entah kenapa itu membuatku tertawa.
GargantuChet
1
public String toString () {return new Gson (). toJson (this); // Gunakan ini alih-alih menulis setiap variabel}
Prakash
45

Bewaaaaare dari Gson! Ini sangat keren, sangat hebat, tetapi yang kedua Anda ingin melakukan apa pun selain objek sederhana, Anda bisa dengan mudah perlu mulai membangun serializers Anda sendiri (yang tidak terlalu sulit).

Juga, jika Anda memiliki larik Objek, dan Anda membatalkan beberapa json ke dalam larik Objek, jenis sebenarnya HILANG! Objek penuh bahkan tidak akan disalin! Gunakan XStream .. Yang, jika menggunakan jsondriver dan mengatur pengaturan yang tepat, akan menyandikan tipe jelek ke json yang sebenarnya, sehingga Anda tidak kehilangan apa pun. Harga kecil untuk dibayar (jelek json) untuk serialisasi yang benar.

Perhatikan bahwa Jackson memperbaiki masalah ini, dan lebih cepat daripada GSON.

Jor
sumber
2
Saya telah menulis garpu Gson yang memperbaiki masalah ini (dan menghindari semua anotasi Jackson): github.com/winterstein/flexi-gson
Daniel Winterstein
26

Anehnya, satu-satunya prosesor JSON yang layak disebutkan sejauh ini adalah GSON.

Berikut ini pilihan yang lebih baik:

  • Jackson ( Github ) - pengikatan data yang kuat (JSON ke / dari POJOs), streaming (sangat cepat), model pohon (nyaman untuk akses yang tidak diketik)
  • Flex-JSON - serialisasi yang sangat dapat dikonfigurasi

EDIT (Agustus / 2013):

Satu lagi untuk dipertimbangkan:

  • Genson - fungsionalitas yang mirip dengan Jackson, bertujuan agar lebih mudah dikonfigurasi oleh pengembang
StaxMan
sumber
15

Atau dengan Jackson:

String json = "...
ObjectMapper m = new ObjectMapper();
Set<Product> products = m.readValue(json, new TypeReference<Set<Product>>() {});
Gene De Lisa
sumber
Ini akan memberikan kesalahan tidak dapat membatalkan turunan dari java.util.HashSet dari token START_OBJECT
Dipen Chawla
7

Jika, dengan perubahan apa pun, Anda berada dalam aplikasi yang sudah menggunakan http://restfb.com/ maka Anda dapat melakukannya:

import com.restfb.json.JsonObject;

...

JsonObject json = new JsonObject(jsonString);
json.get("title");

dll.

cherouvim
sumber
solusi Anda lebih pendek dan lebih mudah dipahami, mengapa hanya menerima 3 upvotes? Apakah ada yang salah?
Jeff
4

Mudah dan bekerja kode java untuk mengkonversi JSONObjectkeJava Object

Employee.java

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Generated;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
"id",
"firstName",
"lastName"
})
public class Employee {

@JsonProperty("id")
private Integer id;
@JsonProperty("firstName")
private String firstName;
@JsonProperty("lastName")
private String lastName;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();

/**
*
* @return
* The id
*/
@JsonProperty("id")
public Integer getId() {
return id;
}

/**
*
* @param id
* The id
*/
@JsonProperty("id")
public void setId(Integer id) {
this.id = id;
}

/**
*
* @return
* The firstName
*/
@JsonProperty("firstName")
public String getFirstName() {
return firstName;
}

/**
*
* @param firstName
* The firstName
*/
@JsonProperty("firstName")
public void setFirstName(String firstName) {
this.firstName = firstName;
}

/**
*
* @return
* The lastName
*/
@JsonProperty("lastName")
public String getLastName() {
return lastName;
}

/**
*
* @param lastName
* The lastName
*/
@JsonProperty("lastName")
public void setLastName(String lastName) {
this.lastName = lastName;
}

@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}

@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}

}

LoadFromJSON.java

import org.codehaus.jettison.json.JSONObject;

import com.fasterxml.jackson.databind.ObjectMapper;

public class LoadFromJSON {

    public static void main(String args[]) throws Exception {
        JSONObject json = new JSONObject();
        json.put("id", 2);
        json.put("firstName", "hello");
        json.put("lastName", "world");

        byte[] jsonData = json.toString().getBytes();

        ObjectMapper mapper = new ObjectMapper();
        Employee employee = mapper.readValue(jsonData, Employee.class);

        System.out.print(employee.getLastName());

    }
}
Rahul Raina
sumber
Bagaimana cara mengakses properti json ini di JSP?
Zoran777
Jika Anda tidak ingin menggunakannya di halaman JSP maka kode masih sama. Kelas Employee.java akan sama seperti itu. Tetapi Kode yang ditulis dalam LoadFromJSON.java akan disalin di halaman jsp dengan impor yang tepat dari setiap kelas. Selebihnya tidak ada perubahan sama sekali.
Rahul Raina
4
HashMap keyArrayList = new HashMap();
Iterator itr = yourJson.keys();
while (itr.hasNext())
{
    String key = (String) itr.next();
    keyArrayList.put(key, yourJson.get(key).toString());
}
PANAS
sumber
3

Jika Anda menggunakan segala jenis peta khusus dengan kunci atau nilai-nilai juga dari peta khusus, Anda akan menemukan itu tidak dimaksudkan oleh penerapan google.

Juanma
sumber
2

Apa yang salah dengan barang standar?

JSONObject jsonObject = new JSONObject(someJsonString);
JSONArray jsonArray = jsonObject.getJSONArray("someJsonArray");
String value = jsonArray.optJSONObject(i).getString("someJsonValue");
Kevin
sumber
itu sangat lambat: github.com/fabienrenaud/java-json-benchmark baru-baru ini di pekerjaan itu, saya menggandakan kinerja (pengurangan penggunaan cpu menjadi dua, pengurangan latensi terhenti) dari server prod kami dengan mengalihkan semua panggilan layanan deserialisasi or org.json untuk menggunakan jackson.
fabien
0

Cobalah:

https://github.com/RichardHightower/boon

Itu jahat cepat:

https://github.com/RichardHightower/json-parsers-benchmark

Jangan mengambil kata-kata saya untuk itu ... lihat patokan gatling.

https://github.com/gatling/json-parsers-benchmark

(Hingga 4x adalah beberapa kasus, dan keluar dari tes 100-an. Ini juga memiliki mode indeks overlay yang bahkan lebih cepat. Ini masih muda tetapi sudah memiliki beberapa pengguna.)

Ini dapat mengurai JSON ke Maps dan Daftar lebih cepat daripada lib lainnya dapat mengurai ke JSON DOM dan itu tanpa mode Indeks Overlay. Dengan mode Overlay Indeks Boon, bahkan lebih cepat.

Ini juga memiliki mode JSON lax yang sangat cepat dan mode parser PLIST. :) (dan memiliki memori super rendah, langsung dari mode byte dengan pengkodean UTF-8 on the fly).

Ini juga memiliki mode JSON ke JavaBean tercepat juga.

Ini baru, tetapi jika kecepatan dan API sederhana adalah apa yang Anda cari, saya tidak berpikir ada API yang lebih cepat atau lebih minimalis.

RickHigh
sumber
dapatkah Anda memberikan tautan untuk dokumentasi terbaru untuk versi terbaru? Sampai hari ini, saya menemukan 0,4, tetapi tidak dapat dengan mudah menemukan tautan atau tutorial doc yang cocok untuk versi itu. Terima kasih
Bizmarck
Berikut ini adalah tutorial github.com/RichardHightower/boon/wiki/Boon-JSON-in-five-minutes Boon ada di repo pakar umum. Itu di 0,27 atau lebih.
RickHigh
richardhightower.github.io/site/releases memiliki 0,4, jadi saya pikir itu yang terbaru. Saya telah memeriksa Boon untuk sebuah proyek di tempat kerja, apakah ia memiliki anotasi yang setara dengan @JsonIgnore milik Jackson?
Bizmarck
anugerah berada di ujung bawah kinerja layanan ser / deserialization: github.com/fabienrenaud/java-json-benchmark Pilih jackson atau dsljson untuk kinerja. @RickHigh: Saya tidak bisa membuka masalah di github Anda, saya lebih dari bersedia untuk meningkatkan tolok ukur saya atau memperbaiki interpretasinya jika ada yang salah / yang-saya-lewatkan tentang hal itu.
fabien
0

Bergantung pada format input JSON (string / file) membuat jSONString. Contoh objek kelas Pesan yang sesuai dengan JSON dapat diperoleh seperti di bawah ini:

Message msgFromJSON = ObjectMapper baru (). ReadValue (jSONString, Message.class);

Shailendra Singh
sumber
0

Cara termudah adalah Anda dapat menggunakan metode nilai konversi lunak yang merupakan metode khusus di mana Anda dapat mengkonversi jsonData ke kelas Dto spesifik Anda.

Dto response = softConvertValue(jsonData, Dto.class);


public static <T> T softConvertValue(Object fromValue, Class<T> toValueType) 
{
    ObjectMapper objMapper = new ObjectMapper();
    return objMapper
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        .convertValue(fromValue, toValueType);
}
Dipen Chawla
sumber