java 将不带引号的json字符串转换为地图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36582892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 01:38:18  来源:igfitidea点击:

Convert json string without quotes into a map

javajsonHymansonmapper

提问by user2869231

I have a string that is in Json format, only none of the keys or values are surrounded by quotes. For example, I have this:

我有一个 Json 格式的字符串,只有没有一个键或值被引号包围。例如,我有这个:

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

I want this to become a map that looks like so:

我希望这成为一个看起来像这样的地图:

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

I have tried the following two methods:

我尝试了以下两种方法:

ObjectMapper mapper = new ObjectMapper();
mapper.readValue(json, new TypeReference<Map<String, Object>>() {});

This will throw an error, saying:

这将抛出一个错误,说:

Unexpected character ('n'): was expecting double-quote to start field name

Then I tried changing the config of mapper:

然后我尝试更改映射器的配置:

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

But this threw an error saying:

但这引发了一个错误说:

com.fasterxml.Hymanson.core.JsonParseException: Unrecognized token 'Bob': was expecting ('true', 'false' or 'null')
at [Source: {name: Bob, state: Colorado, Friends: [{ name: Dan, age: 23 }, {name: Zane, age: 24 }]}; line: 1, column: 11]

Is there a way of getting this Map when quotes aren't included in the json string?

当 json 字符串中不包含引号时,是否有获取此 Map 的方法?

回答by Brian

To answer your question: There is no safeway of getting your JSON - which is not JSON by the way, because it's invalid - converted into a Map<String, Object>.

回答你的问题:没有安全的方法可以让你的 JSON - 顺便说一下,它不是 JSON,因为它是无效的 - 转换为Map<String, Object>.

Let me elaborate just a little bit (why can't it be parsed safely?): Imagine a "JSON" like this:

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

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

Valid JSON would look something like this

有效的 JSON 看起来像这样

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

With the quotes a parser can safely determine keys and values. Without them a parser is lost.

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

回答by u11460018

you may could use the following code to preprocess the json string and then parse it.

您可以使用以下代码对 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(":\"?([^{|^]*?)\"?(?=[,|}|\]])",":\"\"").replaceAll("\"?(\w+)\"?(?=:)","\"\""));
    JSONObject obj = JSON.parseObject(str);
    System.out.println(obj.getJSONObject("request").getString("token"));

回答by epox

SINCE Java 15

自 Java 15

NOTE: we expect Java 15 will support unescaped double-quotes as is:

注意:我们预计 Java 15 将支持未转义的双引号:

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

more details

更多细节



SINCE GSON v2.8.6

由于 GSON v2.8.6

ObjectMapper with Hymanson fasterxml doesn't support values without quotes, but GSON does:

带有 Hymanson fastxml 的 ObjectMapper 不支持不带引号的值,但 GSON 支持:

import com.fasterxml.Hymanson.databind.JsonNode;
import com.fasterxml.Hymanson.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);
}


EARLIER GSON

早期的 GSON

Before v2.8.6 GSON didn't have the static parseString method. So you should use the (deprecated in higher versions) instance method:

在 v2.8.6 之前 GSON 没有静态 parseString 方法。所以你应该使用(在更高版本中已弃用)实例方法:

JsonNode json(String content) throws IOException {

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

回答by Benoit Vanalderweireldt

The ObjectMapper won't be able to parse the Json input if it's not valid, so the answer is no.

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

Test your Json here : http://jsonlint.com/

在这里测试您的 Json:http: //jsonlint.com/

After correcting the Json input you could do :

更正 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"));

Will print :

将打印:

Bob

鲍勃

回答by Dhruv

We can convert such a json to a Map using Apache Commons and Guava base libraries. Example: Input - {name=Hyman, id=4} Output - Map(name = Hyman, id = 4)

我们可以使用 Apache Commons 和 Guava 基础库将这样的 json 转换为 Map。示例:输入 - {name=Hyman, id=4} 输出 - Map(name = Hyman, id = 4)

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