JSON verilerini Java nesnesine dönüştürme


262

Java eylem yöntemi içinde bir JSON dizesi özelliklerine erişmek istiyorum. Dize basitçe söylenebilir myJsonString = object.getJson(). Aşağıda dizenin nasıl görünebileceğine bir örnek verilmiştir:

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

Bu dizede her JSON nesnesi diğer JSON nesnelerinden oluşan bir dizi içerir. Amaç, diğer JSON nesnelerini içeren bir grup özelliğine sahip herhangi bir nesnenin bulunduğu bir kimlik listesi çıkarmaktır. Google'ın Gson'una potansiyel bir JSON eklentisi olarak baktım. Herkes nasıl bu JSON dizesinden Java oluşturmak için bir tür rehberlik sunabilir?



Yanıtlar:


329

Google'ın Gson'una potansiyel bir JSON eklentisi olarak baktım. Herkes nasıl bu JSON dizesinden Java oluşturmak için bir tür rehberlik sunabilir?

Google Gson , jenerikleri ve iç içe fasulyeleri destekler. []JSON bir diziyi temsil eder ve bu şekilde bir Java koleksiyonuna haritalandırmalıdır Listya da sadece düz Java dizi. {}JSON bir nesneyi temsil eden ve bir Java eşleşmelidir Mapveya sadece bazı JavaBean sınıfında.

Birkaç özelliğe sahip bir JSON nesneniz var, bu groupsözellik aynı türden iç içe nesnelerin bir dizisini temsil ediyor. Bu, Gson ile şu şekilde ayrıştırılabilir:

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);
    }
}

Oldukça basit, değil mi? Sadece uygun bir JavaBean'a sahip olun ve arayın Gson#fromJson().

Ayrıca bakınız:


4
Ölçülebilir? Gerçekten ölçtün mü? GSON'un makul özellik seti olmasına rağmen, performansın bir tür zayıf nokta olduğunu düşündüm ([ cowtowncoder.com/blog/archives/2009/09/entry_326.html] uyarınca ) GSON'un gerçekten ayarlayıcılara ihtiyaç duymadığını düşündüm ve alanlara dayanıyordu. Böylece kod biraz basitleştirilebilir.
StaxMan

3
Bir android uygulamasında kullanıyorum. Mümkün olan en hızlı çözüm değil, ancak kullanıcı için şimdiye kadar performans eksikliğini haklı çıkarmak için programlamak yeterince basit. Belki uygulamanın daha sonraki bir sürümünde daha hızlı bir çözüm için kaldırılacaktır.
Janusz

1
Wrt hızı, yeterince hızlıysa, yeterince hızlıdır. Beklenen iyi performansa atıfta bulundum. Özellik kümesi akıllı Jackson aynı yuvalama, katmanlama, jenerikler, bu yüzden hız farkının geldiği yer değildir. Alıcılara ve ayarlayıcılara sahip olmak, performansı ölçülebilir bir şekilde etkilemez (farkında olduğum paketler için), bu yüzden kesinlikle orada olabilirler.
StaxMan

97
"Paket com.stackoverflow.q1688099;" için +1. Nedense beni kıkırdadı.
GargantuChet

1
public String toString () {yeni Gson () döndürür. toJson (this); // Her değişkeni yazmak yerine bunu kullanın}
Prakash

45

Bsonaaaaar Gson! Çok güzel, çok harika, ama basit nesnelerden başka bir şey yapmak istediğinizde, kendi serileştiricilerinizi ( o kadar da zor değil ) inşa etmeye kolayca başlamanız gerekebilir .

Ayrıca, bir Nesneler diziniz varsa ve bu Nesneler dizisine bazı json serisini kaldırırsanız, gerçek türler KAYBEDİR! Nesnelerin tamamı kopyalanmayacak bile! XStream kullanın .. Hangi, jsondriver kullanarak ve uygun ayarları yaparsanız, çirkin türleri gerçek json kodlar, böylece hiçbir şey kaybetmezsiniz. Gerçek serileştirme için ödenecek küçük bir fiyat (çirkin json).

Not Jackson bu sorunları düzeltir ve bir hızlı GSON daha.


2
Bu sorunları gideren (ve Jackson'ın tüm ek açıklamalarından kaçınan) bir Gson çatalı yazdım
Daniel Winterstein

26

İşin garibi, şu ana kadar bahsedilen tek iyi JSON işlemci GSON oldu.

İşte daha iyi seçenekler:

  • Jackson ( Github ) - güçlü veri bağlama (JSON'dan POJO'ya / POJO'lara), akış (ultra hızlı), ağaç modeli (türsüz erişim için uygun)
  • Flex-JSON - son derece yapılandırılabilir serileştirme

DÜZENLEME (Ağu / 2013):

Düşünülmesi gereken bir tane daha:

  • Genson - geliştirici tarafından yapılandırılması daha kolay olması amaçlanan Jackson'a benzer işlevsellik

15

Veya Jackson ile:

String json = "...
ObjectMapper m = new ObjectMapper();
Set<Product> products = m.readValue(json, new TypeReference<Set<Product>>() {});

Bu hata, java.util.HashSet örneğinin START_OBJECT jetonundan serisini kaldıramayacak hata verecek
Dipen Chawla

7

Herhangi bir değişiklikle, zaten http://restfb.com/ kullanan bir uygulamadaysanız şunları yapabilirsiniz:

import com.restfb.json.JsonObject;

...

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

vb.


çözümünüz daha kısa ve daha anlaşılır, neden sadece 3 puan alıyor? Yanlış bir şey var mı?
Jeff

4

Kolay ve dönüştürmek için çalışan java kodu JSONObjectiçinJava 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());

    }
}

