Gson: напрямую конвертировать строку в JsonObject (без POJO)


301

Не могу понять это. Я пытаюсь манипулировать деревом 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/…
Вадим

Ответы:


526

использовать JsonParser; например:

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

17
тьфу должен иметь статический метод удобства 1 лайнера
Blundell

43
приведение к JsonObject не нужно, лучше использоватьnew JsonParser().parse(..).getAsJsonObject();
Chriss

1
Я думаю, JsonParser - абстрактный класс
Джатин Сегал,

1
@KevinMeredith ваша ссылка не работает, используйте это, пожалуйста
Ninja

4
Обратите внимание, что этот метод устарел. Использование JsonParser.parseString(str).getAsJsonObject().
Михаэль Рёриг

147

Попробуйте использовать getAsJsonObject()вместо прямого броска, используемого в принятом ответе:

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

2
По какой-то причине он оборачивается membersродительским ключом. Вот пример {"members": {"key1": "13756963814f2c594822982c0307fb81", "key2": true, "key3": 123456789}}
Хоссейн Хан

1
Используйте последнюю библиотеку gson, например 2.2.4. Версия как 2.2.2 по какой-то причине добавляет тэг members.
Рубин Ю

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определение класса? Это происходит из библиотеки Google Gson. Вы можете обратиться к документации здесь .
Пурушотам

Это дает мне ошибку с жалобой на то, что JsonElement не имеет конструктора без аргументов.
Клапа

37

Самый простой способ - использовать JsonPrimitiveкласс, который наследуется JsonElement, как показано ниже:

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

2
Это самый простой ответ и выручил меня. Спасибо!
khiner

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.

Строка от клиента: [{"property": "COLUMN_NAME", "direction": "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.
Мэдди

1
Спасибо, в моем случае у меня была непарсированная строка JSON, с которой мне нужно было начать.
7zark7
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.