【问题标题】:Jackson Deserializer has no default(no arg) constructorJackson Deserializer 没有默认(无 arg)构造函数
【发布时间】:2018-04-20 11:30:11
【问题描述】:

首先,我知道这个问题: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

我该如何解决这个问题?是默认构造函数有问题,还是其他地方有错误?

【问题讨论】:

  • 尝试添加一个默认的空构造函数
  • 添加构造函数后你清理重建了吗?

标签: java json jackson deserialization


【解决方案1】:

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

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

而 Jackson 可能正在尝试实例化类(简化,实际上它使用 Java 反射 API)

ServiceDeserializer sd = new JsonAdapter.ServiceDeserializer();

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

public static class ServiceDeserializer extends StdDeserializer<Service>

【讨论】:

    猜你喜欢
    • 2017-08-30
    • 1970-01-01
    • 2019-04-13
    • 2023-03-20
    • 2016-07-18
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多