我正在学习Java,所以我决定玩弄GW2,希望编写一些有用的东西:API:http://wiki.guildwars2.com/wiki/API:Main
我正在尝试获取以下数据:https://api.guildwars2.com/v1/world_names.json 在Java String中,这是我的代码:
public static void main(String[] args) {
URL url = null;
String jsonData = "";
try {
url = new URL("https://api.guildwars2.com/v1/world_names.json");
InputStream is = url.openStream();
Scanner scan = new Scanner(is);
while(scan.hasNext()) {
jsonData += scan.next();
}
scan.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(jsonData);
}
问题是我正在丢失字符串的格式(我错过了分隔单词的空白字符)。 如果您访问该网址,则会看到以下内容:
[{“id”:“1009”,“name”:“Fort Aspenwood”}, {“id”:“1005”,“name”:“Maguuma”},{“id”:“1008”,“name”:“Jade Quarry”},
这是我在我的字符串中得到的结果:
{“id”:“1009”,“name”:“FortAspenwood”},{“id”:“1005”,“name”:“Maguuma”}, { “ID”: “1008”, “名称”: “JadeQuarry”}
我该如何解决?我做错了什么?
我的最终目标是将此数据转换为对象,然后能够向api请求特定ID或NAME并获取更多数据,例如地图或事件,但首先要做的事情,因为我是学习,我无法正确使用String ..
感谢您阅读,
答案 0 :(得分:3)
Scanner
使用分隔符模式将其输入分解为标记,该分隔符模式默认匹配空格。
您不想要任何类型的标记化,因此您可以从Stupid Scanner tricks借用一行代码:
final String jsonData = new Scanner(is).useDelimiter("\\A").next();
使用一行中的整个输入流。
N.B。如果你坚持使用循环,你应该使用StringBuilder
而不是连接(jsonData += scan.next();
),因为该操作具有二次渐近运行时。
但是,我强烈建议您使用Jackson进行所有真实的JSON处理用途。
答案 1 :(得分:0)
我可以看到你在做:
while(scan.hasNext()) {
jsonData += scan.next();
}
next()返回下一个由空格,换行等分隔的标记。既然你必须从JSON数据中获取整行,你可以这样做:
while(scan.hasNextLine()) {
jsonData += scan.nextLine();
}
答案 2 :(得分:0)
解决这个问题的一种方法是使用像Jackson这样知道如何解析json输入的库。这是一个示例程序,它指向您提供的URL并创建一个DataTransferObject列表。
此代码取决于http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl/1.9.13
严格来说,这不是你问题的答案,而是另一种方法。
package stackoverflow;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import java.io.IOException;
import java.net.URL;
import java.util.List;
public class JsonParser {
private static final String urlString = "https://api.guildwars2.com/v1/world_names.json";
public static void main(String[] args) throws IOException {
JsonParser parser = new JsonParser();
URL url = new URL(urlString);
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(url.openStream());
List<DataTransferObject> dtoList = mapper.readValue(root, new TypeReference<List<DataTransferObject>>(){});
for(DataTransferObject dto : dtoList) {
System.out.println("DTO: " + dto);
}
}
public static class DataTransferObject {
public int id;
public String name;
@Override
public String toString() {
return "ID: " + id + " NAME: " + name;
}
}
}