将json源转换为java对象

将json源转换为java对象,java,json,Java,Json,我有一个url(https://),其中包含json数据,但它有一个防止json highjacking攻击的保护,我认为这是因为源代码以以下内容开头: )]}, 来源如下: [ { "address": { "street": "Neuenfelder Str", "housenumber": "13A", "postalcode": "21109", "city": "Hamburg", "geo

我有一个url(
https://
),其中包含
json
数据,但它有一个防止
json highjacking攻击的保护,我认为这是因为源代码以以下内容开头:
)]},
来源如下:

  [
  {
    "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
  },
  .....]
我试图通过使用
Jackson
gson
甚至
org.json
创建客户端代码并使用此json,但我遇到了解析错误:

无法读取文档:意外字符(')(代码41)): 应为有效值(数字、字符串、数组、对象、'true'、'false' 或“空”)

我可以将
json
转换为
Java
对象,方法是保存为文件并删除这些字符
)]}


但我需要知道,有没有任何方法可以像普通方法一样转换此源代码,而不保存为文档,只使用这些库(
ObjectMapper
ResponseEntity
).

您提到的所有主要JSON库都没有提供任何解析您所说的JSON文档的方法:它们只能处理格式良好的JSON文档,而这是它们唯一的责任,也是它们的责任。您提到了一个不是有效JSON的文档,所以这是所有人都无法解析它的唯一原因。但是,您在问题中提到的所有库都透明地使用
Reader
s,并且在删除了这五个字符之后,您可以修复损坏的JSON文档(对于JSON标准或任何JSON工具来说都是损坏的),以便这些库中的任何一个都可以使用它。请注意,您不需要任何类型的“特殊”库(好吧,让我们假设存在这样一个库,但是如果它缺少任何可以与您喜爱的JSON库一起使用的功能,那么会怎样?这让您感到难过?),因为您可以让它在任何情况下工作。性能说明:为了节省内存和处理巨大的JSON文档,您不需要使用字符串

考虑以下“JSON”文档:

)]}',{"foo":"bar"}
知道前五个字符会阻止任何JSON解析器对其进行解析,您可以轻松地去除它们:

private static final char[]protectingCharacters={
')', ']', '}', '\'', ','
};
静态读卡器条带保护(最终读卡器)
抛出IOException{
//分配临时缓冲区
final char[]buffer=新字符[protectingCharacters.length];
//检查给定的读卡器实例是否支持提前读取,必要时进行换行
//这是恢复读卡器位置所必需的
最终读取器normalizedReader=Reader.markSupported()?读取器:新的BufferedReader(读取器);
//记住当前位置,告诉读卡器将其内部缓冲区大小限制为5个字符
normalizedReader.mark(保护字符.长度);
//将五个字符读入缓冲区
//我们不需要检查读取了多少个字符——我们将在下面进行检查
normalizedReader.read(缓冲区,0,保护字符.length);
//不是保护标志?
如果(!array.equals(保护字符,缓冲区)){
//然后将读卡器指针倒回使用mark()调用存储的位置
normalizedReader.reset();
}
//或者假设跳过五个字符就可以了
返回标准化读取器;
}
以下示例使用Gson、Jackson和org.json库解析给定输入流的
stripProtection
方法创建各自的json树模型,以简化操作:

static void testWithGson()
抛出IOException{
try(final Reader=stripProtection(getPackageResourceReader(Q42971905.class,“no-jacking.json”)){
final JsonParser=new JsonParser();
final JsonElement JsonElement=parser.parse(reader);
System.out.println(jsonElement);
}
}
静态void testWithJackson()
抛出IOException{
try(final Reader=stripProtection(getPackageResourceReader(Q42971905.class,“no-jacking.json”)){
最终ObjectMapper ObjectMapper=新ObjectMapper();
final JsonNode JsonNode=objectMapper.readTree(reader);
System.out.println(jsonNode);
}
}
静态void testWithOrgJson()
抛出IOException{
try(final Reader=stripProtection(getPackageResourceReader(Q42971905.class,“no-jacking.json”)){
最终JSONTokener JSONTokener=新JSONTokener(读取器);
最终对象值=jsonTokener.nextValue();
系统输出打印项次(值);
}
}
所有三种方法都会产生以下输出:

{“foo”:“bar”}

如果出于某种原因需要生成此类文档,只需编写如下方法:

static Writer coverWithProtection(最终写入程序)
抛出IOException{
writer.write(保护字符);
返回作者;
}

并将编写器传递给您正在使用的相应JSON库。这个方法只会在writer输出前面加上
)]},

将这个源代码转换成字符串并修剪起始字符
)]}
听起来问题不在于如何将json转换成java,而在于如何修复json的一个片段。为什么要采用不删除无效字符的方法?这就像在问,“1+1”是什么但不是以2作为答案。您必须去掉第一个字符,但因为您没有包含任何关于读取JSON的源代码以及我们无法帮助您的内容。如果您控制发送JSON的服务器代码,请确保它发送有效的JSON,否则您将不得不对其进行修剪以使其有效。非常感谢,我需要确定。这很有解释力。我尝试了您的解决方案,
jsonNode
返回格式良好的json文档,由于性能是一个问题,因此更为合理。