Перетворення даних JSON в об'єкт Java


262

Я хочу мати доступ до властивостей із рядка JSON в рамках мого методу дії Java. Рядок доступний, просто кажучи myJsonString = object.getJson(). Нижче наведено приклад того, як може виглядати рядок:

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

У цьому рядку кожен об'єкт JSON містить масив інших об'єктів JSON. Наміром є отримання списку ідентифікаторів, коли будь-який даний об'єкт має групову властивість, що містить інші об'єкти JSON. Я розглядав Gson Google як потенційний плагін JSON. Чи може хтось запропонувати певну форму вказівки щодо того, як я можу генерувати Java із цієї рядки JSON?



Відповіді:


329

Я розглядав Gson Google як потенційний плагін JSON. Чи може хтось запропонувати певну форму вказівки щодо того, як я можу генерувати Java із цієї рядки JSON?

Google Gson підтримує дженерики та вкладені боби. []У JSON являє собою масив , і повинен відображатися в колекції Java , такі як Listабо просто звичайний масив Java. The{} JSON являє собою об'єкт і має відображатись на Java Mapабо просто якийсь клас JavaBean.

У вас є об'єкт JSON з кількома властивостями, groupsвластивість якого представляє масив вкладених об'єктів того самого типу. Це можна проаналізувати з Gson наступним чином:

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

Досить просто, чи не так? Просто мати підходящий JavaBean і зателефонуватиGson#fromJson() .

Дивитися також:


4
Виконавець? Ви насправді це виміряли? Незважаючи на те, що GSON має розумний набір функцій, я вважав, що продуктивність є слабкою точкою (відповідно до [ cowtowncoder.com/blog/archives/2009/09/entry_326.html] ) Щодо прикладу: я вважав, що GSON не дуже потребує сеттерів, і базувався на полях. Тож код можна було б трохи спростити.
StaxMan

3
Я використовую його в додатку для Android. Це не найшвидше рішення, але це досить просто програмування, щоб виправдати недостатню продуктивність для користувача до цих пір. Можливо, в пізнішій версії програми це буде видалено для швидшого вирішення.
Януш

1
Швидкість Wrt, якщо вона досить швидка, вона досить швидка. Я просто прокоментував посилання на очікувані хороші показники. Мудрий Джексон набір функцій обробляє все ті ж гніздування, розшарування, генеричні засоби, тому різниця в швидкості не походить від цього. Наявність геттерів та сеттерів не впливає на продуктивність жодним чином, що вимірюється (для пакетів, про які я знаю), тому, безумовно, можна їх мати там.
StaxMan

97
+1 для "пакета com.stackoverflow.q1688099;". Чомусь це змусило мене посміятися.
GargantuChet

1
public String toString () {return new Gson (). toJson (this); // Використовуйте це замість написання кожної змінної}
Пракаш

45

Осторонь Гсона! Це дуже здорово, дуже здорово, але друге ви хочете зробити що - небудь крім простих об'єктів, ви можете легко потрібно почати будувати свої власні серіалізатор (який не є , що важко).

Крім того, якщо у вас є масив Об'єктів, і ви десеріалізуєте деякий json в цей масив Об'єктів, справжні типи ПОСЛУГАНО! Повні об'єкти навіть не будуть скопійовані! Використовуйте XStream .. Що, якщо використовувати jsondriver та встановити належні налаштування, буде кодувати некрасиві типи у фактичний json, щоб ви нічого не втрачали. Невелика ціна, яку потрібно заплатити (потворний json) за справжню серіалізацію.

Зауважте, що Джексон виправляє ці проблеми та швидше, ніж GSON.


2
Я написав вилку Gson, яка виправляє ці проблеми (і уникає всіх приміток Джексона): github.com/winterstein/flexi-gson
Daniel Winterstein

26

Як не дивно, єдиний пристойний процесор JSON, згаданий до цього часу, був GSON.

Ось більш хороший вибір:

  • Джексон ( Github ) - потужне прив'язування даних (JSON до / з POJO), потокове (надшвидке), дерево модель (зручно для нетипізованого доступу)
  • Flex-JSON - серійні налаштування, які можна легко налаштувати

EDIT (серп. / 2013):

Ще одне, що слід врахувати:

  • Genson - функціональність, схожа на Jackson, спрямована на простіше налаштування розробником

15

Або з Джексоном:

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

Це призведе до помилки не може знецінити екземпляр java.util.HashSet з START_OBJECT маркера
Dipen Chawla

7

Якщо будь-якими змінами ви знаходитесь у програмі, яка вже використовує http://restfb.com/, ви можете:

import com.restfb.json.JsonObject;

...

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

тощо.


ваше рішення коротше і зрозуміліше, чому він отримує лише 3 оновлення? Чи щось не так?
Джефф

4

Легкий і працює Java - код для перетворення JSONObjectвJava Object

Співробітник.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());

    }
}

Як отримати доступ до цих властивостей json в JSP?
Zoran777

Якщо ви не хочете використовувати його на сторінці JSP, код залишається тим самим. Клас Employee.java буде таким же, як є. Але Код, написаний на LoadFromJSON.java, буде скопійовано на сторінку jsp при належному імпорті кожного класу. Відпочинок взагалі не зміниться.
Рахул Райна

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

Якщо ви використовуєте будь-які спеціальні карти з ключами або значеннями, також спеціальні карти, ви побачите, що це не передбачається реалізацією google.


2

Що не так із стандартними речами?

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

це надзвичайно повільно: нещодавно на роботі github.com/fabienrenaud/java-json-benchmark я подвоїв продуктивність (скорочення використання процесора навпіл, скорочення затримки) на наших серверах prod, перемикаючи всі сервіси org.json / десеріалізація використовувати Джексона.
fabien

0

Спробуйте спробувати:

https://github.com/RichardHightower/boon

Це нечестиво швидко:

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

Не сприймайте мого слова на це ... перевірте контрольний показник.

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

(До чотирьох разів - це випадки, і тест із 100-х років. Також він має режим накладання індексу, який ще швидший. Він молодий, але вже має деяких користувачів.)

Він може проаналізувати JSON на «Картах» та «Списках» швидше, ніж будь-яка інша версія може проаналізувати JSON DOM, і це не в режимі індексу накладання У режимі накладення індексу Boon це ще швидше.

Він також має дуже швидкий розслаблений режим JSON та режим парсингу PLIST. :) (і має надто низьку пам'ять, безпосередньо з байтового режиму з кодуванням UTF-8 на льоту).

Він також має найшвидший JSON в режимі JavaBean.

Це нове, але якщо швидкість і простий API - це те, що ви шукаєте, я не думаю, що існує більш швидкий або мінімалістичний API.


чи можете ви надати посилання на актуальну документацію для останньої версії? На сьогоднішній день я знайшов 0,4, але не можу легко знайти відповідне посилання на документ або підручник для цієї версії. Спасибі
Bizmarck

Ось підручник github.com/RichardHightower/boon/wiki/Boon-JSON-in-five-minutes Boon знаходиться в репортажі громадського Maven. Це на рівні 0,27 або близько того.
RickHigh

richardhightower.github.io/site/releases має 0,4, тому я подумав, що це останнє. Я перевіряв Boon для проекту на роботі, чи він має анотацію, аналогічну Джексону @JsonIgnore?
Bizmarck

boon знаходиться на нижньому кінці продукту ser / deserialization : github.com/fabienrenaud/java-json-benchmark Виберіть Джексона або dsljson для продуктивності. @RickHigh: Я не міг відкрити проблему щодо вашого github, я більше ніж готовий покращити свій показник або виправити його тлумачення, якщо в цьому є щось не так / що-то я пропустив.
fabien

0

Залежно від вхідного формату JSON (рядок / файл) створіть jSONString. Об'єкт класу зразкового повідомлення, що відповідає JSON, можна отримати, як показано нижче:

Повідомлення msgFromJSON = новий ObjectMapper (). ReadValue (jSONString, Message.class);


0

Найпростіший спосіб полягає в тому, що ви можете використовувати цей метод softconvertvalue, який є спеціальним методом, за допомогою якого ви можете перетворити jsonData у свій конкретний клас Dto.

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);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.