【问题标题】:How to not use nested try catch blocks when parsing JSON?解析 JSON 时如何不使用嵌套的 try catch 块?
【发布时间】:2015-06-30 22:17:55
【问题描述】:

对于下面的代码,有没有比为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(); }
    }

【问题讨论】:

  • 如果您不关心异常,请使用返回类型适当地制作单个方法和参数。方法的参数将是您在上述代码中用于查找的 KEY。
  • 您要检查每个字段是否继续,否则停止解析?
  • @Nambari 我确实关心异常。我想看看日志中出了什么问题。
  • @SafwanHijazi 我希望每个键解析都相互独立。因此,如果它缺少一个键,我希望它继续。
  • 您可以简单地登录,我的建议仍然有效。

标签: java android json try-catch


【解决方案1】:

您的所有if 语句似乎都在做类似的事情:

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

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

【讨论】:

    【解决方案2】:

    如果您使用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;
    
        }
    }
    

    【讨论】:

    • 这可能是最简单的解决方案,也很快。谢谢!
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 2019-04-23
    • 2022-01-01
    • 1970-01-01
    相关资源
    最近更新 更多