Ole*_*nyj 7 java generics rest spring json
我有以下控制器:
@RestController
@RequestMapping(value = "/{entity}", produces = MediaType.APPLICATION_JSON_VALUE)
public class CrudController<T extends SomeSuperEntity> {
@RequestMapping(method = GET)
public Iterable<T> findAll(@PathVariable String entity) {
}
@RequestMapping(value = "{id}", method = GET)
public T findOne(@PathVariable String entity, @PathVariable String id) {
}
@RequestMapping(method = POST)
public void save(@PathVariable String entity, @RequestBody T body) {
}
}
Run Code Online (Sandbox Code Playgroud)
SomeSuperEntity
课程看起来像:
public abstract class SomeSuperEntity extends AbstractEntity {
// some logic
}
Run Code Online (Sandbox Code Playgroud)
而AbstractEntity
它的抽象类的一些领域:
public abstract class AbstractEntity implements Comparable<AbstractEntity>, Serializable {
private Timestamp firstField;
private String secondField;
public Timestamp getFirstField() {
return firstField;
}
public void setFirstField(Timestamp firstField) {
this.firstField = firstField;
}
public String getSecondField() {
return secondField;
}
public void setSecondField(String secondField) {
this.secondField = secondField;
}
}
Run Code Online (Sandbox Code Playgroud)
所有子类SomeSuperEntity
- 简单的JavaBeans.如果用findAll()
和findOne(id)
方法 - 一切正常.我在服务层创建实体,它以JSON的形式返回客户端,所有字段都在子类和in中声明AbstractEntity
.
但当我试图获取请求正文时save(entity, body)
,我得到以下错误:
无法读取文档:无法构造SomeSuperEntity的实例,问题:抽象类型需要映射到具体类型,具有自定义反序列化器,或者使用其他类型信息进行实例化
如果我删除摘要SomeSuperEntity
,一切正常,但我请求身体我只得到那些声明的字段AbstractEntity
.
这是我的问题,在我的案例中是否有针对此类问题的解决方法?如果没有,那么在没有任何结构变化的情况下,最佳解决方案会是什么(为每个实体制作子控制器不是一个选项)?将检索体作为纯文本是个好主意吗?或者它最好Map
用于此?
我使用Spring v4.2.1和Jackson 2.6.3作为转换器.
有一些关于通用控制器的信息,但我找不到任何涵盖我的情况.所以,请在重复问题的情况下导航.
提前致谢.
UPD:目前其工作方式如下:我添加了额外的检查,MessageConverter
并定义@RequestBody
为String
@Override
public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
if (IGenericController.class.isAssignableFrom(contextClass)) {
return CharStreams.toString(new InputStreamReader(inputMessage.getBody(), getCharset(inputMessage.getHeaders())));
}
return super.read(type, contextClass, inputMessage);
}
Run Code Online (Sandbox Code Playgroud)
然后,在服务层,我定义接收的实体(在普通的json中)并转换它:
final EntityMetaData entityMetadata = getEntityMetadataByName(alias);
final T parsedEntity = getGlobalGson().fromJson(entity, entityMetadata.getEntityType());
Run Code Online (Sandbox Code Playgroud)
哪里EntityMetaData
是enum
与实体别名和类之间的关系定义.别名来了@PathVariable
.
Spring真正看到的是:
public class CrudController {
@RequestMapping(method = GET)
public Iterable<Object> findAll(@PathVariable String entity) {
}
@RequestMapping(value = "{id}", method = GET)
public Object findOne(@PathVariable String entity, @PathVariable String id) {
}
@RequestMapping(method = POST)
public void save(@PathVariable String entity, @RequestBody Object body) {
}
}
Run Code Online (Sandbox Code Playgroud)
对于返回的对象并不重要,因为 Jackson 无论如何都会生成正确的 JSON 输出,但看起来 Spring 无法以相同的方式处理传入的对象。
您可以尝试仅用 SomeSuperEntity 替换泛型,并查看包含不同类型列表(但接口相同)的 Spring @RequestBody
归档时间: |
|
查看次数: |
14210 次 |
最近记录: |