【问题标题】:Java convert Json array to typed List<T>Java 将 Json 数组转换为类型化 List<T>
【发布时间】:2023-03-15 22:20:01
【问题描述】:

我有一个网络服务,它发送一个类型化的数组列表,我通过 HttpResponse 捕获它,如下所示:

// create GET request
HttpGet httpGet = new HttpGet("http://localhost:8084/MinecraftRestServer/webresources/Items");
// execute GET request
HttpResponse response = client.execute(httpGet);
// check response
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) { // response OK
    // retreive response
    List<Recipe> recipesList = new ArrayList<Recipe>();
    HttpEntity jsonObj = response.getEntity();
            //What's next?

从 web 服务发送的数组如下所示:

recipesList.add(new Item(1, 11, "diamond_ingot", "Diamond ingot",
                "0,0,0,0,0,0,0,0,1", "air,diamond_ore"));
recipesList.add(new Item(2, 11, "iron_ingot", "Iron ingot",
                "0,0,0,0,0,0,0,0,1", "air,iron_ore"));

并以这种格式输出:

[{"recipeCategory":11,"recipeImageID":"diamond_ingot","recipeDescription":"Diamond ingot","recipeLocations":"0,0,0,0,0,0,0,0,1","usedImages":"air,diamond_ore","recipeID":1},{"recipeCategory":11,"recipeImageID":"iron_ingot","recipeDescription":"Iron ingot","recipeLocations":"0,0,0,0,0,0,0,0,1","usedImages":"air,iron_ore","recipeID":2},{"recipeCategory":11,"recipeImageID":"gold_ingot","recipeDescription":"Gold ingot","recipeLocations":"0,0,0,0,0,0,0,0,1","usedImages":"air,gold_ore","recipeID":3},{"recipeCategory":11,"recipeImageID":"diamond_ore","recipeDescription":"Diamond ore","recipeLocations":"0,0,0,0,0,0,0,0,1","usedImages":"air,wooden_pickaxe","recipeID":4},{"recipeCategory":11,"recipeImageID":"iron_ore","recipeDescription":"Iron ore","recipeLocations":"0,0,0,0,0,0,0,0,1","usedImages":"air,wooden_pickaxe","recipeID":5},{"recipeCategory":11,"recipeImageID":"gold_ore","recipeDescription":"Gold ore","recipeLocations":"0,0,0,0,0,0,0,0,1","usedImages":"air,wooden_pickaxe","recipeID":6},{"recipeCategory":2,"recipeImageID":"diamond_boots","recipeDescription":"Boots (Diamond)","recipeLocations":"0,0,0,1,0,1,1,0,1","usedImages":"air,diamond_ingot","recipeID":7},{"recipeCategory":2,"recipeImageID":"gold_boots","recipeDescription":"Boots (Gold)","recipeLocations":"0,0,0,1,0,1,1,0,1","usedImages":"air,gold_ingot","recipeID":8},{"recipeCategory":2,"recipeImageID":"iron_boots","recipeDescription":"Boots (Iron)","recipeLocations":"0,0,0,1,0,1,1,0,1","usedImages":"air,iron_ingot","recipeID":9},{"recipeCategory":2,"recipeImageID":"diamond_leggings","recipeDescription":"Leggings (Diamond)","recipeLocations":"1,1,1,1,0,1,1,0,1","usedImages":"air,diamond_ingot","recipeID":10},{"recipeCategory":2,"recipeImageID":"gold_leggings","recipeDescription":"Leggings (Gold)","recipeLocations":"1,1,1,1,0,1,1,0,1","usedImages":"air,gold_ingot","recipeID":11},{"recipeCategory":2,"recipeImageID":"iron_leggings","recipeDescription":"Leggings (Iron)","recipeLocations":"1,1,1,1,0,1,1,0,1","usedImages":"air,iron_ingot","recipeID":12},{"recipeCategory":2,"recipeImageID":"diamond_chestplate","recipeDescription":"Chestplate (Diamond)","recipeLocations":"1,0,1,1,1,1,1,1,1","usedImages":"air,diamond_ingot","recipeID":13},{"recipeCategory":2,"recipeImageID":"gold_chestplate","recipeDescription":"Chestplate (Gold)","recipeLocations":"1,0,1,1,1,1,1,1,1","usedImages":"air,gold_ingot","recipeID":14},{"recipeCategory":2,"recipeImageID":"iron_chestplate","recipeDescription":"Chestplate (Iron)","recipeLocations":"1,0,1,1,1,1,1,1,1","usedImages":"air,iron_ingot","recipeID":15},{"recipeCategory":2,"recipeImageID":"diamond_helmet","recipeDescription":"Helmet (Diamond)","recipeLocations":"1,1,1,1,0,1,0,0,0","usedImages":"air,diamond_ingot","recipeID":16},{"recipeCategory":2,"recipeImageID":"gold_helmet","recipeDescription":"Helmet (Gold)","recipeLocations":"1,1,1,1,0,1,0,0,0","usedImages":"air,gold_ingot","recipeID":17},{"recipeCategory":2,"recipeImageID":"iron_helmet","recipeDescription":"Helmet 

我的问题是,如何将其转换回数组列表 (ArrayList&lt;Item&gt;) 客户端应用程序中已经存在一个 Item 类。

我已阅读有关 Gson 库的示例,但在 API 17 中编译时似乎不再包含它。

最简单的方法是什么?

【问题讨论】:

  • 你的意思是说你想把json解析成arraylist?
  • @MT8 是的,它是一个类型化的数组列表,类型为 Item 类
  • 创建一个arraylist实例,解析JSON,存储在arraylist中,有什么问题??
  • I've read examples about the Gson library but it seems it's not included anymore when compiling in API 17. 这是错误的。 GSON 从未与 android api 一起包含。如果使用Android Studio,则需要下载jar 或将其添加到build.gradle 中的dependencies 块中
  • @RobbieVercammen 看看我的回答。它展示了如何将 JSON 字符串解析为类型化列表。

标签: java android json list


【解决方案1】:

如果使用 Eclipse,请从 here 下载 GSON jar 并将其包含在您的项目中。

如果使用 Android Studio,请打开您的 build.gradle 并将以下内容添加到您的 dependencies 块中。或者你可以再次选择不使用 maven,只需将 jar 放到你的 lib 文件夹中。

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

接下来,使用GSON 构造一个项目列表。 确保您的 Item.java 类与 JSON 响应中的成员名称相同

 List<Recipe> recipesList = new ArrayList<Recipe>();
 HttpEntity jsonObj = response.getEntity();
 String data = EntityUtils.toString(entity);
 Log.d("TAG", data);
 Gson gson = new GsonBuilder().create();
 recipesList = gson.fromJson(data, new TypeToken<List<Item>>() {}.getType());

确保适当地处理异常。

【讨论】:

  • 我正在尝试您的方法!我已经添加了 gson 库,但现在我遇到了 networkonmain 线程异常。等一下:)
  • 你不应该在主线程上做任何网络操作。如果您在修复 NetworkOnMainThreadException 时遇到问题,那么已经有很多答案了 - stackoverflow.com/search?q=networkonmainthread
  • 我已经找到了答案,我用一个新的可运行对象包围了它,并设法在填充它的内容之前让列表等待。但是在本地主机上调用我的网络服务时,连接仍然被拒绝。
  • 我认为在你的模拟器或设备上使用 localhost 是行不通的。您可能需要使用托管网络服务的机器的 IP 地址。
  • 不,是缺少权限!它奏效了,我已经从网络服务中取回了我的数据。非常感谢。顺便说一句,如果您为私人设备打开端口,它确实可以在 localhost 上工作;)
【解决方案2】:

您可以使用Jackson 来解析传入的 JSON。 (Quick introduction)

如果您已经有一个具有适当属性的类,则可以像这样简单:

public class Items {
    private List<Item> items;
    // getter+setter
}

ObjectMapper mapper = new ObjectMapper();
Items = mapper.readValue(src, Items.class);

更多信息请参见this

【讨论】:

    【解决方案3】:
    Step 1 : Item obj=new Item;
    
    Step 2: Parse the json formar for example here :
    
    [[Example1][1]
    
    Step 3: while parsing put ur values in obj :
    
    obj.recipeCategory=value1;
    
    Step 4: insret ur obj into arraylist:
    
    arrayList.add(obj);
    

    【讨论】:

      【解决方案4】:

      我认为您应该使用 json-simple 库将字符串 Json 解析为 JsonObject 并转换为简单数据类型。 示例:

      JSONArray arrJson = (JSONArray) parser.parse("String json");
      

      获取JSONArray中的每个元素JSONObject,然后解析为简单数据类型:

      long recipeCategory = (long) jsonObject.get("recipeCategory");
      

      【讨论】:

        【解决方案5】:

        您可以像许多用户所说的那样使用Gson,这是一个使用Gson的RESTfull客户端示例:

        public class RestRequest {
            Gson gson = new Gson();
        
            public <T> T post(String url, Class<T> clazz,
                List<NameValuePair> parameters) {
            // Create a new HttpClient and Post Header
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(url);
            try {
                // Add your data
                httppost.setEntity(new UrlEncodedFormEntity(parameters));
                // Execute HTTP Post Request
                HttpResponse response = httpclient.execute(httppost);
                StringBuilder json = inputStreamToString(response.getEntity()
                        .getContent());
                T gsonObject = gson.fromJson(json.toString(), clazz);
                return gsonObject;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
            }
        
            // Fast Implementation
            private StringBuilder inputStreamToString(InputStream is)
                throws IOException {
            String line = "";
            StringBuilder total = new StringBuilder();
        
            // Wrap a BufferedReader around the InputStream
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        
            // Read response until the end
            while ((line = rd.readLine()) != null) {
                total.append(line);
            }
        
            // Return full string
            return total;
            }
        
        }
        

        用法如下: new RestRequest("myserver.com/rest/somewebservice", SomeClass.class, Arrays.asList(new BasicValuePair("postParameter", "someParameterValue")));

        在您的情况下,SomeClass.class 将是 Recipe[].class。还要检查this 问题以正确处理服务器端错误。

        【讨论】:

        • Inputstream to string 是我的第一种方法,但 Varuns 的回答更准确。感谢您的输入
        【解决方案6】:

        伙计,谷歌是你的朋友!快速搜索“android json”或“android json parse”会为您提供一些不错的教程,例如 this onethis here

        【讨论】:

        • 更多的评论,更多的答案
        • 感谢批评者......以及教程,他们非常有帮助。如果你不知道你必须谷歌搜索什么,那么谷歌搜索并不容易。我想我搜索得太具体了。
        猜你喜欢
        • 2017-03-11
        • 2021-11-26
        • 2012-11-15
        • 2022-11-02
        • 1970-01-01
        • 2010-10-19
        • 1970-01-01
        • 2017-05-06
        • 1970-01-01
        相关资源
        最近更新 更多