简体   繁体   English

将json源转换为java对象

[英]convert json source to java object

I have an url ( https:// ) which includes json data but it has a protection against called JSON highjacking exploit I think because the source begins with: )]}', and the source is like: 我有一个网址( https:// ),其中包含json数据,但它有一个防止被叫JSON highjacking exploit的保护我认为因为源代码以JSON highjacking exploit )]}',开头)]}',而源代码如下:

  [
  {
    "address": {
        "street": "Neuenfelder Str",
        "housenumber": "13A",
        "postalcode": "21109",
        "city": "Hamburg",
        "geoLocation": {
            "lat": "52.092309",
            "lng": "5.130041"
        }
    },
    "distance": 0
  },
  {
    "address": {
        "street": "Umber Str",
        "housenumber": "2",
        "postalcode": "22567",
        "city": "Berlin",
        "geoLocation": {
            "lat": "51.5761166",
            "lng": "5.0377286"
        }
    },
    "distance": 0
  },
  .....]

I tried to create client code and consume this json by using Jackson , gson and even org.json but I got parsing error : 我尝试使用Jacksongson甚至org.json创建客户端代码并使用此json,但我得到了解析错误:

Could not read document: Unexpected character (')' (code 41)): expected a valid value (number, String, array, object, 'true', 'false' or 'null') 无法读取文档:意外字符(')'(代码41)):预期有效值(数字,字符串,数组,对象,'真','假'或'空')

I could convert json to Java object by saving as a file and remove these characters )]}' . 我可以通过保存为文件并删除这些字符来将json转换为Java对象)]}'

But I need to know is there any way to convert this source as a normal way we do without saving as a document and just use these libraries( ObjectMapper or ResponseEntity ). 但我需要知道有没有办法将这个源转换为我们不用保存为文档的常规方法,只使用这些库( ObjectMapperResponseEntity )。

All major JSON libraries you mentioned do NOT provide any way of parsing JSON documents you are talking about: they can just work with well-formed JSON documents, nothing else, and that's the only and justified their responsibility. 您提到的所有主要JSON库都没有提供任何解析您正在讨论的JSON文档的方法:它们只能使用格式良好的 JSON文档,而不是其他任何东西,这是唯一且合理的责任。 You mentioned a document that is not a valid JSON, so that's the only reason of why all of them fail to parse it. 您提到的文档不是有效的JSON,因此这就是为什么所有这些文档都无法解析它的唯一原因。 However, all of the libraries you mentioned in your question work with Reader s transparently, and having just removed those five characters, you can fix the broken JSON document (and it's broken for the JSON standard or any JSON tool) so it could be consumed by any of those library. 但是,您在问题中提到的所有库都透明地使用Reader ,并且刚刚删除了这五个字符,您可以修复损坏的JSON文档(并且它已经破坏了JSON标准或任何JSON工具),因此可以使用它任何这些图书馆。 Please note that you don't need a "special" library of any kind (ok, let's assume such a library exists, but what if it lacks any features that you can use with your favorite JSON library, so that making you sad?), because you can just make it work for any. 请注意,您不需要任何类型的“特殊”库(好吧,我们假设存在这样的库,但如果它缺少您可以使用您喜欢的JSON库的任何功能,那么会让您感到难过?) ,因为你可以让它适用于任何。 Performance note: you don't need to use strings in order to save memory and being able to process huge JSON documents as well. 性能说明:您不需要使用字符串来节省内存并且还能够处理大量JSON文档。

Consider the following "JSON" document: 考虑以下“JSON”文档:

)]}',{"foo":"bar"}

Knowing that the very first five characters prevent any JSON parser to parse it, you can easily just strip them: 知道前五个字符阻止任何JSON解析器解析它,您可以轻松地剥离它们:

private static final char[] protectingCharacters = {
        ')', ']', '}', '\'', ','
};

static Reader stripProtection(final Reader reader)
        throws IOException {
    // Allocating a temporary buffer
    final char[] buffer = new char[protectingCharacters.length];
    // Check if the given Reader instance supports reading ahead, and wrap if necessary
    // This is necessary in order to restore the reader position
    final Reader normalizedReader = reader.markSupported() ? reader : new BufferedReader(reader);
    // Memorizing the current position telling the reader to limit its internal buffer size just with five characters
    normalizedReader.mark(protectingCharacters.length);
    // Reading five characters to the buffer
    // We don't need to check how many characters were read -- we'll check it below
    normalizedReader.read(buffer, 0, protectingCharacters.length);
    // Not a protecting mark?
    if ( !Arrays.equals(protectingCharacters, buffer) ) {
        // Then just rewind the reader pointer to the position stored with the mark() invocation
        normalizedReader.reset();
    }
    // Or assume that skipping five characters is fine
    return normalizedReader;
}

The following examples use the stripProtection method for the Gson, Jackson and org.json libraries parsing the given input stream to create their respective JSON tree models for simplicity: 以下示例使用stripProtection方法为Gson,Jackson和org.json库解析给定的输入流,以简化创建各自的JSON树模型:

static void testWithGson()
        throws IOException {
    try ( final Reader reader = stripProtection(getPackageResourceReader(Q42971905.class, "no-hijacking.json")) ) {
        final JsonParser parser = new JsonParser();
        final JsonElement jsonElement = parser.parse(reader);
        System.out.println(jsonElement);
    }
}

static void testWithJackson()
        throws IOException {
    try ( final Reader reader = stripProtection(getPackageResourceReader(Q42971905.class, "no-hijacking.json")) ) {
        final ObjectMapper objectMapper = new ObjectMapper();
        final JsonNode jsonNode = objectMapper.readTree(reader);
        System.out.println(jsonNode);
    }
}

static void testWithOrgJson()
        throws IOException {
    try ( final Reader reader = stripProtection(getPackageResourceReader(Q42971905.class, "no-hijacking.json")) ) {
        final JSONTokener jsonTokener = new JSONTokener(reader);
        final Object value = jsonTokener.nextValue();
        System.out.println(value);
    }
}

All three methods produce the following output: 这三种方法都产生以下输出:

{"foo":"bar"} { “富”: “酒吧”}

If, for some reason, you need to generate such documents, you just have to write a method like this: 如果由于某种原因,您需要生成此类文档,则只需编写如下方法:

static Writer coverWithProtection(final Writer writer)
        throws IOException {
    writer.write(protectingCharacters);
    return writer;
}

And pass the writer to the corresponding JSON library you're using. 并将编写器传递给您正在使用的相应JSON库。 This method will just prepend the writer output with )]}', . 这个方法只会在编写器输出前加上)]}', ,.

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

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