Gson: Пряме перетворення рядка в JsonObject (без POJO)


300

Не можу цього зрозуміти. Я намагаюся маніпулювати деревом JSON в GSON, але у мене є випадок, коли я не знаю або не маю POJO для перетворення рядка до перетворення в JsonObject. Чи є спосіб перейти безпосередньо від точки Stringдо JsonObject?

Я спробував таке (синтаксис Scala):

val gson = (new GsonBuilder).create

val a: JsonObject = gson.toJsonTree("""{ "a": "A", "b": true }""").getAsJsonObject
val b: JsonObject = gson.fromJson("""{ "a": "A", "b": true }""", classOf[JsonObject])

але aне вдається, JSON виходить і аналізується як JsonStringєдиний, і bповертається порожнім JsonObject.

Будь-які ідеї?


1
Остерігайтеся пасток перевірки gson: stackoverflow.com/questions/43233898 / ...
Вадиму

Відповіді:


525

використовувати JsonParser; наприклад:

JsonParser parser = new JsonParser();
JsonObject o = parser.parse("{\"a\": \"A\"}").getAsJsonObject();

17
ugh повинен мати статичний метод зручності 1 вкладиша
Блонделл

43
акторський склад в JsonObject не потрібний, краще використовуватиnew JsonParser().parse(..).getAsJsonObject();
Chriss

1
Я здогадуюсь, JsonParser - це абстрактний клас
Джатін Сеггал

1
@KevinMeredith зв'язування зламано, використовуйте цей будь ласка
Ninja

4
Зауважте, що цей метод зараз застарілий. Використовуйте JsonParser.parseString(str).getAsJsonObject().
Michael

147

Спробуйте використовувати getAsJsonObject()замість прямої ролі, що використовується у прийнятій відповіді:

JsonObject o = new JsonParser().parse("{\"a\": \"A\"}").getAsJsonObject();

2
Чомусь він завершується membersбатьківським ключем. Ось зразок {"members": {"key1": "13756963814f2c594822982c0307fb81", "key2": true, "key3": 123456789}}
Hossain Khan

1
Використовуйте останню бібліотеку gson, як-от 2.2.4. Версія на зразок 2.2.2 чомусь додає теги членів.
Рубін Йо

2
JsonParser (). Parse () застарілий у нових версіях Gson. Використовуйте JsonObject jsonObj = JsonParser.parseString(str).getAsJsonObject()або Gson gson = new Gson(); JsonElement element = gson.fromJson (jsonStr, JsonElement.class); JsonObject jsonObj = element.getAsJsonObject();
Джиммі Гарпеялл

54
String jsonStr = "{\"a\": \"A\"}";

Gson gson = new Gson();
JsonElement element = gson.fromJson (jsonStr, JsonElement.class);
JsonObject jsonObj = element.getAsJsonObject();

Ви можете перевірити мою відповідь з GSON способом для даних списку новонаверненого JSONObject по gson stackoverflow.com/questions/18442452 / ...
LOG_TAG

3
Я підтвердив вашу відповідь.
Пурушотам

@knoxxs, Ви маєте на увазі JsonObjectвизначення класу? Походить з бібліотеки Gson Google. Документацію можна посилатись тут .
Пурушотхам

Це дає мені помилку скаржитися на те, що JsonElement не має конструктора без аргументів.
клапас

37

Найпростіший спосіб - використовувати JsonPrimitiveклас, який походить від JsonElement, як показано нижче:

JsonElement element = new JsonPrimitive(yourString);
JsonObject result = element.getAsJsonObject();

2
Це найпростіша відповідь і допомогла мені. Дякую!
Кінер

11

Щойно стикалися з тією ж проблемою. Ви можете написати тривіальний спеціальний десеріалізатор для JsonElementкласу:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

GsonBuilder gson_builder = new GsonBuilder();
gson_builder.registerTypeAdapter(
        JsonElement.class,
        new JsonDeserializer<JsonElement>() {
            @Override
            public JsonElement deserialize(JsonElement arg0,
                    Type arg1,
                    JsonDeserializationContext arg2)
                    throws JsonParseException {

                return arg0;
            }
        } );
String str = "{ \"a\": \"A\", \"b\": true }";
Gson gson = gson_builder.create();
JsonElement element = gson.fromJson(str, JsonElement.class);
JsonObject object = element.getAsJsonObject();

4

Я вважаю, що це більш простий підхід:

public class HibernateProxyTypeAdapter implements JsonSerializer<HibernateProxy>{

    public JsonElement serialize(HibernateProxy object_,
        Type type_,
        JsonSerializationContext context_) {
        return new GsonBuilder().create().toJsonTree(initializeAndUnproxy(object_)).getAsJsonObject();
        // that will convert enum object to its ordinal value and convert it to json element

    }

    public static <T> T initializeAndUnproxy(T entity) {
        if (entity == null) {
            throw new 
               NullPointerException("Entity passed for initialization is null");
        }

        Hibernate.initialize(entity);
        if (entity instanceof HibernateProxy) {
            entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer()
                    .getImplementation();
        }
        return entity;
    }
}

І тоді ви зможете назвати це так:

Gson gson = new GsonBuilder()
        .registerTypeHierarchyAdapter(HibernateProxy.class, new HibernateProxyTypeAdapter())
        .create();

Таким чином, всі сплячі об'єкти будуть перетворені автоматично.


3

JsonParserКонструктор застарів. Використовуйте замість статичного методу:

JsonObject asJsonObject = JsonParser.parseString(request.schema).getAsJsonObject();

2

Сходився сценарій з дистанційним сортуванням зберігання даних у EXTJS 4.X, де рядок надсилається серверу у вигляді масиву JSON (всього 1 об’єкт).
Подібний підхід до того, що представлено раніше для простого рядка, просто потребує перетворення в JsonArray спочатку до JsonObject.

Рядок від клієнта: [{"властивість": "COLUMN_NAME", "напрям": "ASC"}]

String jsonIn = "[{\"property\":\"COLUMN_NAME\",\"direction\":\"ASC\"}]";
JsonArray o = (JsonArray)new JsonParser().parse(jsonIn);

String sortColumn = o.get(0).getAsJsonObject().get("property").getAsString());
String sortDirection = o.get(0).getAsJsonObject().get("direction").getAsString());

1
//import com.google.gson.JsonObject;  
JsonObject complaint = new JsonObject();
complaint.addProperty("key", "value");

Вище - це найпростіший спосіб перетворити ваші ключові значення в об’єкт gson.
Maddy

1
Дякую, у моєму випадку у мене була непарна струна JSON, з якої мені потрібно було почати.
7zark7
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.