2010-09-22 29 views
12

Tôi đang sử dụng gson để phân tích cú pháp json thành hạt java. Đối với API tôi đang sử dụng, một số lượng lớn các kết quả json bao gồm kết quả là thuộc tính đầu tiên của một đối tượng json. Cách "gson" dường như là tạo một đối tượng java bao bọc tương đương, có một thuộc tính cho kiểu kết quả đích - nhưng điều này dẫn đến các lớp throwaway không cần thiết. Có cách thực hành tốt nhất để làm điều này không?Cách dễ nhất để phân tích cú pháp json bằng cách sử dụng gson khi phần tử phân tích cú pháp là thành phần của chuỗi json là gì?

Ví dụ để phân tích: {"profile":{"username":"nickstreet","first_name":"Nick","last_name":"Street"}}

tôi phải làm:

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

Tất nhiên một cách tiếp cận khác để sử dụng một container sẽ tự loại bỏ phần ngoài của chuỗi (tức là loại bỏ "hồ sơ": {và đóng}) bằng cách sử dụng các kỹ thuật phân tích cú pháp chuỗi tiêu chuẩn, nhưng điều này giống như cách tiếp cận sai.

Tôi muốn để có thể làm điều gì đó như:

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

This issue cho thấy chúng ta có thể phá vỡ một chuỗi json lên thành một đối tượng JSON, để kéo ra một jsonElement từ đối tượng này, và vượt qua nó vào json.fromJson(). Tuy nhiên, phương thức toJsonElement() chỉ hoạt động trên một đối tượng java, không phải là một chuỗi json.

Có ai có cách tiếp cận tốt hơn không?

Trả lời

8

Tôi đã gặp sự cố tương tự. Về cơ bản những gì bạn làm để tránh tất cả các lớp vô nghĩa của container là chỉ sử dụng các hàm JSONObject để lấy đối tượng bên trong mà bạn đang cố gắng deserialize. Hãy tha thứ cho tôi vì mã cẩu thả nhưng nó giống như sau:

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(); 
} 
+2

Cảm ơn bạn đã phản hồi. Nó không phải là khá chính xác, nhưng nó đã dẫn tôi đến câu trả lời đúng. Bạn không thể trực tiếp tạo một JsonObject bằng một chuỗi, bạn phải sử dụng JsonParser để tạo nó. JsonParser parser = new JsonParser(); JsonObject j = (JsonObject) parser.parse (json); –

Các vấn đề liên quan