Java “处理”;“未识别的令牌”;Jackson自定义json中的异常

Java “处理”;“未识别的令牌”;Jackson自定义json中的异常,java,json,data-binding,jackson,Java,Json,Data Binding,Jackson,我试图使用Jackson json解析器(v2.5.2)来解析一个不是真正的json的自定义json文档,我不知道如何使它工作。我有一个json文档,可能看起来像: { "test": { "one":"oneThing", "two": nonStandardThing(), "three": true } } 我想使用ObjectMapper将其映射到java.util.map,我只想将nonStandardThing()作为

我试图使用Jackson json解析器(v2.5.2)来解析一个不是真正的json的自定义json文档,我不知道如何使它工作。我有一个json文档,可能看起来像:

{
    "test": {
        "one":"oneThing",
        "two": nonStandardThing(),
        "three": true
    }
}
我想使用ObjectMapper将其映射到
java.util.map
,我只想将
nonStandardThing()
作为键
two
的字符串值添加到我的映射中

当我通过
ObjectMapper.readValue(json,Map.class)
运行此命令时,我得到一个异常:

com.fasterxml.jackson.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.jackson.core.JsonParser._constructError(JsonParser.java:1487)
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:518)
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2300)
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2277)
我曾尝试使用
ObjectMapper
注册一个
反序列化ProblemHandler
,但在出现此问题时从未调用它

下面是一个示例应用程序,显示了我所尝试的内容:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

public class JacksonDeserializerTest {
    private Logger log = Logger.getLogger(JacksonDeserializerTest.class.getName());
    public JacksonDeserializerTest() {
        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) {
        JacksonDeserializerTest test = new JacksonDeserializerTest();
    }
}
import com.fasterxml.jackson.core.JsonParser;
导入com.fasterxml.jackson.core.JsonProcessingException;
导入com.fasterxml.jackson.databind.DeserializationContext;
导入com.fasterxml.jackson.databind.JsonDeserializer;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
导入java.io.IOException;
导入java.util.Map;
导入java.util.logging.Level;
导入java.util.logging.Logger;
公共类jacksondertest{
私有记录器log=Logger.getLogger(JacksonTest.class.getName());
公共jacksondertest(){
字符串validJson=“{\'test\':{\'test1\':\'one\',\'test2\':\'two\'}”;
字符串invalidJson=“{\'test\”:{\'test1\”:非标准();
ObjectMapper mapper=新的ObjectMapper();
addHandler(新的反序列化ProblemHandler(){
@凌驾
公共布尔handleUnknownProperty(反序列化上下文dc、JsonParser jp、JsonDeserializer jd、对象bean、字符串属性)抛出IOException、JsonProcessingException{
System.out.println(“处理未知属性:+属性”);
返回false;
}
});
试一试{
log.log(Level.INFO,“有效的json看起来像:{0}”,mapper.readValue(validJson,Map.class.toString());
log.log(Level.INFO,“无效的json看起来像:{0}”,mapper.readValue(invalidJson,Map.class.toString());
}捕获(IOEX异常){
log.log(Level.severy,“错误解析json”,ex);
}
}
公共静态void main(字符串[]args){
JacksonDeserializerTest=新的JacksonDeserializerTest();
}
}
输出如下所示:

Apr 24, 2015 1:40:27 PM net.acesinc.data.json.generator.jackson.JacksonDeserializerTest <init>
INFO: Valid json looks like: {test={test1=one, test2=two}}
Apr 24, 2015 1:40:27 PM net.acesinc.data.json.generator.jackson.JacksonDeserializerTest <init>
SEVERE: Error parsing json
com.fasterxml.jackson.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.jackson.core.JsonParser._constructError(JsonParser.java:1487)
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:518)
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2300)
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2277)
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._matchToken(ReaderBasedJsonParser.java:2129)
2015年4月24日下午1:40:27 net.acesinc.data.json.generator.jackson.jacksonderest
信息:有效的json看起来像:{test={test1=one,test2=two}
2015年4月24日下午1:40:27 net.acesinc.data.json.generator.jackson.jacksonderest
严重:解析json时出错
com.fasterxml.jackson.core.JsonParseException:无法识别的标记“非标准”:应为“null”、“true”、“false”或“NaN”
在[Source:{“test”:{“test1”:nonStandardThing(),“test2”:“two”};第1行,第35列]
位于com.fasterxml.jackson.core.JsonParser.\u constructError(JsonParser.java:1487)
在com.fasterxml.jackson.core.base.ParserMinimalBase.\u报告错误(ParserMinimalBase.java:518)
位于com.fasterxml.jackson.core.json.ReaderBasedJsonParser.\u reportInvalidToken(ReaderBasedJsonParser.java:2300)
位于com.fasterxml.jackson.core.json.ReaderBasedJsonParser.\u reportInvalidToken(ReaderBasedJsonParser.java:2277)
位于com.fasterxml.jackson.core.json.ReaderBasedJsonParser.\u matchToken(ReaderBasedJsonParser.java:2129)

有人能指出为什么处理程序从未被调用吗?或者,如果有更好的方法解析这个定制json文档(jackson与否…),请告诉我

未调用处理程序,因为无效部分不是属性(
“two”
),而是值(
非标准()

处理此问题的一个明显方法是将
非标准()作为
字符串传递,即将JSON文档重写为

{
    "test": {
        "one":"oneThing",
        "two": "nonStandardThing()",
        "three": true
    }
}

如果不可能的话,那就没什么可做的了。使用自定义的
Jackson
反序列化器
只对属性有用,而不是值。

您列出的内容不幸不是有效的JSON,因此您拥有的不是真正的JSON文档,而是Javascript对象的序列化。 所有字符串值必须在JSON中用双引号括起来

Jackson不支持直接读取此类内容,但可以使用类似SnakeYAML的YAML解析器来读取这些内容。
Jackson在上还有YAML数据格式模块,所以您也许可以使用它。考虑到YAML(主要是!)是JSON的超集,它可能会做你想做的事。

而Jackson反序列化程序
你指的是定制的java.util.Map反序列化程序?这正是我所担心的…即使这样也不能提供解决方案。从
Jackson
邮件列表中的讨论可以清楚地看出,当前存在的是属性而不是值的必要功能。您可能无法控制序列化过程+1问一个有趣的问题。:-)实际上,我可能可以更改此格式,但有趣的是,
Jackson
不允许您处理值。糟糕,因为它可能再次发生。我想您可以预处理json以引用非标准值并使其有效。不管怎么说,你的回答(我以前曾想过)让我再次以不同的方式思考这个问题,现在我正在重新设计,以更好地适应这个问题。谢谢感谢您对YAML解析器的建议!下一次我必须尝试一下。对于仍然需要解决方案的任何人来说,定制Jackson行为的另一种方法是定制JsonParser。请参阅jackson的JsonFactory源代码,ReaderBaseJSONParser#nextToken();看见