简体   繁体   English

如何从URL获取json数据而不丢失Java中的空格?

[英]How do I get json data from a URL without losing spaces in Java?

I'm learning Java, so I decided to toy around with the GW2 with the hope of coding something useful: API: http://wiki.guildwars2.com/wiki/API:Main 我正在学习Java,因此我决定尝试使用GW2,并希望编写一些有用的代码:API: http ://wiki.guildwars2.com/wiki/API: Main

I'm trying to get the following data: https://api.guildwars2.com/v1/world_names.json into a Java String, this is my code: 我正在尝试获取以下数据: https : //api.guildwars2.com/v1/world_names.json转换为Java字符串,这是我的代码:

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

}

The problem is I'm losing the format of the Strings (I'm missing the blank characters that separate words). 问题是我丢失了字符串的格式(我缺少分隔单词的空白字符)。 This is what you see if you access the URL: 如果您访问URL,就会看到以下内容:

[{"id":"1009","name":"Fort Aspenwood"}, {"id":"1005","name":"Maguuma"}, {"id":"1008","name":"Jade Quarry"}, [{“ id”:“ 1009”,“名称”:“阿斯彭伍德堡”},{“ id”:“ 1005”,“名称”:“ Maguuma”},{“ id”:“ 1008”,“名称” :“玉采石场”},

This is what I get in my String: 这是我在字符串中得到的:

{"id":"1009","name":"FortAspenwood"}, {"id":"1005","name":"Maguuma"}, {"id":"1008","name":"JadeQuarry"} {“ id”:“ 1009”,“名称”:“ FortAspenwood”},{“ id”:“ 1005”,“名称”:“ Maguuma”},{“ id”:“ 1008”,“名称”:“ JadeQuarry”}

How can I fix that? 我该如何解决? am I doing something wrong? 难道我做错了什么?

My final goal is to convert this data to an object, and then be able to ask for an specific ID or NAME to the api and get more data, such as maps or events, but first things first, since I'm learning and I can't get the String right.. 我的最终目标是将这些数据转换为对象,然后能够向api请求一个特定的ID或NAME并获取更多数据,例如地图或事件,但首先要这样做,因为我正在学习无法正确获取字符串。

Thank you for reading, 感谢您的阅读,

Right from the documentation: 直接来自文档:

A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace. Scanner使用定界符模式将其输入分为令牌,默认情况下,该模式与空格匹配。

You don't want any sort of tokenization, so you can borrow a one-liner from Stupid Scanner tricks : 您不需要任何类型的令牌化,因此您可以从Stupid Scanner技巧中借用一种代码:

final String jsonData = new Scanner(is).useDelimiter("\\A").next();

which consumes the entire input stream in one line. 在一行中消耗了整个输入流。


NB if you do stick with using a loop, you should use a StringBuilder instead of concatenation ( jsonData += scan.next(); ) because that operation has quadratic asymptotic runtime. 注意,如果您坚持使用循环,则应该使用StringBuilder而不是串联( jsonData += scan.next(); ),因为该操作具有二次渐近运行时。

However, I strongly recommend that you use Jackson for all your real-world JSON processing uses. 但是,我强烈建议您将Jackson用于现实世界中的所有JSON处理用途。

As I can see you are doing: 如我所见,您正在执行以下操作:

while(scan.hasNext()) {
   jsonData += scan.next();
}

next() returns the next token which is separated by spaces, new lines etc. Now since you have to get the whole line from your JSON data, you can do: next()返回下一个由空格,换行等分隔的令牌。现在,由于必须从JSON数据中获取整行,因此可以执行以下操作:

while(scan.hasNextLine()) {
   jsonData += scan.nextLine();
}

One way to approach this problem is to use a library, like Jackson, that knows how to parse json input. 解决此问题的一种方法是使用像Jackson一样的库,该库知道如何解析json输入。 Here is an example program that goes out to the url you provided and creates a List of DataTransferObject. 这是一个示例程序,该程序转到您提供的URL并创建一个DataTransferObject列表。

This code depends on http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl/1.9.13 此代码取决于http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl/1.9.13

This is not strictly speaking the answer to your question but is another approach. 严格来讲,这不是您问题的答案,而是另一种方法。

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM