Java JSON ayrıştırma


1048

Aşağıdaki JSON metnim var. Nasıl değerlerini almak için ayrıştırmak edebilir pageName, pagePic, post_idvb?

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}

7
java yerleşik JSON kütüphaneleri bunu yapmak için hızlı yolu vardır, ama benim deneyimimde GSON acısız bir JSON bir JSON ayrıştırmak için en iyi kütüphanedir.
Iman Akbari

16
Bu, cevaplarını en kafa karıştırıcı bulduğum ilk yüksek oylanan ve korunan soru
Riyafa Abdul Hameed

6
@JaysonMinard kabul etti. Mod müdahalesi istendi. Bu gerçekten kapatılmalıdır. Başlangıçta (yanlış) soru korunurken bunu yapamayacağımı varsaydım, bu yüzden korumayı kaldırdım ve işimi yaptım. Bir mod beklerken düşük yanıtlı yanıtları ve benzerlerini önlemek için şimdi yeniden koruyun.
Mena

4
"Bu soru herhangi bir araştırma çabası göstermiyor" - Downvote düğme araç ipucu
Jean-François Corbett

6
Bu soru Meta'da tartışılıyor .
Mark Amery

Yanıtlar:


753

Org.json kütüphane kullanımı kolaydır. Aşağıdaki örnek kod:

import org.json.*;

String jsonString = ... ; //assign your JSON String here
JSONObject obj = new JSONObject(jsonString);
String pageName = obj.getJSONObject("pageInfo").getString("pageName");

JSONArray arr = obj.getJSONArray("posts");
for (int i = 0; i < arr.length(); i++)
{
    String post_id = arr.getJSONObject(i).getString("post_id");
    ......
}

Daha fazla örnek bulabilirsiniz: Java'da Parse JSON

İndirilebilir kavanoz: http://mvnrepository.com/artifact/org.json/json


15
@StaxMan'a katılıyorum. Ben sadece org.json denedim ve korkunç hantal. Örneğin, standart Java Koleksiyonu türleriyle gerçekten oynamaz.
Ken Williams

7
@StaxMan Ben org.jsonbile bakmadan basit JSON ayrıştırma için diğer kütüphaneleri tercih ediyorum . Douglas Crockford'un (JSON keşfi) oluşturduğu referans kütüphanesidir.
Omar Al-Ithawi

31
@OmarIthawi bu sadece aptalca. Garip API, verimsiz uygulama ile kavram kanıtı. Yazarların görünürlüğünden kaliteyi çıkarmaya çalışmak yerine kütüphaneleri kendi yararlarına düşünmenin daha iyi olduğunu düşünüyorum - Doug pek çok şey başardı, ancak bu belirli lib'in niteliklerini gerçekten değiştirmez. 10 yıl önce şehirdeki tek oyundu, ancak o zamandan beri çok olumlu ilerleme kaydedildi. Json libs Struts gibi.
StaxMan

12
org.json en kötü json kütüphaneleri arasındadır. Seçmeden önce mevcut json kütüphanelerinin özellik setine ve performansına bakılmalıdır. İşte JMH kullanarak jackson, gson, org.json, genson karşılaştırması yaptığım bir karşılaştırma: github.com/fabienrenaud/java-json-benchmark . jackson burada kazanır.
fabien

4
Lisans, yaygın olarak kullanılan herhangi bir Açık Kaynak lisansını içermez ve ayrıca telif haklarına sahiptir.
Christian Vielma

536

Örneğin uğruna Personsadece a ile bir sınıfınız olduğunu varsayalım name.

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Google GSON ( Maven )

Nesnelerin büyük JSON serileştirme / serileştirme için kişisel favorim.

Gson g = new Gson();

Person person = g.fromJson("{\"name\": \"John\"}", Person.class);
System.out.println(person.name); //John

System.out.println(g.toJson(person)); // {"name":"John"}

Güncelleme

Tek bir özellik almak istiyorsanız Google kütüphanesi ile de kolayca yapabilirsiniz:

JsonObject jsonObject = new JsonParser().parse("{\"name\": \"John\"}").getAsJsonObject();

System.out.println(jsonObject.get("name").getAsString()); //John

Org.JSON ( Maven )

Nesnenin serileştirmesine gerek duymazsanız, ancak bir nitelik elde etmek için org.json'u deneyebilirsiniz ( veya yukarıdaki GSON örneğine bakın! )

JSONObject obj = new JSONObject("{\"name\": \"John\"}");

System.out.println(obj.getString("name")); //John

Jackson ( Maven )

ObjectMapper mapper = new ObjectMapper();
Person user = mapper.readValue("{\"name\": \"John\"}", Person.class);

System.out.println(user.name); //John

