Подтвердить что ты не робот

Каков самый простой способ проанализировать json с помощью gson, когда элемент для синтаксического анализа является элементом строки json?

Я использую gson для анализа json в java beans. Для API, который я использую, большое количество результатов json включает результат как первое свойство объекта json. Кажется, что "gson way" создает эквивалентный объект-оболочку java, который имеет одно свойство для целевого типа вывода, но это приводит к ненужным классам выброса. Есть ли лучший способ сделать это?

Например, для синтаксического анализа: {"profile":{"username":"nickstreet","first_name":"Nick","last_name":"Street"}}

Мне нужно сделать:

public class ParseProfile extends TestCase {
    public void testParseProfile() {
        Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
        String profileJson = "{\"profile\":{\"username\":\"nickstreet\",\"first_name\":\"Nick\",\"last_name\":\"Street\"}}";
        ProfileContainer profileContainer = gson.fromJson(profileJson, ProfileContainer.class);
        Profile profile = profileContainer.getProfile();
        assertEquals("nickstreet", profile.username);
        assertEquals("Nick", profile.firstName);
        assertEquals("Street", profile.lastName);
    }
}

public class ProfileContainer {
    protected Profile profile;

    public Profile getProfile() {
        return profile;
    }

    public void setProfile(Profile profile) {
        this.profile = profile;
    }
}

public class Profile {
    protected String username;
    protected String firstName;
    protected String lastName;

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

Конечно, альтернативный подход к использованию контейнера заключался бы в том, чтобы вручную удалить внешнюю часть строки (т.е. удалить "профиль": {и закрыть}) с использованием стандартных методов синтаксического анализа строк, но это похоже на неправильный подход.

Я хотел бы сделать что-то вроде:

Profile p = gson.fromJsonProperty(json, Profile.class, "profile");

Эта проблема предполагает, что должно быть возможно разбить строку json в json-объект, вытащить jsonElement из этого объекта и перейдите в json.fromJson(). Однако метод toJsonElement() работает только с java-объектом, а не с json-строкой.

Есть ли у кого лучший подход?

4b9b3361

Ответ 1

Я столкнулся с той же проблемой. В основном, что вы делаете, чтобы избежать всякой ерунды класса контейнера, просто использовать функции JSONObject для извлечения внутреннего объекта, который вы пытаетесь десериализовать. Простите меня за неаккуратный код, но он выглядит примерно так:

GsonBuilder gsonb = new GsonBuilder()
Gson gson = gsonb.create();

JSONObject j;
JSONObject jo;

Profile p = null;

try {

    j = new JSONObject(convertStreamToString(responseStream));
    jo = j.getJSONObject("profile"); // now jo contains only data within "profile"
    p = gson.fromJson(jo.toString(), Profile.class);
    // now p is your deserialized profile object
}catch(Exception e) {
    e.printStackTrace();
}