目前我们正在使用 Gson 将 JSON String 转换为 Map
目前如果我们要将以下 Json String 转换为 Map
"{"jwt":abc.def.ghi}"
请注意,针对键“jwt”的值不是字符串。
String jsonString = "{\"jwt\":abc.def.ghi}";
Type type = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> tokens = new Gson().fromJson(jsonString, type);
Gson成功转换为
tokens = {"jwt":"abc.def.ghi"}
使用ObjectMapper的相应代码:
Map<String, String> tokens = objectMapper.readValue(jsonString, new TypeReference<>() {});
尝试使用 ObjectMapper 时,抛出以下异常:
com.fasterxml.jackson.core.JsonParseException 发现无法识别的令牌“abc.def.ghi”....
问题在于,与 Gson 不同,ObjectMapper 无法将
abc.def.ghi
解析为 "abc.def.ghi"
。
为了达到要求的结果,我的正确方法应该是什么。
在将它传递给
objectMapper.writeValueAsString()
之前,我已经尝试过readValue()
。仍然没有进展。
简单;天真的解决方案是使用正则表达式来修复有问题的 JSON:
图案:
(?<=":\s?)(?<unquoted>[^\{\}"]+)(?=,?)
这个模式包括一个积极的回顾,检查前面的报价。后跟一个冒号和一个可选的空格。这将是一个潜在的关键/道具。
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Deserializer {
private static final ObjectMapper objectMapper;
private static final TypeReference<Map<String, String>> mapType;
static {
objectMapper = new ObjectMapper();
mapType = new TypeReference<Map<String, String>>() { };
}
public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
String invalidJsonString = "{\"jwt\":abc.def.ghi}";
String jsonString = fixUnquotedJsonValues(invalidJsonString);
Map<String, String> tokens = objectMapper.readValue(jsonString, mapType);
System.out.println(tokens);
}
public static String fixUnquotedJsonValues(String invalidJson) {
return invalidJson.replaceAll(
"(?<=\\\":\\s?)(?<unquoted>[^\\{\\}\\\"]+)(?=,?)",
"\"${unquoted}\"");
}
}