Java 使用 Jackson 处理自定义 json 中的“无法识别的令牌”异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29856116/
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
Handling "Unrecognized token" exception in custom json with Hymanson
提问by Andrew Serff
I'm trying to use the Hymanson json parser(v2.5.2) to parse a custom json document that isn't true json and I can't figure out how to make it work. I have a json document that might look like:
我正在尝试使用 Hymanson json 解析器(v2.5.2)来解析一个不是真正的 json 的自定义 json 文档,我不知道如何使它工作。我有一个 json 文档,可能如下所示:
{
"test": {
"one":"oneThing",
"two": nonStandardThing(),
"three": true
}
}
I want to use the ObjectMapper to map this to a java.util.Map
and I would just like the nonStandardThing()
to be added as a String value in my map for the key two
.
我想使用 ObjectMapper 将其映射到 a java.util.Map
,我只想nonStandardThing()
将 的作为 String 值添加到我的映射中的 key two
。
When I run this through the ObjectMapper.readValue(json, Map.class)
I get the exception:
当我运行它时,ObjectMapper.readValue(json, Map.class)
我得到了异常:
com.fasterxml.Hymanson.core.JsonParseException: Unrecognized token 'nonStandardThing': was expecting 'null', 'true', 'false' or NaN
at [Source: { "test":{"test1":nonStandardThing(),"test2":"two"}}; line: 1, column: 35]
at com.fasterxml.Hymanson.core.JsonParser._constructError(JsonParser.java:1487)
at com.fasterxml.Hymanson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:518)
at com.fasterxml.Hymanson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2300)
at com.fasterxml.Hymanson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2277)
I have tried to register a DeserializationProblemHandler
with the ObjectMapper
but it is never called when this problem occurs.
我曾尝试向 注册DeserializationProblemHandler
,ObjectMapper
但在发生此问题时从未调用过。
Here is sample application that shows what I have tried:
这是显示我尝试过的示例应用程序:
import com.fasterxml.Hymanson.core.JsonParser;
import com.fasterxml.Hymanson.core.JsonProcessingException;
import com.fasterxml.Hymanson.databind.DeserializationContext;
import com.fasterxml.Hymanson.databind.JsonDeserializer;
import com.fasterxml.Hymanson.databind.ObjectMapper;
import com.fasterxml.Hymanson.databind.deser.DeserializationProblemHandler;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class HymansonDeserializerTest {
private Logger log = Logger.getLogger(HymansonDeserializerTest.class.getName());
public HymansonDeserializerTest() {
String validJson = "{ \"test\":{\"test1\":\"one\",\"test2\":\"two\"}}";
String invalidJson = "{ \"test\":{\"test1\":nonStandardThing(),\"test2\":\"two\"}}";
ObjectMapper mapper = new ObjectMapper();
mapper.addHandler(new DeserializationProblemHandler() {
@Override
public boolean handleUnknownProperty(DeserializationContext dc, JsonParser jp, JsonDeserializer<?> jd, Object bean, String property) throws IOException, JsonProcessingException {
System.out.println("Handling unknown property: " + property);
return false;
}
});
try {
log.log(Level.INFO, "Valid json looks like: {0}", mapper.readValue( validJson, Map.class).toString());
log.log(Level.INFO, "Invalid json looks like: {0}", mapper.readValue(invalidJson, Map.class).toString());
} catch (IOException ex) {
log.log(Level.SEVERE, "Error parsing json", ex);
}
}
public static void main(String[] args) {
HymansonDeserializerTest test = new HymansonDeserializerTest();
}
}
The output looks like:
输出看起来像:
Apr 24, 2015 1:40:27 PM net.acesinc.data.json.generator.Hymanson.HymansonDeserializerTest <init>
INFO: Valid json looks like: {test={test1=one, test2=two}}
Apr 24, 2015 1:40:27 PM net.acesinc.data.json.generator.Hymanson.HymansonDeserializerTest <init>
SEVERE: Error parsing json
com.fasterxml.Hymanson.core.JsonParseException: Unrecognized token 'nonStandardThing': was expecting 'null', 'true', 'false' or NaN
at [Source: { "test":{"test1":nonStandardThing(),"test2":"two"}}; line: 1, column: 35]
at com.fasterxml.Hymanson.core.JsonParser._constructError(JsonParser.java:1487)
at com.fasterxml.Hymanson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:518)
at com.fasterxml.Hymanson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2300)
at com.fasterxml.Hymanson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2277)
at com.fasterxml.Hymanson.core.json.ReaderBasedJsonParser._matchToken(ReaderBasedJsonParser.java:2129)
Can anyone point out why the Handler never gets called? Or, if there is a better parse this custom json document (Hymanson or not...), let me know.
谁能指出为什么 Handler 永远不会被调用?或者,如果有更好的解析这个自定义 json 文档(Hyman逊与否...),请告诉我。
采纳答案by PNS
The handler is not called because the invalid part is not the property ("two"
) but the value (nonStandardThing()
).
不会调用处理程序,因为无效部分不是属性 ( "two"
) 而是值 ( nonStandardThing()
)。
An obvious way to handle this, is to pass nonStandardThing()
as a String
, i.e. rewrite the JSON document as
处理这个问题的一个显而易见的方法是nonStandardThing()
作为 a传递,即将String
JSON 文档重写为
{
"test": {
"one":"oneThing",
"two": "nonStandardThing()",
"three": true
}
}
If that is not a possibility, there is not much to do. Using a custom Hymanson
Deserializer
is only useful for properties, not values.
如果这不可能,那就没什么可做的了。使用自定义Hymanson
Deserializer
仅对属性有用,而不对值有用。
回答by StaxMan
Content you list is unfortunately not valid JSON, so what you have is not really a JSON document, but perhaps serialization of a Javascript object. All String values MUST be enclosed in double quotes in JSON.
不幸的是,您列出的内容不是有效的 JSON,因此您所拥有的并不是真正的 JSON 文档,而是 Javascript 对象的序列化。在 JSON 中,所有字符串值都必须用双引号括起来。
Hymanson does not support reading of such content directly, but it may be possible to read this using YAML parser like SnakeYAML. Hymanson also has YAML data format module at https://github.com/FasterXML/Hymanson-dataformat-yaml/so you could perhaps use that. Given that YAML is (mostly!) a superset of JSON, it could probably do what you want.
Hymanson 不支持直接读取此类内容,但可以使用 YAML 解析器(如 SnakeYAML)读取这些内容。Hymanson 在https://github.com/FasterXML/Hymanson-dataformat-yaml/也有 YAML 数据格式模块,所以你也许可以使用它。鉴于 YAML 是(主要是!)JSON 的超集,它可能可以满足您的需求。