如何在JSONArray中正确嵌套数组

时间:2017-06-14 13:40:25

标签: java android arrays

我是Android新手,并且在如何处理从API here检索到的数据方面遇到了困难。这是一个食谱。以下是一个例子。我正在努力的是创建一个jsonArray的所有项目,我可以用它来显示配方的详细视图中的成分和步骤。我可以获得id和名称,单个项目很好,特别是较大的配方数组中的成分和步骤数组是我不太正确的。

[{"id":2,
 "name":"Brownies",
 "ingredients":[{"quantity":350,"measure":"G","ingredient":"Bittersweet chocolate (60-70% cacao)"},
     {"quantity":226,"measure":"G","ingredient":"unsalted butter"},
     {"quantity":300,"measure":"G","ingredient":"granulated sugar"},
     {"quantity":100,"measure":"G","ingredient":"light brown sugar"},
     {"quantity":5,"measure":"UNIT","ingredient":"large eggs"},
     {"quantity":1,"measure":"TBLSP","ingredient":"vanilla extract"},
     {"quantity":140,"measure":"G","ingredient":"all purpose flour"},
     {"quantity":40,"measure":"G","ingredient":"cocoa powder"},
     {"quantity":1.5,"measure":"TSP","ingredient":"salt"},
     {"quantity":350,"measure":"G","ingredient":"semisweet chocolate chips"}],
 "steps":[{"id":0,"shortDescription":"Recipe Introduction","description":"Recipe Introduction","videoURL":"https:\/\/d17h27t6h515a5.cloudfront.net\/topher\/2017\/April\/58ffdc33_-intro-brownies\/-intro-brownies.mp4","thumbnailURL":""},
     {"id":1,"shortDescription":"Starting prep","description":"1. Preheat the oven to 350�F. Butter the bottom and sides of a 9\"x13\" pan.","videoURL":"","thumbnailURL":""},
     {"id":2,"shortDescription":"Melt butter and bittersweet chocolate.","description":"2. Melt the butter and bittersweet chocolate together in a microwave or a double boiler. If microwaving, heat for 30 seconds at a time, removing bowl and stirring ingredients in between.","videoURL":"https:\/\/d17h27t6h515a5.cloudfront.net\/topher\/2017\/April\/58ffdc43_1-melt-choclate-chips-and-butter-brownies\/1-melt-choclate-chips-and-butter-brownies.mp4","thumbnailURL":""},
     {"id":3,"shortDescription":"Add sugars to wet mixture.","description":"3. Mix both sugars into the melted chocolate in a large mixing bowl until mixture is smooth and uniform.","videoURL":"","thumbnailURL":""},
     {"id":4,"shortDescription":"Mix together dry ingredients.","description":"4. Sift together the flour, cocoa, and salt in a small bowl and whisk until mixture is uniform and no clumps remain. ","videoURL":"https:\/\/d17h27t6h515a5.cloudfront.net\/topher\/2017\/April\/58ffdc9e_4-sift-flower-add-coco-powder-salt-brownies\/4-sift-flower-add-coco-powder-salt-brownies.mp4","thumbnailURL":""},{"id":5,"shortDescription":"Add eggs.","description":"5. Crack 3 eggs into the chocolate mixture and carefully fold them in. Crack the other 2 eggs in and carefully fold them in. Fold in the vanilla.","videoURL":"https:\/\/d17h27t6h515a5.cloudfront.net\/topher\/2017\/April\/58ffdc62_2-mix-egss-with-choclate-butter-brownies\/2-mix-egss-with-choclate-butter-brownies.mp4","thumbnailURL":""},{"id":6,"shortDescription":"Add dry mixture to wet mixture.","description":"6. Dump half of flour mixture into chocolate mixture and carefully fold in, just until no streaks remain. Repeat with the rest of the flour mixture. Fold in the chocolate chips.","videoURL":"https:\/\/d17h27t6h515a5.cloudfront.net\/topher\/2017\/April\/58ffdcc8_5-mix-wet-and-cry-batter-together-brownies\/5-mix-wet-and-cry-batter-together-brownies.mp4","thumbnailURL":""},{"id":7,"shortDescription":"Add batter to pan.","description":"7. Pour the batter into the prepared pan and bake for 30 minutes.","videoURL":"https:\/\/d17h27t6h515a5.cloudfront.net\/topher\/2017\/April\/58ffdcf4_8-put-brownies-in-oven-to-bake-brownies\/8-put-brownies-in-oven-to-bake-brownies.mp4","thumbnailURL":""},{"id":8,"shortDescription":"Remove pan from oven.","description":"8. Remove the pan from the oven and let cool until room temperature. If you want to speed this up, you can feel free to put the pan in a freezer for a bit.","videoURL":"","thumbnailURL":""},{"id":9,"shortDescription":"Cut and serve.","description":"9. Cut and serve.","videoURL":"https:\/\/d17h27t6h515a5.cloudfront.net\/topher\/2017\/April\/58ffdcf9_9-final-product-brownies\/9-final-product-brownies.mp4","thumbnailURL":""}],
"servings":8,
"image":""}]

