用Gson解析Json,没有[]的数组?
Parsing Json with Gson, an array without [ ]?
我需要解析这个 json 文件,但它的格式很奇怪。
https://rsbuddy.com/exchange/summary.json
我正在使用 Gson,我以前从未处理过 Json 所以我很迷茫。
"2": {"buy_average": 191, "id": 2, "sell_average": 191, "name": "Cannonball", "overall_average": 191}
看完这个回答后Parsing JSON from URL
我在这里想出了代码:
public class AlchemyCalculator {
public static void main(String[] args) throws Exception {
String json = readUrl("https://rsbuddy.com/exchange/summary.json");
Gson gson = new Gson();
Page page = gson.fromJson(json, Page.class);
System.out.println(page.items.size());
for (Item item : page.items)
System.out.println(" " + item.buy_average);
}
private static String readUrl(String urlString) throws Exception {
BufferedReader reader = null;
try {
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1)
buffer.append(chars, 0, read);
System.out.println("{items: [" +buffer.substring(1, buffer.length() -1) + "]}");
return "{items: [" +buffer.substring(1, buffer.length() -1) + "]}";
} finally {
if (reader != null)
reader.close();
}
}
static class Item {
int buy_average;
int id;
int sell_average;
String name;
int overall_average;
}
static class Page {
List<Item> items;
}
}
虽然我不明白如何解析它,但我看到的答案说要设置匹配的对象层次结构,但我在这里看不到如何做。
提前致谢,并为这里的数百万 Json 问题和我无法理解的问题提前道歉。
您可以尝试使用 JsonReader 流式传输 json 响应并像这样解析它:
Reader streamReader = new InputStreamReader(url.openStream());
JsonReader reader = new JsonReader(streamReader);
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName(); //This is the JsonObject Key
if (isInteger(name)) {
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("id")) {
//get the id
} else if (name.equals("name")) {
//get the name
} else if (name.equals("buy_average")) {
//get the buy average
} else if (name.equals("overall_average")) {
//get the overall average
} else if (name.equals("sell_average")) {
//get the sell average
} else {
reader.skipValue();
}
}
reader.endObject();
}
}
reader.endObject();
reader.close();
其中 isInteger 是一个函数:
public static boolean isInteger(String str) {
if (str == null) {
return false;
}
int length = str.length();
if (length == 0) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
if (length == 1) {
return false;
}
i = 1;
}
for (; i < length; i++) {
char c = str.charAt(i);
if (c < '0' || c > '9') {
return false;
}
}
return true;
}
如果您确实想使用 Gson 将字符串解析为 Item
class 的列表,有一个解决方法如下:
List<Item> itemsOnPage = new ArrayList<Item>();
String content = readUrl("https://rsbuddy.com/exchange/summary.json");
Gson gson = new GsonBuilder().create();
// the json value in content is like key-value pair which can be treated as a map
// {2: item1, 3: item2, 4: item4, .....}
HashMap<String, Object> items = new HashMap<>();
items = (HashMap<String, Object>) gson.fromJson(content, items.getClass());
for (String key : items.keySet()) {
// Once you have converted the json into a map and since the value associated
// with it is also a set of key-value pairs it is treated as LinkedTreeMap
LinkedTreeMap<String, Object> itemMap = (LinkedTreeMap<String, Object>) items.get(key);
// convert it back to json representation to that we could
// parse it to an object of the Item class
String itemString = gson.toJson(itemMap);
// what we have now in itemString is like this:
// {"id": 2, "name": "Cannonball", "buy_average": 191, "overall_average": 193, "sell_average": 192}
Item item = new Item();
item = gson.fromJson(itemString, item.getClass());
// add the current item to the list
itemsOnPage.add(item);
}
您还需要了解的是 Json 语法。 json从上面的URL的结构是这样的:
{
"2": { ...some details related to item... },
"3": { ...some details related to item... },
...
...
}
您不能直接将其解析为 List<?>
,因为它不是。在 Json 中,列表被表示为数组 [item1, item2]
(检查 http://www.w3schools.com/json/),而上面的表示是一个字典 - 与每个项目关联的 id,即
{2: item1, 3: item2, 4: item4, .....}
每个项目本身都有一些属性,例如
{"id": 2, "name": "Cannonball", "buy_average": 191, "overall_average": 193, "sell_average": 192}
我需要解析这个 json 文件,但它的格式很奇怪。 https://rsbuddy.com/exchange/summary.json 我正在使用 Gson,我以前从未处理过 Json 所以我很迷茫。
"2": {"buy_average": 191, "id": 2, "sell_average": 191, "name": "Cannonball", "overall_average": 191}
看完这个回答后Parsing JSON from URL
我在这里想出了代码:
public class AlchemyCalculator {
public static void main(String[] args) throws Exception {
String json = readUrl("https://rsbuddy.com/exchange/summary.json");
Gson gson = new Gson();
Page page = gson.fromJson(json, Page.class);
System.out.println(page.items.size());
for (Item item : page.items)
System.out.println(" " + item.buy_average);
}
private static String readUrl(String urlString) throws Exception {
BufferedReader reader = null;
try {
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1)
buffer.append(chars, 0, read);
System.out.println("{items: [" +buffer.substring(1, buffer.length() -1) + "]}");
return "{items: [" +buffer.substring(1, buffer.length() -1) + "]}";
} finally {
if (reader != null)
reader.close();
}
}
static class Item {
int buy_average;
int id;
int sell_average;
String name;
int overall_average;
}
static class Page {
List<Item> items;
}
}
虽然我不明白如何解析它,但我看到的答案说要设置匹配的对象层次结构,但我在这里看不到如何做。
提前致谢,并为这里的数百万 Json 问题和我无法理解的问题提前道歉。
您可以尝试使用 JsonReader 流式传输 json 响应并像这样解析它:
Reader streamReader = new InputStreamReader(url.openStream());
JsonReader reader = new JsonReader(streamReader);
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName(); //This is the JsonObject Key
if (isInteger(name)) {
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("id")) {
//get the id
} else if (name.equals("name")) {
//get the name
} else if (name.equals("buy_average")) {
//get the buy average
} else if (name.equals("overall_average")) {
//get the overall average
} else if (name.equals("sell_average")) {
//get the sell average
} else {
reader.skipValue();
}
}
reader.endObject();
}
}
reader.endObject();
reader.close();
其中 isInteger 是一个函数:
public static boolean isInteger(String str) {
if (str == null) {
return false;
}
int length = str.length();
if (length == 0) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
if (length == 1) {
return false;
}
i = 1;
}
for (; i < length; i++) {
char c = str.charAt(i);
if (c < '0' || c > '9') {
return false;
}
}
return true;
}
如果您确实想使用 Gson 将字符串解析为 Item
class 的列表,有一个解决方法如下:
List<Item> itemsOnPage = new ArrayList<Item>();
String content = readUrl("https://rsbuddy.com/exchange/summary.json");
Gson gson = new GsonBuilder().create();
// the json value in content is like key-value pair which can be treated as a map
// {2: item1, 3: item2, 4: item4, .....}
HashMap<String, Object> items = new HashMap<>();
items = (HashMap<String, Object>) gson.fromJson(content, items.getClass());
for (String key : items.keySet()) {
// Once you have converted the json into a map and since the value associated
// with it is also a set of key-value pairs it is treated as LinkedTreeMap
LinkedTreeMap<String, Object> itemMap = (LinkedTreeMap<String, Object>) items.get(key);
// convert it back to json representation to that we could
// parse it to an object of the Item class
String itemString = gson.toJson(itemMap);
// what we have now in itemString is like this:
// {"id": 2, "name": "Cannonball", "buy_average": 191, "overall_average": 193, "sell_average": 192}
Item item = new Item();
item = gson.fromJson(itemString, item.getClass());
// add the current item to the list
itemsOnPage.add(item);
}
您还需要了解的是 Json 语法。 json从上面的URL的结构是这样的:
{
"2": { ...some details related to item... },
"3": { ...some details related to item... },
...
...
}
您不能直接将其解析为 List<?>
,因为它不是。在 Json 中,列表被表示为数组 [item1, item2]
(检查 http://www.w3schools.com/json/),而上面的表示是一个字典 - 与每个项目关联的 id,即
{2: item1, 3: item2, 4: item4, .....}
每个项目本身都有一些属性,例如
{"id": 2, "name": "Cannonball", "buy_average": 191, "overall_average": 193, "sell_average": 192}