16
İyi cevap. Küçük gelişme için bir öneri: hem GSON hem de Jackson, JSON ağacı temsilinin kullanımını destekler (Jackson için bunlar JsonNode, GSON'un benzer bir şeye sahiptir). Parçacıkları göstermek iyi olabilir, çünkü bu org.json'un tek yoluna benzer.
StaxMan

Bahsetmeye değer diğer iki kütüphane (bütünlük yararına): json-simple ve Oracle'ın JSONP
jake stayman

3
@NeonWarge, neden? Bana öyle geliyor ki bu cevap, bir kişinin JSON dizesiyle tam olarak aynı alanları içeren bir Java sınıfını tanımladığını, daha az bir şey ve başka bir şey olmadığını varsayar. Bu oldukça güçlü bir varsayım.
Andrea Lazzarotto

1
json-simple ve oracle'ın jsonp'u çok başarılı: github.com/fabienrenaud/java-json-benchmark Performans için jackson veya dsljson'u seçin.
fabien

GSON, kök dışındaki düzeylerde alanların dinamik olarak filtrelenmesini desteklemez!
Gangnus

102
  1. Biri JSON'dan Java nesnesi oluşturmak istiyorsa veya tam tersi, GSON veya JACKSON üçüncü taraf kavanozlarını kullanın.

    //from object to JSON 
    Gson gson = new Gson();
    gson.toJson(yourObject);
    
    // from JSON to object 
    yourObject o = gson.fromJson(JSONString,yourObject.class);
  2. Ama sadece bir JSON dizesini ayrıştırmak ve bazı değerler almak istiyorsanız, (VEYA tel üzerinden göndermek için sıfırdan bir JSON dizesi oluşturun) sadece JsonReader, JsonArray, JsonObject vb. İçeren JaveEE kavanozunu kullanın. javax.json gibi spec. Bu iki kavanozla json'ı ayrıştırabilir ve değerleri kullanabilirim.

    Bu API'ler aslında XML'in DOM / SAX ayrıştırma modelini izler.

    Response response = request.get(); // REST call 
        JsonReader jsonReader = Json.createReader(new StringReader(response.readEntity(String.class)));
        JsonArray jsonArray = jsonReader.readArray();
        ListIterator l = jsonArray.listIterator();
        while ( l.hasNext() ) {
              JsonObject j = (JsonObject)l.next();
              JsonObject ciAttr = j.getJsonObject("ciAttributes");

4
@nondescript Tahmin etmek zorunda olsaydım, orijinal afişin sorusuna cevap vermediği için indirildiğini söyleyebilirim: "Gerekli kod nedir?" Kaldırılan cevaplar kod parçacıkları sağladı.
jewbix.cube

4
Not: Jackson ve GSON, hem ağaç stili hem de Haritalar / Listeler bağlanmasını destekler, bu nedenle Java EE (javax.json) paketini kullanmaya gerek yoktur. javax.json'un Jackson veya GSON'un ötesinde sunabileceği çok az şey vardır.
StaxMan

JavaEE kütüphanesine bir bağlantı eklemenizi öneririm.
Basil Bourque

72

quick-json ayrıştırıcı çok basit, esnek, çok hızlı ve özelleştirilebilir. Dene

Özellikleri:

  • JSON spesifikasyonu (RFC4627) ile uyumlu
  • Yüksek Performanslı JSON ayrıştırıcı
  • Esnek / Konfigüre edilebilir ayrıştırma yaklaşımını destekler
  • Herhangi bir JSON Hiyerarşisinin anahtar / değer çiftlerinin yapılandırılabilir doğrulaması
  • Kullanımı kolay # Çok az yer kaplar
  • Geliştiricinin dostu ve izlenmesi kolay istisnaları artırır
  • Takılabilir Özel Doğrulama desteği - Tuşlar / Değerler, özel doğrulayıcılarla karşılaşıldığında olduğu gibi yapılandırılarak doğrulanabilir
  • Doğrulama ve Doğrulamayan ayrıştırıcı desteği
  • Hızlı JSON doğrulama ayrıştırıcısını kullanmak için iki tür yapılandırma (JSON / XML) desteği
  • JDK 1.5 gerektirir
  • Harici kütüphanelere bağımlılık yok
  • Nesne serileştirme yoluyla JSON Üretimi desteği
  • Ayrıştırma işlemi sırasında toplama türü seçimi desteği

Bu şekilde kullanılabilir:

JsonParserFactory factory=JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonMap=parser.parseJson(jsonString);

3
Bir javadoc var mı?
jboi

24
Bu paket ayrıştırılırken boş değerleri işleyemiyor. Örneğin: ... "description": "" ... bir istisna atar
Ivan

6
Code.google.com/p/quick-json/issues/detail?id=11 Bu sorunu (ve daha birçoklarını) düzelttim, umarım yazar resmi sürümde düzeltmek için zaman ayırır .
noamik

8
Listelenen özelliklerden, hiçbir şey diğer seçeneklere kıyasla benzersiz değildir - ve yüksek performans iddiası hiçbir şey tarafından desteklenmez; Daha fazla kütüphanede gibi kriterler yer almaktadır (GSON, Jackson, Genson, Boon) olgun için farklı github.com/eishay/jvm-serializers , github.com/novoj/JavaJsonPerformanceTest veya developer.com/lang/jscript/… - I bu kütüphanenin testlerde yer aldığını veya yaygın olarak kullanıldığından bahsetmedik.
StaxMan

26
Bu proje ölü gibi görünüyor ve artık Maven merkez deposunda barındırılmıyor gibi görünüyor.
8bitjunkie

40

Google Gson'u kullanabilirsiniz .

Bu kütüphaneyi kullanarak sadece aynı JSON yapısına sahip bir model oluşturmanız gerekir. Daha sonra model otomatik olarak doldurulur. Değişkenlerinizi JSON anahtarlarınız olarak çağırmanız veya @SerializedNamefarklı adlar kullanmak istiyorsanız kullanmanız gerekir.

JSON

Örneğinizden:

{
    "pageInfo": {
        "pageName": "abc",
        "pagePic": "http://example.com/content.jpg"
    }
    "posts": [
        {
            "post_id": "123456789012_123456789012",
            "actor_id": "1234567890",
            "picOfPersonWhoPosted": "http://example.com/photo.jpg",
            "nameOfPersonWhoPosted": "Jane Doe",
            "message": "Sounds cool. Can't wait to see it!",
            "likesCount": "2",
            "comments": [],
            "timeOfPost": "1234567890"
        }
    ]
}

model

class MyModel {

    private PageInfo pageInfo;
    private ArrayList<Post> posts = new ArrayList<>();
}

class PageInfo {

    private String pageName;
    private String pagePic;
}

class Post {

    private String post_id;

    @SerializedName("actor_id") // <- example SerializedName
    private String actorId;

    private String picOfPersonWhoPosted;
    private String nameOfPersonWhoPosted;
    private String message;
    private String likesCount;
    private ArrayList<String> comments;
    private String timeOfPost;
}

ayrıştırma

Artık Gson kütüphanesini kullanarak ayrıştırabilirsiniz:

MyModel model = gson.fromJson(jsonString, MyModel.class);

Gradle içe aktarma

Uygulama Gradle dosyasındaki kütüphaneyi içe aktarmayı unutmayın

implementation 'com.google.code.gson:gson:2.8.6' // or earlier versions

Otomatik model oluşturma

JSON otomatik gibi çevrimiçi araçlar kullanarak Sen modelini oluşturabilir bu .


38

Verilen yanıtların neredeyse tamamı, ilgilenilen mülkteki değere erişmeden önce JSON'un bir Java nesnesine tam olarak serileştirilmesini gerektirir. Bu rotaya gitmeyen diğer bir alternatif ise JSON için XPath gibi olan ve JSON nesnelerinin geçişine izin veren JsonPATH kullanmaktır .

Bu bir spesifikasyon ve JayWay'deki iyi insanlar, burada bulabileceğiniz spesifikasyon için bir Java uygulaması oluşturdular: https://github.com/jayway/JsonPath

Temel olarak kullanmak için projenize ekleyin, örneğin:

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>${version}</version>
</dependency>

ve kullanmak için:

String pageName = JsonPath.read(yourJsonString, "$.pageInfo.pageName");
String pagePic = JsonPath.read(yourJsonString, "$.pageInfo.pagePic");
String post_id = JsonPath.read(yourJsonString, "$.pagePosts[0].post_id");

vb...

JSON'u çaprazlamanın diğer yolları hakkında daha fazla bilgi için JsonPath teknik özellik sayfasına bakın.


Bu özellikle JSON okumak ve güncellemek için çok iyi bir kütüphane ama bu kütüphane hakkında bilinen bazı sorunlara dikkat edin. Bkz. [1]: github.com/json-path/JsonPath/issues/272 [2]: github.com/json-path/JsonPath/issues/375
papigee

38

A - Açıklama

JSON String'i POJO ( Plain Old Java Object ) örneklerine bağlamak için Jackson kitaplıklarını kullanabilirsiniz . POJO sadece özel alanları ve kamu alıcı / belirleyici yöntemleri olan bir sınıftır. Jackson yöntemleri yansıtır ( yansıma kullanarak ) ve sınıfın alan adları JSON nesnesinin alan adlarına uyurken JSON nesnesini POJO örneğiyle eşler.

Aslında bileşik bir nesne olan JSON nesnenizde, ana nesne iki alt nesneden oluşur. Yani, POJO sınıflarımız aynı hiyerarşiye sahip olmalıdır. Tüm JSON Nesnesini Sayfa nesnesi olarak adlandıracağım. Sayfa nesnesi, bir PageInfo nesnesi ve bir Post nesnesi dizisinden oluşur.

Bu yüzden üç farklı POJO sınıfı yaratmalıyız;

  • Page Class, PageInfo Sınıfının bir bileşimi ve Post Instances dizisi
  • PageInfo Sınıfı
  • Mesaj Sınıfı

Kullandığım tek paket Jackson ObjectMapper, yaptığımız veri bağlama;

com.fasterxml.jackson.databind.ObjectMapper

Gerekli bağımlılıklar, jar dosyaları aşağıda listelenmiştir;

  • Jackson-çekirdek-2.5.1.jar
  • Jackson-databind-2.5.1.jar
  • Jackson-açıklamalar-2.5.0.jar

İşte gerekli kod;

B - Ana POJO Sınıfı: Sayfa

package com.levo.jsonex.model;

public class Page {

    private PageInfo pageInfo;
    private Post[] posts;

    public PageInfo getPageInfo() {
        return pageInfo;
    }

    public void setPageInfo(PageInfo pageInfo) {
        this.pageInfo = pageInfo;
    }

    public Post[] getPosts() {
        return posts;
    }

    public void setPosts(Post[] posts) {
        this.posts = posts;
    }

}

C - Alt POJO Sınıfı: PageInfo

package com.levo.jsonex.model;

public class PageInfo {

    private String pageName;
    private String pagePic;

    public String getPageName() {
        return pageName;
    }

    public void setPageName(String pageName) {
        this.pageName = pageName;
    }

    public String getPagePic() {
        return pagePic;
    }

    public void setPagePic(String pagePic) {
        this.pagePic = pagePic;
    }

}

D - Çocuk POJO Sınıfı: Gönderi

package com.levo.jsonex.model;

public class Post {

    private String post_id;
    private String actor_id;
    private String picOfPersonWhoPosted;
    private String nameOfPersonWhoPosted;
    private String message;
    private int likesCount;
    private String[] comments;
    private int timeOfPost;

    public String getPost_id() {
        return post_id;
    }

    public void setPost_id(String post_id) {
        this.post_id = post_id;
    }

    public String getActor_id() {
        return actor_id;
    }

    public void setActor_id(String actor_id) {
        this.actor_id = actor_id;
    }

    public String getPicOfPersonWhoPosted() {
        return picOfPersonWhoPosted;
    }

    public void setPicOfPersonWhoPosted(String picOfPersonWhoPosted) {
        this.picOfPersonWhoPosted = picOfPersonWhoPosted;
    }

    public String getNameOfPersonWhoPosted() {
        return nameOfPersonWhoPosted;
    }

    public void setNameOfPersonWhoPosted(String nameOfPersonWhoPosted) {
        this.nameOfPersonWhoPosted = nameOfPersonWhoPosted;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getLikesCount() {
        return likesCount;
    }

    public void setLikesCount(int likesCount) {
        this.likesCount = likesCount;
    }

    public String[] getComments() {
        return comments;
    }

    public void setComments(String[] comments) {
        this.comments = comments;
    }

    public int getTimeOfPost() {
        return timeOfPost;
    }

    public void setTimeOfPost(int timeOfPost) {
        this.timeOfPost = timeOfPost;
    }

}

E - Örnek JSON Dosyası: sampleJSONFile.json

JSON örneğinizi bu dosyaya kopyaladım ve proje klasörünün altına koydum.

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}

F - Demo Kodu

package com.levo.jsonex;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.levo.jsonex.model.Page;
import com.levo.jsonex.model.PageInfo;
import com.levo.jsonex.model.Post;

public class JSONDemo {

    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();

        try {
            Page page = objectMapper.readValue(new File("sampleJSONFile.json"), Page.class);

            printParsedObject(page);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void printParsedObject(Page page) {
        printPageInfo(page.getPageInfo());
        System.out.println();
        printPosts(page.getPosts());
    }

    private static void printPageInfo(PageInfo pageInfo) {
        System.out.println("Page Info;");
        System.out.println("**********");
        System.out.println("\tPage Name : " + pageInfo.getPageName());
        System.out.println("\tPage Pic  : " + pageInfo.getPagePic());
    }

    private static void printPosts(Post[] posts) {
        System.out.println("Page Posts;");
        System.out.println("**********");
        for(Post post : posts) {
            printPost(post);
        }
    }

    private static void printPost(Post post) {
        System.out.println("\tPost Id                   : " + post.getPost_id());
        System.out.println("\tActor Id                  : " + post.getActor_id());
        System.out.println("\tPic Of Person Who Posted  : " + post.getPicOfPersonWhoPosted());
        System.out.println("\tName Of Person Who Posted : " + post.getNameOfPersonWhoPosted());
        System.out.println("\tMessage                   : " + post.getMessage());
        System.out.println("\tLikes Count               : " + post.getLikesCount());
        System.out.println("\tComments                  : " + Arrays.toString(post.getComments()));
        System.out.println("\tTime Of Post              : " + post.getTimeOfPost());
    }

}

G - Demo Çıkışı

Page Info;
****(*****
    Page Name : abc
    Page Pic  : http://example.com/content.jpg
Page Posts;
**********
    Post Id                   : 123456789012_123456789012
    Actor Id                  : 1234567890
    Pic Of Person Who Posted  : http://example.com/photo.jpg
    Name Of Person Who Posted : Jane Doe
    Message                   : Sounds cool. Can't wait to see it!
    Likes Count               : 2
    Comments                  : []
    Time Of Post              : 1234567890

26

Kullanım Minimal json çok hızlı ve kullanımı kolaydır. String obj ve Stream öğelerinden ayrıştırabilirsiniz.

Örnek veri:

{
  "order": 4711,
  "items": [
    {
      "name": "NE555 Timer IC",
      "cat-id": "645723",
      "quantity": 10,
    },
    {
      "name": "LM358N OpAmp IC",
      "cat-id": "764525",
      "quantity": 2
    }
  ]
}

Ayrıştırma:

JsonObject object = Json.parse(input).asObject();
int orders = object.get("order").asInt();
JsonArray items = object.get("items").asArray();

JSON oluşturuluyor:

JsonObject user = Json.object().add("name", "Sakib").add("age", 23);

Uzman:

<dependency>
  <groupId>com.eclipsesource.minimal-json</groupId>
  <artifactId>minimal-json</artifactId>
  <version>0.9.4</version>
</dependency>

Pojo nasıl görünecek?
Jesse

Pojo için gson kullanın. Bu kütüphane desteklenmiyor.
Sakib Sami

22

En iyi uygulamanın , halen devam etmekte olan resmi Java JSON API'sinden geçmek olması gerektiğine inanıyorum .


7
Yanıtladığımdan beri Jackson'ı kullanmaya başladım ve bunun JSON serileştirmesi için en iyi kütüphanelerden biri olduğunu düşünüyorum.
Giovanni Botta

2
Neden Padding ile JSON'dan farklı bir şey ifade etmek için JSONP'u tekrar kullanıyorlar ? ...
Chris Wesseling

@ChrisWesseling Ne demek istiyorsun?
Giovanni Botta

"JSON İşleme için Java API (JSON-P)" bağlandığınız belgenin başlığıdır. Ve beni şaşırttı, çünkü JSONP'u başka bir şey ifade ettiğini biliyordum.
Chris Wesseling

1
@ChrisWesseling oh bu kafa karıştırıcı. Şartname için seçtikleri şey budur. Ancak dediğim gibi, doğrudan Jackson'a giderdim.
Giovanni Botta

22

Henüz kimse bundan bahsetmediği için, Nashorn (Java 8'in JavaScript çalışma zamanı kısmı olan, ancak Java 11'de kullanımdan kaldırıldı) kullanan bir çözümün başlangıcı .

Çözüm

private static final String EXTRACTOR_SCRIPT =
    "var fun = function(raw) { " +
    "var json = JSON.parse(raw); " +
    "return [json.pageInfo.pageName, json.pageInfo.pagePic, json.posts[0].post_id];};";

public void run() throws ScriptException, NoSuchMethodException {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    engine.eval(EXTRACTOR_SCRIPT);
    Invocable invocable = (Invocable) engine;
    JSObject result = (JSObject) invocable.invokeFunction("fun", JSON);
    result.values().forEach(e -> System.out.println(e));
}

Performans karşılaştırması

20, 20 ve 100 elemandan oluşan üç dizi içeren JSON içeriği yazdım. Sadece üçüncü diziden 100 eleman almak istiyorum. Girişlerimi ayrıştırmak ve almak için aşağıdaki JavaScript işlevini kullanıyorum.

var fun = function(raw) {JSON.parse(raw).entries};

Nashorn kullanarak çağrıyı milyonlarca kez çalıştırmak 7,5 ~ 7,8 saniye sürer

(JSObject) invocable.invokeFunction("fun", json);

org.json 20 ~ 21 saniye sürer

new JSONObject(JSON).getJSONArray("entries");

Jackson 6.5 ~ 7 saniye sürüyor

mapper.readValue(JSON, Entries.class).getEntries();

Bu durumda Jackson, org.json'dan çok daha iyi performans gösteren Nashorn'dan daha iyi performans gösterir. Nashorn API'sini kullanmak org.json's veya Jackson'tan daha zordur. İhtiyaçlarınıza bağlı olarak Jackson ve Nashorn her ikisi de uygun çözümler olabilir.


1
" "" Birimi nedir ? İnç değil mi? Saniye mi? Dakika?
Peter Mortensen

1
@PeterMortensen saniye demek. Belirsiz göründüğü için değiştireceğim. İnceleme için teşekkürler.
otonglet

2
Ne yazık ki, Nashorn Java 11'de kullanımdan kaldırılmıştır. JEP 335 .
Per Mildner

1
Nashorn'un onaylanmadığını biliyorum, ama bu cevabı beğendim çünkü herhangi bir bağımlılık istemedim; ancak, örneği biraz yeniden çalışmak zorunda kaldım:ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); engine.eval("var fun = function(raw) { return JSON.parse(raw); };"); Map<String, Object> json = (Map<String, Object>) ((Invocable) engine).invokeFunction("fun", jsonString);
kgibm

21

Aşağıdaki örnek, sorudaki "jsonText" değişkeni olarak gösterilen metnin nasıl okunacağını gösterir. Bu çözüm, Java EE7 javax.json API'sini kullanır (diğer bazı cevaplarda belirtilmiştir). Ben ayrı bir cevap olarak ekledikten nedeni aşağıdaki kod gösterir nasıl olduğunu aslında söz konusu gösterilen değerlerinden bazılarını erişin. Bir javax.json API uygulaması bu kod çalışmasını sağlamak için gerekli olacaktır. Gerekli sınıfların her biri için tam paket dahil "alma" deyimleri bildirmek istemiyordu.

javax.json.JsonReader jr = 
    javax.json.Json.createReader(new StringReader(jsonText));
javax.json.JsonObject jo = jr.readObject();

//Read the page info.
javax.json.JsonObject pageInfo = jo.getJsonObject("pageInfo");
System.out.println(pageInfo.getString("pageName"));

//Read the posts.
javax.json.JsonArray posts = jo.getJsonArray("posts");
//Read the first post.
javax.json.JsonObject post = posts.getJsonObject(0);
//Read the post_id field.
String postId = post.getString("post_id");

Şimdi, GSON, org.json, Jackson veya mevcut diğer 3. taraf çerçevelerinden herhangi birini kullanmadığından, bu yanıtı kimse yanıtlayıp indirmeden önce, sağlanan metni ayrıştırmak için soru başına "gerekli kod" örneğidir. Mevcut JSR 353 standardına uymanın JDK 9 için dikkate alınmadığının ve JSR 353 spesifikasyonunun diğer üçüncü taraf JSON işleme uygulamalarıyla aynı şekilde ele alınması gerektiğinin farkındayım .


15

Bu aklımı ne kadar kolay olduğu ile uçurdu. Sadece bir geçebilir Stringvarsayılan org.json paketinde JSONObject nesnesi kurucusuna sizin JSON tutarak.

JSONArray rootOfPage =  new JSONArray(JSONString);

Bitti. Mikrofonu düşürür . Bu da işe yarıyor JSONObjects. Bundan sonra, nesnelerinizdeki yöntemleri Objectskullanma hiyerarşinize bakabilirsiniz get().


13
JSONArrayTipi J2SE JDK API parçası değildir ve API veya üçüncü taraf kütüphane bu tür sağlayan söyleme.
Bobulous

2
Ben bunu kullanarak öneriyoruz, ancak bundan "org.json" paketine atıfta düşünüyorum Değil o json.org/java . Eskiden iyi Java kütüphaneleri kullanıma sunulmadan önce kullanılırdı, ancak bu yıllar önce (2008 veya daha önce) idi
StaxMan

1
Veya anlamına brainmurphy1 gelmez JSONArray Android'de?
Alexander Farber

12

Java'da birçok JSON kütüphanesi vardır.

En kötü şöhretli olanlar: Jackson, GSON, Genson, FastJson ve org.json.

Herhangi bir kütüphaneyi seçmek için genellikle bakılması gereken üç şey vardır:

  1. Verim
  2. Kullanım kolaylığı (kodun yazılması basit ve okunaklı) - bu özelliklerle birlikte gelir.
  3. Mobil uygulamalar için: bağımlılık / kavanoz boyutu

Özellikle JSON kütüphaneleri (ve herhangi bir serileştirme / serileştirme kütüphanesi) için, veri paketlemek / paketten çıkarmak için kazan plakası kodunun yazılması gerekliliğini ortadan kaldırdığı için, veri toplama da genellikle ilgi çekicidir.

: 1, bu kriter bakınız https://github.com/fabienrenaud/java-json-benchmark I kullanılarak mi JMH karşılaştırır (Jackson, GSON, genson, fastjson, org.json, jsonp) akışı kullanılarak serileştiricileri ve deserializers performansı ve databind API'leri. 2 için internette çok sayıda örnek bulabilirsiniz. Yukarıdaki karşılaştırmalı değerlendirme örnek bir kaynak olarak da kullanılabilir ...

Karşılaştırmanın hızlı bir şekilde sunumu : Jackson , org.json'dan 5 ila 6 kat daha iyi ve GSON'dan iki kat daha iyi performans sergiliyor.

Özel örneğiniz için, aşağıdaki kod json'unuzu jackson ile çözer:

public class MyObj {

    private PageInfo pageInfo;
    private List<Post> posts;

    static final class PageInfo {
        private String pageName;
        private String pagePic;
    }

    static final class Post {
        private String post_id;
        @JsonProperty("actor_id");
        private String actorId;
        @JsonProperty("picOfPersonWhoPosted")
        private String pictureOfPoster;
        @JsonProperty("nameOfPersonWhoPosted")
        private String nameOfPoster;
        private String likesCount;
        private List<String> comments;
        private String timeOfPost;
    }

    private static final ObjectMapper JACKSON = new ObjectMapper();
    public static void main(String[] args) throws IOException {
        MyObj o = JACKSON.readValue(args[0], MyObj.class); // assumes args[0] contains your json payload provided in your question.
    }
}

Herhangi bir sorunuz olursa bize bildirin.


11

Diğer cevaplara ek olarak, GSON, Jackson 1.x veya Jackson 2.x için json veya json şemasından hızlı bir şekilde Java sınıfları oluşturmak için bu çevrimiçi açık kaynak hizmeti jsonschema2pojo.org'u öneriyorum. Örneğin, aşağıdakilere sahipseniz:

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    }
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": 1234567890,
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": 2,
              "comments": [],
              "timeOfPost": 1234567890
         }
    ]
}

