我正在使用Spring MVC来处理JSON帖子请求。在封面下面,我正在使用jackson JSON处理器上构建的MappingJacksonHttpMessageConverter,并在使用MVC:注释驱动时启用。

我的一项服务收到了一系列措施:

@RequestMapping(value="/executeActions", method=RequestMethod.POST)
    public @ResponseBody String executeActions(@RequestBody List<ActionImpl> actions) {
        logger.info("executeActions");
        return "ACK";
    }

我发现杰克逊将请求机构映射到java.util.linkedhashmap项目(简单数据绑定)的列表。相反,我希望该请求绑定到键入对象列表(在这种情况下为“ ActionImpl”)。

我知道,如果您直接使用Jackson的ObjectMapper,这很容易做到:

List<ActionImpl> result = mapper.readValue(src, new TypeReference<List<ActionImpl>>() { }); 

但是我想知道,当使用Spring MVC和MappingJacksonHtpMessageConverter时,最好的方法是什么。有提示吗?

谢谢

有帮助吗?

解决方案

我怀疑问题是由于类型擦除,即而不是传递通用参数类型,也许只传递action.getClass()。这将给出等效列表<?>的类型。

如果这是真的,一种可能性是使用中级子类,例如:

public class ActionImplList extends ArrayList<ActionImpl> { }

因为这将保留类型信息,即使仅通过了类。因此:

public @ResponseBody String executeActions(@RequestBody ActionImplList actions)

会做到的。不是最佳的,但应该起作用。

我希望有更多春季MVC知识的人能否阐明为什么没有通过参数类型(也许是一个错误?),但至少有一项工作。

其他提示

我发现您还可以通过使用数组作为@requestbody而不是集合来解决擦除类型问题。例如,以下将有效:

public @ResponseBody String executeActions(@RequestBody ActionImpl[] actions) { //... }

有关您的信息,该功能将在春季3.2中提供(请参阅 https://jira.springsource.org/browse/spr-9570)

我刚刚在当前的M2上进行了测试,它的工作方式就像是一个开箱即用的魅力(无需提供添加注释来提供参数化类型,它将由新的MessageConverter自动解决)

这个问题已经老了,但是我认为我可以做出一些贡献。

就像Staxman指出的那样,这是由于类型擦除。绝对是 应该 有可能,因为你 能够 通过从方法定义进行反思获取通用参数。但是,问题是 httpmessageconverter:

T read(Class<? extends T> clazz, HttpInputMessage inputMessage);

在这里,只有List.Class将传递给该方法。因此,如您所见,无法通过查看方法参数类型来实现httpmessageconverter,该httpmessageconverter可以计算真实类型。

但是,可以编码自己的解决方法 - 您不会使用httpmessageconverter。春季MVC允许您写自己的 WebargumentResolver 这是在标准分辨率方法之前开始的。例如,您可以使用自己的自定义注释(@jsonrequestbody?),该注释直接使用ObjectMapper来解析您的价值。您将能够从该方法提供参数类型:

final Type parameterType= method.getParameterTypes()[index];
List<ActionImpl> result = mapper.readValue(src, new TypeReference<Object>>() {
    @Override
    public Type getType() {
        return parameterType;
    }
});

我认为并不是真正打算使用分键的方式,但是ObjectMapper并没有提供更合适的方法。

您是否尝试将该方法声明为:

executeActions(@RequestBody TypeReference<List<ActionImpl>> actions)

我没有尝试过,但是根据您的问题,这是我的第一件事 尝试。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top