sp0*_*00m 3 java generics spring spring-mvc payload
我正在尝试为Spring MVC实现一个通用的REST控制器:
public abstract class GenericRestController<T extends GenericEntity> {
  protected final GenericService<T> service;
  public GenericRestController(GenericService<T> service) {
    this.service = service;
  }
  @RequestMapping(method = RequestMethod.GET)
  @ResponseStatus(HttpStatus.OK)
  public List<T> list() {
    return service.list();
  }
  @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
  @ResponseStatus(HttpStatus.CREATED)
  public T create(@RequestBody T entity) {
    return service.create(entity);
  }
  // other basic REST methods such as get(), delete(), etc.
}
然后,例如ArticleRestController:
@RestController
@RequestMapping(value = "/rest/articles", produces = MediaType.APPLICATION_JSON_VALUE)
public class ArticleRestController extends GenericRestController<Article> {
  @Autowired
  public ArticleRestController(ArticleService articleService) {
    super(articleService);
  }
}
让我们说一篇文章只有一个name领域String.
在通话时GET /rest/articles,我按预期获得持久文章列表.但是在调用时POST /rest/articles {name: "Any Article Name"},我会遇到以下异常:
java.lang.IllegalStateException: argument type mismatch
HandlerMethod details: 
Controller [com.basepackage.web.controllers.rest.ArticleRestController]
Method [public T com.basepackage.web.controllers.rest.support.GenericRestController.create(T)]
Resolved arguments: 
[0] [type=com.google.gson.internal.LinkedTreeMap] [value={name=Any Article Name}]
覆盖create方法时ArticleRestController,不再抛出异常:
  @Override
  @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
  @ResponseStatus(HttpStatus.CREATED)
  public Article create(@RequestBody Article article) {
    return articleService.create(article);
  }
知道为什么吗?可能是Spring T在用作@RequestBody?时无法解决泛型类型?
从Spring 4.1开始,a GsonHttpMessageConverter被添加到HttpMessageConverterSpring用于序列化从带@ResponseBody注释的处理程序方法返回的对象的实例列表中.此电流GsonHttpMessageConverter不够复杂,无法反序列化泛型类型.所以当它看到一个类型的变量T,它不会尝试点与类型参数连接Article中extends条款,而是使用默认LinkedTreeMap.
一种选择是将Jackson 2添加到您的类路径中.Spring将MappingJackson2HttpMessageConverter在之前注册GsonHttpMessageConverter.也就是说,它会先尝试使用它.杰克逊的转换器非常智能,可以执行通用的反序列化.
| 归档时间: | 
 | 
| 查看次数: | 4213 次 | 
| 最近记录: |