Spring 引导/Jackson 反序列化错误类型的 JSON

Spring boot / Jackson deserializes JSON of wrong type

我有点迷茫,我不得不承认。我写了一个 Spring Boot (1.3M2) 应用程序接收一个 JSON object 它需要存储在数据库中:

@RequestMapping(value = "/fav", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public ResponseEntity<String> setFavorite(@RequestBody List<Favorite> favorites) {
...

在内部,此方法将 JSON 传递给另一个方法,该方法将其逐行存储在数据库中:

jdbcTemplate.batchUpdate(INSERT_FAVORITE, new BatchPreparedStatementSetter() {
                @Override
                public void setValues(PreparedStatement ps, int i) throws SQLException {
                    Favorit fav = favorites.get(i);
                    ps.setString( ...
                }

                @Override
                public int getBatchSize() {
                    int size = favorites.size();
                    return size;
                }

当我 POST 一个 JSON 到与我的 Favorite-object 结构不匹配的控制器时,我在我的数据库中只看到空值。显然,Jackson 尽最大努力将我的 JSON 转换为 Java object 但失败了,并将它发现没有值的 object 的所有值设置为 null。 然后这个排序为空的列表 objects 被写入数据库。

我使用 curl 来 POST 值

curl -vX POST https://localhost/fav -d @incorrectype.json 

这不可能是错误的来源,因为它适用于 favorite.json。如果我使用的 JSON 不匹配,如何让我的控制器/Jackson 检测到?

一个解决方案是使用来自 javax.validation 的注解,而不是在控制器签名中接受 List,而是使用自定义包装器(省略 getters/setters) :

public class FavoriteList {
  @Valid
  @NotNull
  @Size(min = 1)
  private List<Favorite> favorites;
}

然后对于 Favorite class 根据需要添加验证,例如。 g.:

public class Favorite {
  @NotNull
  private String id;
}

完成这些更改后,按照以下行修改控制器方法签名:

public ResponseEntity<String> setFavorite(@Valid @RequestBody FavoriteList favoritesList) {

这样,输入验证失败将在执行控制器方法中的任何内容之前抛出异常。