我一直试图用来处理这些数据。

public static String[] getSimpleRecipeStringsFromJson(Context context, String recipeJsonStr)
        throws JSONException {

    String[] parsedRecipeData = null;

    JSONArray recipeJSONArray = new JSONArray(recipeJsonStr);

    parsedRecipeData = new String[recipeJSONArray.length()];

    // Loop through the recipe array
    for (int i = 0; i < recipeJSONArray.length(); i++) {
        JSONObject recipeDetails = recipeJSONArray.getJSONObject(i);
        String recipeID    = recipeDetails.getString("id");
        String recipeName  = recipeDetails.getString("name");
        String recipeIngredients  = recipeDetails.getString("ingredients");
        String servings    = recipeDetails.getString("servings");
        String image       = recipeDetails.getString("image");

        String[] parsedRecipeIngredientsData = null;
        JSONArray recipeIngredientsJSONArray = new JSONArray(recipeIngredients);
        parsedRecipeIngredientsData = new String[recipeIngredientsJSONArray.length()];

        // Loop through ingredients array
        for (int ingredient = 0; ingredient < recipeIngredientsJSONArray.length(); ingredient++) {
            JSONObject ingredientDetails = recipeIngredientsJSONArray.getJSONObject(ingredient);
            String ingredientQuantity = ingredientDetails.getString("quantity");
            String ingredientMeasure = ingredientDetails.getString("measure");
            String ingredientIngredient = ingredientDetails.getString("ingredient");
            parsedRecipeIngredientsData[ingredient] = "\"" + ingredientQuantity + "\",\"" + ingredientMeasure + "\",\"" + ingredientIngredient + "\"";
            Log.d(TAG, "CHECK : " + parsedRecipeIngredientsData[ingredient]);
        }

        parsedRecipeData[i] = "[\"" + recipeID + "\",\"" + recipeName +  "\",\"" + parsedRecipeIngredientsData + "]\",\""  + servings + "\",\"" + image + "\"]";
        Log.d(TAG, "TAG : " + parsedRecipeData[i]);
    }
    return parsedRecipeData;
}

我在这样的详细视图中使用它,现在它只显示食谱名称,这是我需要所有信息的地方。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.recipe_detail);

    // Creating variables for each of the items we need to display
    mRecipeName = (TextView) findViewById(R.id.recipe_name);
    mRecipeIngredients = (TextView) findViewById(R.id.recipe_ingredients);

    Intent intentThatStartedThisActivity = getIntent();

    if (intentThatStartedThisActivity != null) {

        if (intentThatStartedThisActivity.hasExtra(Intent.EXTRA_TEXT)) {
            Context context = getApplicationContext();
            mRecipe = intentThatStartedThisActivity.getStringExtra(Intent.EXTRA_TEXT);
            try {
                JSONArray jsonArray = new JSONArray(mRecipe);
                String recipeID = jsonArray.getString(0);
                // Display title
                mRecipeName.setText(jsonArray.getString(1));
            } catch (JSONException e) {
                Log.d(TAG, "CHECK : " + e);
                e.printStackTrace();
            }
        }
    }
}

我希望我可以创建成分和步骤数组,我可以在以后循环但但我一直在收到错误。此代码生成的对象如下所示。

["4","Cheesecake","[Ljava.lang.String;@e5c064e}","8",""]

因此java.lang.string就是问题所在。我虽然创建一个String []会允许我稍后循环它,因为这是发送到此方法的数据,我只是试图复制它,但我无法让它解决。我收到了错误

 unterminated array character at ### (the numbers  change)

所以也许我只是错误地格式化它,或者我需要一种不同的方法。如果有人可以给我一个提示,告诉我如何将上面的食谱处理成可用的jsonArray,我可以使用它来填充视图,我将不胜感激。即使只是链接到要查看的示例或方法,也会非常感激。

5 个答案:

答案 0 :(得分:1)

您可以使用gson更轻松地解析JSON数据。 在build.gradle文件中添加此依赖项。

compile 'com.google.code.gson:gson:2.8.0'

解析这样的数据

Gson gson = new Gson(); Data data= gson.fromJson(json,Data.class);

这是Data类

     public class Data {

@SerializedName("id")
@Expose
public int id;
@SerializedName("name")
@Expose
public String name;
@SerializedName("ingredients")
@Expose
public List<Ingredient> ingredients = null;
@SerializedName("steps")
@Expose
public List<Step> steps = null;
@SerializedName("servings")
@Expose
public int servings;
@SerializedName("image")
@Expose
public String image;

}

