Jackson Deserializer没有默认(无arg)构造函数

时间:2018-04-20 11:30:11

标签: java json jackson deserialization

首先,我知道这个问题:CustomDeserializer has no default (no arg) constructor

我使用了推荐的解决方案,但仍然存在同样的问题。 当我尝试反序列化我的json时,我仍然会收到错误。

我想要对我的对象进行自定义反序列化。我的单元测试看起来如下:

Service service = new Service();
service.setId("ID");
service.setTitle("Title");
service.setDescription("Description");
service.setType("Service");

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(service);
Service service2 = mapper.readValue(json, Service.class);

我的反序列化器(包含目前单元测试未涵盖的一些功能,但他甚至没有达到这个目的):

public class ServiceDeserializer extends StdDeserializer<Service> {

    public ServiceDeserializer() {
        super(Service.class);
    }

    @Override
    public Service deserialize(final JsonParser jp, final DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        DataBaseManagment manager = DataBaseManagmentManager.getInstance();
        List<DataObject> objects = manager.readAll("Utility", true);
        JsonNode node = jp.getCodec().readTree(jp);
        String id = node.get("id").asText();
        String title = node.get("title").asText();
        String description = node.get("description").asText();
        Service service = new Service(id, title, description);
        for (JsonNode utility : node.get("provides")) {
            String checkId = utility.get("id").asText();
            for (DataObject object : objects) {
                if (object.getId().equals(checkId)) {
                    service.addUtility((Utility) object);
                    break;
                }
            }
        }
        return service;
    }
}

绑定:

@Entity
@Table(name = "SERVICE")
@JsonDeserialize(using = ServiceDeserializer.class)
public class Service extends DataObject {
   ...
}

错误堆栈:

com.fasterxml.jackson.databind.JsonMappingException: Class de.fraunhofer.fkie.aidpfm.reader.utils.JsonAdapter$ServiceDeserializer has no default (no arg) constructor
 at [Source: (String)"{"pk":0,"id":"ID","title":"Title","description":"Description","type":"Service","provides":[],"fulfills":[],"ensures":[],"consistsOf":[],"partOf":[],"requires":[],"requiredBy":[],"classifiedBy":[]}"; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:305)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:268)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:477)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4178)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3997)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
at de.fraunhofer.fkie.aidpfm.model.JsonConvertionTest.jsonToObjectTest(JsonConvertionTest.java:123)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: java.lang.IllegalArgumentException: Class de.fraunhofer.fkie.aidpfm.reader.utils.JsonAdapter$ServiceDeserializer has no default (no arg) constructor
at com.fasterxml.jackson.databind.util.ClassUtil.createInstance(ClassUtil.java:553)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.deserializerInstance(DefaultDeserializationContext.java:229)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findDeserializerFromAnnotation(DeserializerCache.java:427)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:326)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
... 30 more

如何解决此问题?默认构造函数有问题,还是其他地方的错误?

1 个答案:

答案 0 :(得分:7)

考虑de.fraunhofer.fkie.aidpfm.reader.utils.JsonAdapter$ServiceDeserializerServiceDeserializer似乎是JsonAdapter的内部类。非static的内部类只能初始化为:

JsonAdapter outerClass = new JsonAdapter();
ServiceDeserializer innerClass = outerClass.new ServiceDeserializer();

杰克逊可能试图将类实例化(简化,实际上是使用Java Reflection API)

ServiceDeserializer sd = new JsonAdapter.ServiceDeserializer();

但这不起作用,因为ServiceDeserializer是一个内部的,非静态的类。要简单地解决问题,请制作ServiceDeserializer static

public static class ServiceDeserializer extends StdDeserializer<Service>