Jsonschema2pojo.org GSON için oluşturulmuş:

@Generated("org.jsonschema2pojo")
public class Container {
    @SerializedName("pageInfo")
    @Expose
    public PageInfo pageInfo;
    @SerializedName("posts")
    @Expose
    public List<Post> posts = new ArrayList<Post>();
}

@Generated("org.jsonschema2pojo")
public class PageInfo {
    @SerializedName("pageName")
    @Expose
    public String pageName;
    @SerializedName("pagePic")
    @Expose
    public String pagePic;
}

@Generated("org.jsonschema2pojo")
public class Post {
    @SerializedName("post_id")
    @Expose
    public String postId;
    @SerializedName("actor_id")
    @Expose
    public long actorId;
    @SerializedName("picOfPersonWhoPosted")
    @Expose
    public String picOfPersonWhoPosted;
    @SerializedName("nameOfPersonWhoPosted")
    @Expose
    public String nameOfPersonWhoPosted;
    @SerializedName("message")
    @Expose
    public String message;
    @SerializedName("likesCount")
    @Expose
    public long likesCount;
    @SerializedName("comments")
    @Expose
    public List<Object> comments = new ArrayList<Object>();
    @SerializedName("timeOfPost")
    @Expose
    public long timeOfPost;
}

9

JSON dizesini (jsonString) temsil eden bazı Java sınıfınız (Mesaj deyin) varsa, Jackson JSON kitaplığını aşağıdakilerle kullanabilirsiniz :