JSP'de bu json özelliklerine nasıl erişilir?
Zoran777

JSP sayfasında kullanmak istemiyorsanız, kod yine aynıdır. Employee.java sınıfı ile aynı olacaktır. Ancak LoadFromJSON.java'da yazılan Kod, her sınıfın doğru şekilde içe aktarılmasıyla jsp sayfasına kopyalanacaktır. Dinlenme hiç bir değişiklik yok.
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());
}

3

Özel haritaların anahtarları veya değerleri olan herhangi bir özel harita kullanırsanız, google'ın uygulanması tarafından tasarlanmadığını göreceksiniz.


2

Standart şeylerin sorunu nedir?

JSONObject jsonObject = new JSONObject(someJsonString);
JSONArray jsonArray = jsonObject.getJSONArray("someJsonArray");
String value = jsonArray.optJSONObject(i).getString("someJsonValue");

son derece yavaş: son zamanlarda işte github.com/fabienrenaud/java-json-benchmark , tüm org.json ser / deserialization çağrılarını değiştirerek prod sunucularımızın performansını ikiye katladım (işlemci kullanımı yarı yarıya, gecikme gecikmesi) jackson kullanmak.
fabien

0

Boon'u deneyin:

https://github.com/RichardHightower/boon

Hızlı kötü:

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

Benim sözüme güvenme ... şaşırtıcı kısma göz atın.

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

(4x'e kadar bazı durumlar ve 100'lü testlerin dışında. Ayrıca daha hızlı bir dizin yer paylaşımı modu var. Genç ama zaten bazı kullanıcıları var.)

JSON'u Haritalar'a ve Listelere diğer lib'lerin bir JSON DOM ile ayrıştırabildiğinden daha hızlı ayrıştırabilir ve bu da İndeks Yerleşimi modudur. Boon Index Overlay modu ile daha da hızlı.

Ayrıca çok hızlı bir JSON gevşek modu ve bir PLIST ayrıştırıcı modu vardır. :) (ve UTF-8 kodlaması anında bayt modundan doğrudan süper düşük bir belleğe sahiptir).

Ayrıca JavaBean moduna da en hızlı JSON sahiptir.

Bu yeni, ancak hız ve basit API aradığınız şeyse, daha hızlı veya daha minimalist bir API olduğunu sanmıyorum.


en son sürümle ilgili güncel belgeler için bir bağlantı sağlayabilir misiniz? Bugün itibariyle, 0.4 buldum, ancak bu sürüm için kolayca eşleşen bir doc bağlantısı veya öğretici bulamıyorum. Teşekkürler
Bizmarck

İşte bir öğretici github.com/RichardHightower/boon/wiki/Boon-JSON-in-five-minutes Boon kamu maven deposunda . 0.27 ya da öylesine.
RickHigh

richardhightower.github.io/site/releases 0.4, bu yüzden en son olduğunu düşündüm. Boon'u işteki bir proje için kontrol ediyorum, Jackson'un @JsonIgnore'a eşdeğer bir notu var mı?
Bizmarck

nimet ser / serileştirme performansının alt ucundadır: github.com/fabienrenaud/java-json-benchmark Performans için jackson veya dsljson'u seçin. @RickHigh: Github'ınızda bir sorun açamadım, bu konuda yanlış / kaçırılan bir şey varsa karşılaştırmamı geliştirmek veya yorumunu düzeltmek için daha fazla istek duyuyorum.
fabien

0

Giriş JSON biçimine (dize / dosya) bağlı olarak bir jSONString oluşturun. JSON'a karşılık gelen Sample Message sınıf nesnesi aşağıdaki gibi elde edilebilir:

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


0

En kolay yol, jsonData'yı özel Dto sınıfınıza dönüştürebileceğiniz özel bir yöntem olan bu softconvertvalue yöntemini kullanabilmenizdir.

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);
}
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.