如何在不丢失Java空格的情况下从URL获取json数据?

时间:2014-03-08 18:42:12

标签: java json

我正在学习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 ..

感谢您阅读,

3 个答案:

答案 0 :(得分:3)

the documentation:

开始
  

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;
        }
    }

}