Message message= new ObjectMapper().readValue(jsonString, Message.class);

ve mesaj nesnesinden herhangi bir niteliğini alabilirsiniz.


9

Gson'un öğrenmesi ve uygulanması kolaydır, bilmemiz gerekenler iki yöntemi takip etmektedir

  • toJson () - Java nesnesini JSON biçimine dönüştür

  • fromJson () - JSON'u Java nesnesine dönüştür

'

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import com.google.gson.Gson;

public class GsonExample {
    public static void main(String[] args) {

    Gson gson = new Gson();

    try {

        BufferedReader br = new BufferedReader(
            new FileReader("c:\\file.json"));

        //convert the json string back to object
        DataObject obj = gson.fromJson(br, DataObject.class);

        System.out.println(obj);

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

    }
}

'


Gson hakkında tam bilgi için aşağıdaki bağlantılara bakın. github.com/google/gson/blob/master/UserGuide.md
venkat

9

JSON içeriğini bir nesneye ayrıştırmak veya sadece JSON değerlerini okumak için birçok açık kaynak kitaplığı vardır. İhtiyacınız sadece değerleri okumak ve özel nesneye ayrıştırmaktır. Yani org.json kütüphanesi sizin durumunuzda yeterlidir.

Ayrıştırmak ve JsonObject oluşturmak için org.json kütüphanesini kullanın:

JSONObject jsonObj = new JSONObject(<jsonStr>);

Şimdi, değerlerinizi almak için bu nesneyi kullanın:

String id = jsonObj.getString("pageInfo");

Burada tam bir örnek görebilirsiniz:

Java JSON ayrıştırma


Görünüşe göre tüm yanıtlarınız bu siteye bir bağlantı içeriyor. Spam ise lütfen durdurun. Değilse, karışıklık için özür dilerim, ancak tüm cevaplarınıza bir bağlantı göndermenin gerekli olduğunu düşünmüyorum.
Donald Duck

1
Tüm senaryoları açıklayabileceğiniz bir cevap vermek zor. Bu durumda olduğu gibi, json dizisi veya birden fazla json nesnesinin nasıl okunacağı. Bunu yapsam bile cevap çok uzun olur ve kişi kafasını karıştırabilir. Bu yüzden, uygun örnekle, uygun bir açıklama yapılan bir bağlantı veriyorum. Ziyaret etmeyi seçebilir veya sadece açıklamamı kullanabilir.
lalitbhagtani

1
Bana verdiğiniz bağlantının sadece JSON'un nasıl okunacağını gösterdiği anlaşılıyor. JSON ile ilgili bilgileri nereden bulabilirim?
Lampros Tzanetos

Üzgünüz, ama sorunuzu anlamadım: - "nasıl JSON için"
lalitbhagtani

7

Lütfen böyle bir şey yapın:

JSONParser jsonParser = new JSONParser();
JSONObject obj = (JSONObject) jsonParser.parse(contentString);
String product = (String) jsonObject.get("productId");

10
Ee, bu hangi kütüphane?
Stewart

2
Sanırım org.json.simple kullanıyor
Lasitha Yapa

7

JSON dizesini ayrıştırmak için Gson Kitaplığı'nı kullanabilirsiniz.

Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(jsonAsString, JsonObject.class);

String pageName = jsonObject.getAsJsonObject("pageInfo").get("pageName").getAsString();
String pagePic = jsonObject.getAsJsonObject("pageInfo").get("pagePic").getAsString();
String postId = jsonObject.getAsJsonArray("posts").get(0).getAsJsonObject().get("post_id").getAsString();

Ayrıca "posts" dizisi arasında şu şekilde döngü yapabilirsiniz:

JsonArray posts = jsonObject.getAsJsonArray("posts");
for (JsonElement post : posts) {
  String postId = post.getAsJsonObject().get("post_id").getAsString();
  //do something
}

5
{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}

Java code :

JSONObject obj = new JSONObject(responsejsonobj);
String pageName = obj.getJSONObject("pageInfo").getString("pageName");

JSONArray arr = obj.getJSONArray("posts");
for (int i = 0; i < arr.length(); i++)
{
    String post_id = arr.getJSONObject(i).getString("post_id");
    ......etc
}

9
Lütfen yanıtınızı yalnızca kod yanıtları, iyi belgelenmiş koddan çok daha azına yardımcı olur. Bkz. "Bir adama balık verin ve onu bir günlüğüne besleyin; bir adama balık tutmayı öğretin ve onu ömür boyu beslersiniz" .
Wai Ha Lee

Bunun 'org.json' lib için olduğunu belirtmek iyi olur. Bununla birlikte, bunun çok ayrıntılı ve 'org.json' lib'in eski (yavaş, hantal API) olması için iyi bir yol olduğunu düşünmüyorum. Daha iyi seçenekler var: GSON, Jackson, Boon, Genson kullanmak.
StaxMan

5

Aşağıdaki blog yazısını okuyun, JSON Java .

Bu yazı biraz eski, ama yine de size soruyu cevaplamak istiyorum.

Adım 1: Verilerinizden bir POJO sınıfı oluşturun.

Adım 2: Şimdi JSON kullanarak bir nesne oluşturun.

Employee employee = null;
ObjectMapper mapper = new ObjectMapper();
try{
    employee =  mapper.readValue(newFile("/home/sumit/employee.json"), Employee.class);
} 
catch (JsonGenerationException e){
    e.printStackTrace();
}

Daha fazla referans için aşağıdaki bağlantıya bakabilirsiniz .


4

Bu sayfadaki en iyi yanıtlar, bir özelliğe sahip nesne gibi çok basit örnekler kullanır (örneğin, {name: value}). Bence hala basit ama gerçek hayat örneği birine yardım edebilir.

İşte Google Translate API tarafından döndürülen JSON:

{
  "data": 
     {
        "translations": 
          [
            {
              "translatedText": "Arbeit"
             }
          ]
     }
}

Google'ın Gson'u kullanarak "Arbeit" gibi "tercüme edilmişText" özniteliğinin değerini almak istiyorum.

İki olası yaklaşım:

  1. Gereken tek bir özelliği alın

    String json  = callToTranslateApi("work", "de");
    JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
    return jsonObject.get("data").getAsJsonObject()
            .get("translations").getAsJsonArray()
            .get(0).getAsJsonObject()
            .get("translatedText").getAsString();
  2. JSON'dan Java nesnesi oluşturma

    class ApiResponse {
        Data data;      
        class Data {
            Translation[] translations;         
            class Translation {
                String translatedText;
            }
         }
     }

    ...

     Gson g = new Gson();
     String json =callToTranslateApi("work", "de");
     ApiResponse response = g.fromJson(json, ApiResponse.class);
     return response.data.translations[0].translatedText;

4

İlk önce bir uygulama kütüphanesi seçmeniz gerekiyor .

JSON İşleme için Java API (JSR 353) dönüşümü oluşturmak ayrıştırmak taşınabilir API'ler sağlar ve sorgu JSON nesne modelini kullanarak ve API'ler akışı.

Referans uygulama burada: https://jsonp.java.net/

Burada JSR 353 uygulamalarının bir listesini bulabilirsiniz :

JSR-353 (JSON) uygulayan API nedir

Karar vermenize yardımcı olmak için ... Bu makaleyi de buldum:

http://blog.takipi.com/the-ultimate-json-library-json-simple-vs-gson-vs-jackson-vs-json/

Jackson'a giderseniz, Jackson'ı kullanarak JSON'dan Java'ya / Java'dan dönüştürme hakkında iyi bir makale: https://www.mkyong.com/java/how-to-convert-java-object-to-from-json- jackson /

Umarım yardımcı olur!


Jackson kütüphanesinin 1. versiyonunu gösteriyorsunuz. Kesinlikle Jackson kütüphanesinin mevcut sürümünü kullanmanızı öneririz.
Herbert Yu

4

Jayway JsonPath'i kullanabilirsiniz . Aşağıda, kaynak kodu, pom ayrıntıları ve iyi belgeler içeren bir GitHub bağlantısı bulunmaktadır.

https://github.com/jayway/JsonPath

Lütfen aşağıdaki adımları izleyin.

Adım 1 : Maven kullanarak jayway JSON yolu bağımlılığını sınıf yolunuza ekleyin veya JAR dosyasını indirin ve manuel olarak ekleyin.

<dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.2.0</version>
</dependency>

Adım 2 : Lütfen JSON girişinizi bu örnek için bir dosya olarak kaydedin. Benim durumumda JSON'unuzu sampleJson.txt olarak kaydettim. PageInfo ve yayınlar arasında virgül attığınızı unutmayın.

Adım 3 : BufferedReader kullanarak yukarıdaki dosyadan JSON içeriğini okuyun ve Dize olarak kaydedin.

BufferedReader br = new BufferedReader(new FileReader("D:\\sampleJson.txt"));

