3

我有以下 json

"notes": {"note": [
         {
             "content": "Having wisdom teeth removed.",
             "from": "employee"
         },
         {
             "content": "Get well soon",
             "from": "manager"
         }
     ]},

问题是价值也可以

 "notes": "",

或者

"notes": {"note": {
            "content": "This is a test note.",
            "from": "employee"
        }},

并将其存储在这些

public  class Notes
{
    @SerializedName ("note")
    public List<Note> note;
}
public  class Note
{
    @SerializedName ("content")
    public String content;
    @SerializedName ("from")
    public String from;
}

我相信我通过这样做解决了不是数组而是单个对象的问题

public class Json {
    private static Gson gson;

    private static class MyNoteClassTypeAdapter implements JsonDeserializer<List<RequestsDTO.Note>> {
        public List<RequestsDTO.Note> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx) {
            List<RequestsDTO.Note> vals = new ArrayList<RequestsDTO.Note>();
            if (json.isJsonArray()) {
                for (JsonElement e : json.getAsJsonArray()) {
                    vals.add((RequestsDTO.Note) ctx.deserialize(e, RequestsDTO.Note.class));
                }
            } else if (json.isJsonObject()) {
                vals.add((RequestsDTO.Note) ctx.deserialize(json,RequestsDTO.Note.class));
            } else {
                throw new RuntimeException("Unexpected JSON type: " + json.getClass());
            }
            return vals;
        }
    }

    public static Gson getGson()
    {
        if (gson == null)
        {
            Type ListType = new TypeToken<List<RequestsDTO.Note>>() {}.getType();
            GsonBuilder builder = new GsonBuilder();
            builder.registerTypeAdapter(DateTime.class, new DateTimeSerializer());
            builder.registerTypeAdapter(ListType, new MyNoteClassTypeAdapter());
            gson = builder.create();
        }
        return gson;
    }
}

现在,当整个事情以字符串的形式返回时,我被困住了……

4

3 回答 3

2

请参阅下面的代码片段以使用 Gson 库反序列化您的 json,无一例外。

String jsonStr = "your json string ";

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

JsonElement elem = jsonObj.get("note");

if(elem.isJsonArray()) { //**Array**
    List<Note> notelist = gson.fromJson(elem.toString(), new TypeToken<List<Note>>(){}.getType());
} else if(elem.isJsonObject()) { //**Object**
    Note note = gson.fromJson(elem.toString(), Note.class);
} else {  //**String**
    String note = elem.toString();
}
于 2014-01-31T11:46:54.357 回答
1

The idea is try to get "note" field (from "notes" JSONObject) as JSONArray first and if it throws exception that will mean that there is no "note" JSONArray into "notes" JSONObject and that will mean that "note" is JSONObject. The same way we can figure out situation when note field is String.

try {
        //String jsonString="{\"notes\": {\"note\": [{\"content\": \"Having wisdom teeth removed.\",\"from\": \"employee\" }, {\"content\": \"Get well soon\", \"from\": \"manager\"} ] }}";
        //String jsonString="{\"notes\": { \"note\": {\"content\": \"This is a test note.\",\"from\": \"employee\"}}}";
        String jsonString="{\"notes\": { \"note\": \"\"}}";

        JSONObject jsonObject=new JSONObject(jsonString);
        JSONObject jsonObjectNotes=jsonObject.getJSONObject("notes");

        try{
            JSONArray jsonArrayNote=jsonObjectNotes.getJSONArray("note");
            for (int i = 0; i < jsonArrayNote.length(); i++) {

                JSONObject jsonObject2= jsonArrayNote.getJSONObject(i);
                String stringContent=jsonObject2.getString( "content");
                String stringFrom= jsonObject2.getString( "from");

                Log.e(getClass().getName(), "content="+stringContent +"; from="+stringFrom);
            }
        }
        catch(JSONException e){
            //that means that jsonObjectNotes has no jsonArray with name "notes" and "notes" is jsonObject
            try{
                JSONObject jsonObject3=jsonObjectNotes.getJSONObject("note");

                String stringContent=(String) jsonObject3.get( "content");
                String stringFrom=(String) jsonObject3.get( "from");

                Log.e(getClass().getName(), "content="+stringContent +"; from="+stringFrom);
            }
            catch(JSONException ex){
                //that means that jsonObjectNotes has no jsonObject with name "notes" and "notes" is empty String
                String stringNote=jsonObjectNotes.getString("note") ;       
                Log.e(getClass().getName(), "note is string ="+ stringNote);
            }
        }

    } catch (JSONException e) {
        e.printStackTrace();
    }

In my example code another get operations can also throw jsonExceptions but I think you get the idea.

于 2012-11-08T06:04:40.627 回答
0

看看 Genson 库http://code.google.com/p/genson/。如果您的类是内部类,请将它们设为静态。以下代码应该可以解决您的问题。

Genson genson = new Genson.Builder().withDeserializerFactory(new NotesDeserializerFactory()).create();
Notes notes = genson.deserialize(in, Notes.class);

// Define a factory so you can delegate the deserialization to existing mechanisms for lists and beans
class NotesDeserializerFactory implements Factory<Deserializer<Notes>> {

    @Override
    public Deserializer<Notes> create(Type type, Genson genson) {
        Converter<List<Note>> noteListConverter = genson.provideConverter(new GenericType<List<Note>>() {}.getType());
        Converter<Note> noteConverter = genson.provideConverter(Note.class);
        return new NotesDeserializer(noteListConverter, noteConverter);
    }

}

// define an implementation for you Notes class so you can handle the different cases
class NotesDeserializer implements Deserializer<Notes> {
    private final Converter<List<Note>> noteListConverter;
    private final Converter<Note> noteConverter;

    public NotesDeserializer(Converter<List<Note>> noteListConverter,
            Converter<Note> noteConverter) {
        this.noteListConverter = noteListConverter;
        this.noteConverter = noteConverter;
    }

    @Override
    public Notes deserialize(ObjectReader reader, Context ctx) throws TransformationException,
            IOException {
        Notes notes = new Notes();
        if (reader.getValueType() == ValueType.ARRAY) notes.note = noteListConverter.deserialize(reader, ctx);
        else if (reader.getValueType() == ValueType.OBJECT) notes.note = Arrays.asList(noteConverter.deserialize(reader, ctx));
        else { // it is a litteral (string, numeric, boolean, null)
            notes.note = new ArrayList<Note>();
        }
        return notes;
    }
}
于 2012-11-08T10:05:57.130 回答