Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将不带引号的json字符串转换为映射_Java_Json_Jackson_Mapper - Fatal编程技术网

Java 将不带引号的json字符串转换为映射

Java 将不带引号的json字符串转换为映射,java,json,jackson,mapper,Java,Json,Jackson,Mapper,我有一个Json格式的字符串,只有所有键或值都没有引号。例如,我有: String json = "{name: Bob, state: Colorado, Friends: [{ name: Dan, age: 23 }, {name: Zane, age: 24 }]}" 我希望这张地图看起来像这样: Map<String, Object> friend1Map = new HashMap<>(); friend1Map.put("name", "Dan"); fr

我有一个Json格式的字符串,只有所有键或值都没有引号。例如,我有:

String json = "{name: Bob, state: Colorado, Friends: [{ name: Dan, age: 23 }, {name: Zane, age: 24 }]}"
我希望这张地图看起来像这样:

Map<String, Object> friend1Map = new HashMap<>();
friend1Map.put("name", "Dan");
friend1Map.put("age", 23);

Map<String, Object> friend2Map = new Hashmap<>();
friend2Map.put("name", "Zane");
friend2Map.put("age", 24);

Map<String, Object> newMap = new HashMap<>();
newMap.put("name", "Bob");
newMap.put("state", "Colorado");
newMap.put("Friends", Arrays.asList(friend1Map, friend2Map));
然后我尝试更改映射器的配置:

mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
mapper.readValue(json, new TypeReference<Map<String, Object>>() {});

当json字符串中不包含引号时,有没有办法获取此映射?

如果json输入无效,ObjectMapper将无法解析它,因此答案是否定的

在此处测试Json:

更正Json输入后,您可以执行以下操作:

    ObjectMapper ob = new ObjectMapper();
    ob.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
    String json = "{name: \"Bob\", state: \"Colorado\", Friends: [{ name: \"Dan\", age: 23 }, {name: \"Zane\", age: 24 }]}";

    Map<String, ObjectNode> theMap = ob.readValue(json, Map.class);
    System.out.println(theMap.get("name"));
ObjectMapper ob=new ObjectMapper();
ob.configure(Feature.ALLOW\u UNQUOTED\u FIELD\u NAMES,true);
字符串json=“{name:\'Bob\”,state:\'Colorado\”,Friends:[{name:\'Dan\,age:23},{name:\'Zane\,age:24}]}”;
Map theMap=ob.readValue(json,Map.class);
System.out.println(theMap.get(“name”));
将打印:

鲍勃


回答您的问题:没有安全的方法将JSON转换成
映射
,顺便说一句,JSON不是JSON,因为它是无效的

让我详细说明一下(为什么不能安全地解析它?) 想象一下这样的“JSON”:

{
    this is my key: and here's my value and it even has a colon:
}
有效的JSON如下所示

{
    "this is my key": "and here's my value and it even has a colon:"
}

使用引号,解析器可以安全地确定键和值。如果没有它们,解析器将丢失。

您可以使用以下代码对json字符串进行预处理,然后对其进行解析

String str = ("{requestid:\"55275645.f213506045\",timestamp:\"213506045\",bidnumber:\"55275645\",checkcode:\"1f6ad033de64d1c6357af34d4a38e9e3\",version:\"1.0\",request:{token:ee4e90c2-7a8b-4c73-bd48-1bda7e6734d5,referenceId:0.5878463922999799}}");
    str = (str.replaceAll(":\"?([^{|^]*?)\"?(?=[,|}|\\]])",":\"$1\"").replaceAll("\"?(\\w+)\"?(?=:)","\"$1\""));
    JSONObject obj = JSON.parseObject(str);
    System.out.println(obj.getJSONObject("request").getString("token"));
自Java 15以来 注意:我们预计Java 15将支持未替换的双引号,如下所示:

var json = """
        {"name": "Bob", "state": "Colorado", "Friends": [{ "name": "Dan", "age": 23 }, {"name": "Zane", "age": 24 }]} """;


自GSON v2.8.6以来 带有jackson fasterxml的ObjectMapper不支持不带引号的值,但GSON支持:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonParser;


早前的格森 在v2.8.6之前,GSON没有静态parseString方法。因此,您应该使用(在更高版本中已弃用)实例方法:

JsonNode json(String content) throws IOException {

  String canonicalFormat = new JsonParser().parse(content).toString();
  return json.readTree(canonicalFormat);
}

我们可以使用ApacheCommons和Guava库将这样的json转换为映射。 例子: 输入-{name=jack,id=4} 输出-映射(名称=插孔,id=4)

import com.google.common.base.Splitter;
导入org.apache.commons.lang.StringUtils;
字符串输入=StringUtils.substringBetween(值,“{,“}”);
地图=
Splitter.on(“,”).withKeyValueSeparator(“=”).split(输入);

您的Json字符串无效,请在此处测试:如何测试?显然,这个评论需要15个字符才能添加itor,我该如何使它有效呢?显然,问题在于没有报价。我需要做一些令人讨厌的拆分吗?只是想澄清一下:那不是Json,只是Json一样。我不认为jackson可以处理不带引号的sring值,只支持不带引号的键。这个答案可能会对你有所帮助:你可以查看GSON库而不是Jackson。请参阅Jackson可以解析无效的JSON。请注意
JsonParser.Feature.ALLOW\u UNQUOTED\u FIELD\u NAMES
。它只是无法解析未加引号的字段值(似乎)。此外,您的
theMap
将不会只有
String
值。JSON中有数组。你建议的不是类型安全的。改用
ObjectNode
。我不是这个意思。并非所有的值都是
ObjectNode
。我指的是更多的
ObjectNode root=ob.readValue(json,ObjectNode.class)他问如何将Json字符串转换成Map,他还问如何使用不带引号的值。你纠正了那部分。你也应该纠正其余的错误。这里没有办法将类型安全参数化
Map
引用。你可以有一个
Map>
Map
,但那是非常无用的
ObjectNode
为您提供了更大的灵活性。我们都知道它无效,但我们仍在询问,因为我们收到的遥测消息没有引号。@mrki102,那么我建议您实现一个“过滤器”,以更正传入的数据。然后您可以选择任何您喜欢的解析器。过滤器可能需要一些帮助,通过定义某种模式,让它知道哪些字段值是字符串,除了字段键/标签之外,还需要引号。
var json = """
        {"name": "Bob", "state": "Colorado", "Friends": [{ "name": "Dan", "age": 23 }, {"name": "Zane", "age": 24 }]} """;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonParser;
  JsonNode json = json("{"
      + "  name: Bob,      "
      + "  state: Colorado,"
      + "  Friends: [      "
      + "    {"
      + "      name: Dan,  "
      + "      age: 23     "
      + "    },"
      + "    {"
      + "      name: Zane, "
      + "      age: 24     "
      + "     }"
      + "  ],"
      + "  extra: \"text with spaces or colon(:) must be quoted\""
      + "}");

  Map m = new ObjectMapper().convertValue(json, Map.class);
JsonNode json(String content) throws IOException {

  String canonicalFormat = JsonParser.parseString(content).toString();
  return json.readTree(canonicalFormat);
}
JsonNode json(String content) throws IOException {

  String canonicalFormat = new JsonParser().parse(content).toString();
  return json.readTree(canonicalFormat);
}
import com.google.common.base.Splitter;
import org.apache.commons.lang.StringUtils;

String input = StringUtils.substringBetween(value, "{", "}");
Map<String, String> map = 
Splitter.on(",").withKeyValueSeparator("=").split(input);