        StringBuilder sb = new StringBuilder();
        String line = br.readLine();

        while (line != null) {
            sb.append(line);
            sb.append(System.lineSeparator());
            line = br.readLine();
        }
        br.close();
        String jsonInput = sb.toString();

Adım 4 : JSON dizenizi jayway JSON ayrıştırıcısını kullanarak ayrıştırın.

Object document = Configuration.defaultConfiguration().jsonProvider().parse(jsonInput);

Adım 5 : Aşağıdaki gibi ayrıntıları okuyun.

String pageName = JsonPath.read(document, "$.pageInfo.pageName");
String pagePic = JsonPath.read(document, "$.pageInfo.pagePic");
String post_id = JsonPath.read(document, "$.posts[0].post_id");

System.out.println("$.pageInfo.pageName " + pageName);
System.out.println("$.pageInfo.pagePic " + pagePic);
System.out.println("$.posts[0].post_id " + post_id);

Çıktı şöyle olacaktır :

$.pageInfo.pageName = abc
$.pageInfo.pagePic = http://example.com/content.jpg
$.posts[0].post_id  = 123456789012_123456789012

3

Ben böyle JSON var:

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    }
}

Java sınıfı

class PageInfo {

    private String pageName;
    private String pagePic;

    // Getters and setters
}

