我在SpringBoot上下文中使用JSON Jackson。
我对使用通用类型约束的Jackson反序列化有问题。

这段代码可以正常工作:


public abstract class AbstractSyncableWriteAndReadResource<T, K> extends AbstractSyncableReadResource<T, K> {

    ...

    @Timed
    @RequestMapping(method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
    @Transactional
    public ResponseEntity<List<SynQueuDTO<T>>> syncPushPut(@RequestBody List<SynQueuDTO<T>> entities) {
        ...
    }

}


但是这段代码不起作用:
这段代码可以正常工作:


public abstract class AbstractSyncableWriteAndReadResource<T extends EntitySyncableWrite, K> extends AbstractSyncableReadResource<T, K> {

    ...

    @Timed
    @RequestMapping(method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
    @Transactional
    public ResponseEntity<List<SynQueuDTO<T>>> syncPushPut(@RequestBody List<SynQueuDTO<T>> entities) {
        ...
    }

}


仅有一个区别:在Generic上添加Java接口以获取约束类的类型。

例外情况:

Type definition error: [simple type, class xxx.xxx.xxx.EntitySyncableWrite]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `xxx.xxx.xxx.EntitySyncableWrite` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information\n at [Source: (PushbackInputStream); line: 5, column: 26]


我尝试了很多配置来强制Jackson接受Class而不是Interface信息,但是没有成功:
@JsonTypeInfo(use= JsonTypeInfo.Id.NAME, include= JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")(ko)

你有什么主意吗

谢谢



[更新]

另一个很好用的用例:

public abstract class AbstractSyncableWriteAndReadResource<T extends EntitySyncableWrite, K> ... {

public ResponseEntity<List<SyncQueuDTO<T>>> syncPushPut( @RequestBody SyncQueuDTO<T> data) {
...
}

}


但是在将RequestBody添加为List时不起作用:

public abstract class AbstractSyncableWriteAndReadResource<T extends EntitySyncableWrite, K> ... {

public ResponseEntity<List<SyncQueuDTO<T>>> syncPushPut( @RequestBody List<SyncQueuDTO<T>> data) {
...
}

}


例外情况:

Type definition error: [simple type, class xx.xx.xx.EntitySyncableWrite]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `xx.xx.xx.EntitySyncableWrite` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information\n at [Source: (PushbackInputStream); line: 5, column: 26] (through reference chain: java.util.ArrayList[0]->xx.xx.xx.SyncQueuDTO[\"serverVersion\"])

最佳答案

借助Map JSON array of objects to @RequestBody List<T> using jackson的灵感,我解决了这个Jackson / JVM的局限性:

public abstract class AbstractSyncableWriteAndReadResource<T extends EntitySyncableWrite, K> extends AbstractSyncableReadResource<T, K> {
  ...

public ResponseEntity<List<SyncQueuDTO<T>>> syncPushPut(@RequestBody SyncQueuDTOList<T> queuList) {
....
}
}


和ArrayList实现:

public class SyncQueuDTOList<T extends EntitySyncableWrite> extends ArrayList<SyncQueuDTO<T>> {}

08-16 12:11