这是成分类

public class Ingredient {

@SerializedName("quantity")
@Expose
public int quantity;
@SerializedName("measure")
@Expose
public String measure;
@SerializedName("ingredient")
@Expose
public String ingredient;

}

这是Step class

public class Step {

@SerializedName("id")
@Expose
public int id;
@SerializedName("shortDescription")
@Expose
public String shortDescription;
@SerializedName("description")
@Expose
public String description;
@SerializedName("videoURL")
@Expose
public String videoURL;
@SerializedName("thumbnailURL")
@Expose
public String thumbnailURL;

}

答案 1 :(得分:1)

我知道它没有直接回答答案,但是当谈到在android中序列化和反序列化Json时我建议使用GSON,谷歌的一个有用的库

通过使用它,您可以创建3个类,如下所示

 public class Recipe {
    @SerializedName("id")
    public Integer id;
    @SerializedName("name")
    public String name;
    @SerializedName("ingredients")
    public List<Ingredient> ingredients = null;
    @SerializedName("steps")
    public List<Step> steps = null;
    @SerializedName("servings")
    public Integer servings;
    @SerializedName("image")
    public String image;
}


public class Ingredient {
    @SerializedName("quantity")
    public Double quantity;
    @SerializedName("measure")
    public String measure;
    @SerializedName("ingredient")
    public String ingredient;
}

public class Step {
    @SerializedName("id")
    public Integer id;
    @SerializedName("shortDescription")
    public String shortDescription;
    @SerializedName("description")
    public String description;
    @SerializedName("videoURL")
    public String videoURL;
    @SerializedName("thumbnailURL")
    public String thumbnailURL;
}

然后像这样解析你的JSON

private List<Recipe> mRecipes;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.recipe_detail);

    // Creating variables for each of the items we need to display
    mRecipeName = (TextView) findViewById(R.id.recipe_name);
    mRecipeIngredients = (TextView) findViewById(R.id.recipe_ingredients);

    Intent intentThatStartedThisActivity = getIntent();

    if (intentThatStartedThisActivity != null) {

        if (intentThatStartedThisActivity.hasExtra(Intent.EXTRA_TEXT)) {
            Context context = getApplicationContext();
            mRecipes = new Gson().fromJson(intentThatStartedThisActivity.getStringExtra(Intent.EXTRA_TEXT), new TypeToken<List<Recipe>>(){}.getType()); 

        }
    }
}

答案 2 :(得分:0)

要阅读数组,你必须像这样选择它们:

JSONArray recipeIngredients  = recipeDetails.getJSONArray("ingredients");
JSONArray steps = recipeDetails.getJSONArray("steps");

不像字符串。

这样做,您可以遍历JSONArray并从中提取每个JSONObject。并形成JSONObject,你需要的字符串。

答案 3 :(得分:0)

您需要的是像GSONJakson这样的图书馆 这些库将把JSON变成一个pojo。 为此,您必须声明一个定义JSON响应模型的java类。

如果你使用android studio(为什么不是你!),我建议你安装一个名为DTO Generator的插件,这个插件会为你生成java类,所以你甚至不用打字所有的类和属性。

这些链接包含您需要的所有教程。 但是,大多数网络级库(如RETROFIT / OKHTTP)都允许您声明JSON解析器,因此他们将在每次网络调用中直接使用JSON库并将响应转换为POJO。

我不知道您使用的是哪个网络库,但我只是谷歌“如何使用gson进行改造”等等,并且有很多教程可以帮助您。

答案 4 :(得分:0)

  

如果您想使用Normal JSON解析,可以使用以下代码   解析发布的JSON的每个标记。

try {
            JSONObject mainObj = new JSONObject("Your API Response");
            String id = mainObj.getString("id");
            String name = mainObj.getString("name");
            String servings = mainObj.getString("servings");
            String image = mainObj.getString("image");

            JSONArray ingredients = mainObj.getJSONArray("ingredients");
            for(int i=0;i<ingredients.length();i++){
                JSONObject jobj = ingredients.getJSONObject(i);
                String quantity = jobj.getString("quantity");
                String measure = jobj.getString("measure");
                String ingredient = jobj.getString("ingredient");
                String chocolate = jobj.getString("chocolate");
            }

            JSONArray steps = mainObj.getJSONArray("steps");
            for(int i=0;i<ingredients.length();i++){
                JSONObject jobj = ingredients.getJSONObject(i);
                String ids = jobj.getString("id");
                String shortDescription = jobj.getString("shortDescription");
                String description = jobj.getString("description");
                String videoURL = jobj.getString("videoURL");
                String thumbnailURL = jobj.getString("thumbnailURL");
            }

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