gpt4 book ai didi

java - Spring 通用 REST Controller : parsing request body

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:35:44 26 4
gpt4 key购买 nike

我有以下 Controller :

@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) {
}
}

SomeSuperEntity 类如下所示:

public abstract class SomeSuperEntity extends AbstractEntity {
// some logic
}

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;
}
}

SomeSuperEntity 的所有子类 - 简单的 JavaBeans。如果使用 findAll()findOne(id) 方法 - 一切正常。我在服务层创建实体,它以 JSON 形式返回给客户端,其中包含在子类和 AbstractEntity 中声明的所有字段。

但是当我尝试在 save(entity, body) 中获取请求正文时,出现以下错误:

Could not read document: Can not construct instance of SomeSuperEntity, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information

如果我从 SomeSuperEntity 中删除抽象,一切正常,但我请求正文我只得到那些在 AbstractEntity 中声明的字段。

这是我的问题,在我的案例中是否有解决此类问题的方法?如果不是,那么在没有任何结构变化的情况下,这里最好的解决方案是什么(为每个实体设置 subcontloller 不是一种选择)?将正文检索为纯文本是个好主意吗?还是为此使用 Map 会更好?

我使用 Spring v4.2.1 和 Jackson 2.6.3 作为转换器。

有一些关于通用 Controller 的信息,但我找不到任何适合我的情况的信息。因此,请导航以防出现重复问题。

提前致谢。

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);
}

然后,在服务层,我定义接收到的实体(在普通 json 中)并转换它:

final EntityMetaData entityMetadata = getEntityMetadataByName(alias);
final T parsedEntity = getGlobalGson().fromJson(entity, entityMetadata.getEntityType());

其中 EntityMetaDataenum,在实体别名和类之间定义了关系。别名来自 @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) {
}
}

对于返回的对象,这无关紧要,因为 Jackson 无论如何都会生成输出正确的 JSON,但看起来 Spring 无法以同样的方式处理传入的对象。

您可以尝试用 SomeSuperEntity 替换泛型并查看 Spring @RequestBody containing a list of different types (but same interface)

关于java - Spring 通用 REST Controller : parsing request body,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33660443/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com