Bu JSON'u bir Java sınıfına dönüştürme kodu.

    PageInfo pageInfo = JsonPath.parse(jsonString).read("$.pageInfo", PageInfo.class);

Uzman

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.2.0</version>
</dependency>

2

JSON dosyalarının yapısını temsil eden Java model sınıfları oluşturmak için Apache @Model ek açıklaması kullanılabilir ve bunları JSON ağacındaki çeşitli öğelere erişmek için kullanabilirsiniz . Diğer çözümlerin aksine bu tamamen yansıtma olmadan çalışır ve bu nedenle yansımanın imkansız olduğu veya önemli ek yük ile geldiği ortamlar için uygundur.

Bir yoktur örnek Maven projesi kullanımını gösteren. Her şeyden önce yapıyı tanımlar:

@Model(className="RepositoryInfo", properties = {
    @Property(name = "id", type = int.class),
    @Property(name = "name", type = String.class),
    @Property(name = "owner", type = Owner.class),
    @Property(name = "private", type = boolean.class),
})
final class RepositoryCntrl {
    @Model(className = "Owner", properties = {
        @Property(name = "login", type = String.class)
    })
    static final class OwnerCntrl {
    }
}

ve sonra sağlanan girdi akışını ayrıştırmak ve bunu yaparken belirli bilgileri almak için oluşturulan RepositoryInfo ve Owner sınıflarını kullanır:

