如何在解析 JSON 时不使用嵌套的 try catch 块?

How to not use nested try catch blocks when parsing JSON?

下面的代码是否有比 JSONException 的多个嵌套 try-catch 块更优雅的解决方案?

我嵌套它们的原因是因为我不想在解析中出现一个错误时停止其余的解析。我希望每个人都相互独立。

if (obj.has(GlobalVars.KEY_DESC)) {
        try {
            JSONObject descObj = obj.getJSONObject(GlobalVars.KEY_DESC);

            if (descObj.has(GlobalVars.KEY_COUNTRY)) {
                try {
                    description.put(GlobalVars.KEY_COUNTRY, descObj.getString(GlobalVars.KEY_COUNTRY));
                }
                catch (JSONException e) { e.printStackTrace(); }
            }

            if (descObj.has(GlobalVars.KEY_CITY)) {
                try {
                    description.put(GlobalVars.KEY_COUNTRY, descObj.getString(GlobalVars.KEY_CITY));
                }
                catch (JSONException e) { e.printStackTrace(); }
            }

            if (descObj.has(GlobalVars.KEY_POSTAL)) {
                try {
                    description.put(GlobalVars.KEY_COUNTRY, descObj.getString(GlobalVars.KEY_POSTAL));
                }
                catch (JSONException e) { e.printStackTrace(); }
            }

            if (descObj.has(GlobalVars.KEY_STREET)) {
                try {
                    description.put(GlobalVars.KEY_COUNTRY, descObj.getString(GlobalVars.KEY_STREET));
                }
                catch (JSONException e) { e.printStackTrace(); }
            }

            if (descObj.has(GlobalVars.KEY_SUBSTREET)) {
                try {
                    description.put(GlobalVars.KEY_COUNTRY, descObj.getString(GlobalVars.KEY_SUBSTREET));
                }
                catch (JSONException e) { e.printStackTrace(); }
            }

            if (descObj.has(GlobalVars.KEY_YEAR)) {
                try {
                    description.put(GlobalVars.KEY_COUNTRY, descObj.getInt(GlobalVars.KEY_YEAR));
                }
                catch (JSONException e) { e.printStackTrace(); }
            }

            if (descObj.has(GlobalVars.KEY_SQUARE_METERS)) {
                try {
                    description.put(GlobalVars.KEY_COUNTRY, descObj.getInt(GlobalVars.KEY_SQUARE_METERS));
                }
                catch (JSONException e) { e.printStackTrace(); }
            }
        }
        catch (JSONException e) { e.printStackTrace(); }
    }

您似乎在所有 if 陈述中都在做类似的事情:

            try {
                description.put(GlobalVars.KEY_COUNTRY, descObj.getString(GlobalVars.KEY_COUNTRY));
            }
            catch (JSONException e) { e.printStackTrace(); }

因此您可以将这段代码移到一个方法中,并可以从每个 if 语句中调用该方法。它会让你的代码更干净

我认为如果你使用 Gson lib,你不需要使用所有这些 try catch,它会忽略丢失的字段并继续解析,但你可以使用以下代码注册丢失的字段:

package json;

import java.lang.reflect.Field;
import java.lang.reflect.Type;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;

public class App {

    public static void main(String[] args) {
        Gson gson = new GsonBuilder().registerTypeAdapter(
                MyAnnotationBean.class,
                new AnnotatedDeserializer<MyAnnotationBean>()).create();

        String json = "{\"desc\":\"This is desc\",\"country\":\"this is country\"}";
        MyAnnotationBean tab = gson.fromJson(json, MyAnnotationBean.class);
        System.out.println(tab.desc);
        System.out.println(tab.country);

        json = "{\"desc\":\"This is desc\"}";
        tab = gson.fromJson(json, MyAnnotationBean.class);
        System.out.println(tab.desc);
        System.out.println(tab.country);

        json = "{\"country\":\"This is country\"}";
        tab = gson.fromJson(json, MyAnnotationBean.class);
        System.out.println(tab.desc);
        System.out.println(tab.country);
    }
}


class MyAnnotationBean {
    public String desc;
    public String country;
}

class AnnotatedDeserializer<T> implements JsonDeserializer<T> {

    public T deserialize(JsonElement je, Type type,
            JsonDeserializationContext jdc) throws JsonParseException {
        T obj = new Gson().fromJson(je, type);

        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field f : fields) {
                try {
                    f.setAccessible(true);
                    if (f.get(obj) == null) {
//                       throw new JsonParseException("required json " +
//                       f.getName());

                        // add your code to know missing fields
                    }
                } catch (IllegalArgumentException ex) {
                    ex.printStackTrace();
                } catch (IllegalAccessException ex) {
                    ex.printStackTrace();
                }
        }
        return obj;

    }
}