List<RepositoryInfo> repositories = new ArrayList<>();
try (InputStream is = initializeStream(args)) {
    Models.parse(CONTEXT, RepositoryInfo.class, is, repositories);
}

System.err.println("there is " + repositories.size() + " repositories");
repositories.stream().filter((repo) -> repo != null).forEach((repo) -> {
    System.err.println("repository " + repo.getName() + 
        " is owned by " + repo.getOwner().getLogin()
    );
})

İşte bu! Buna ek olarak, senkronize olmayan ağ iletişimi ile birlikte benzer örneği gösteren canlı bir öz .


2

jsoniter(jsoniterator) basit ve hızlı olacak şekilde tasarlanmış nispeten yeni ve basit bir json kütüphanesidir. Json verilerinin serileştirilmesini kaldırmak için tek yapmanız gereken

JsonIterator.deserialize(jsonData, int[].class);

nerede jsonDatabir json veri dizisidir.

Check out resmi web Daha fazla bilgi için.


1

JSON dizesini JSON nesnesine dönüştürmek ve JSON nesnesi üzerinde yineleme yapmak için JSONObject sınıfını kullanabiliriz. Aşağıdaki kodu kullanın.

JSONObject jObj = new JSONObject(contents.trim());
Iterator<?> keys = jObj.keys();

while( keys.hasNext() ) {
  String key = (String)keys.next();
  if ( jObj.get(key) instanceof JSONObject ) {           
    System.out.println(jObj.getString(String key));
  }
}

2
Bu sadece android
Mayubomír


1
@DototCanniffe sadece Android.
user4020527

1

Karmaşık json ve XML belgesini ayrıştırmak için DSM akış ayrıştırma kitaplığını kullanabilirsiniz . DSM verileri yalnızca bir kez ayrıştırır ve tüm verileri belleğe yüklemez.

Diyelim ki Sayfa var verilen json verilerinin serileştirmesini kaldırmak sınıfımız .

Sayfa sınıfı

public class Page {
    private String pageName;
    private String pageImage;
    private List<Sting> postIds;

    // getter/setter

}

Bir yaml Eşleme dosyası oluşturun.

result:
  type: object     # result is array
  path: /posts
  fields:
    pageName:
        path: /pageInfo/pageName
    pageImage:
        path: /pageInfo/pagePic
    postIds:
      path: post_id
      type: array

Alanları ayıklamak için DSM kullanın.

DSM dsm=new DSMBuilder(new File("path-to-yaml-config.yaml")).create(Page.class);
Page page= (Page)dsm.toObject(new path-to-json-data.json");

json'a serileştirilmiş sayfa değişkeni:

{
  "pageName" : "abc",
  "pageImage" : "http://example.com/content.jpg",
  "postIds" : [ "123456789012_123456789012" ]
}

DSM, karmaşık json ve xml için çok iyidir.


0

JsonNodeJSON dizenizin yapılandırılmış bir ağaç temsili için kullanabilirsiniz . Her yerde bulunan kaya gibi sağlam jackson kütüphanesinin bir parçası .

ObjectMapper mapper = new ObjectMapper();
JsonNode yourObj = mapper.readTree("{\"k\":\"v\"}");
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.