【问题标题】:How to get jackson to ignore non-DTO objects如何让杰克逊忽略非 DTO 对象
【发布时间】:2014-04-23 16:44:03
【问题描述】:

我们最近从 Sun Jersey 实施升级到 GlassFish Jersey 2.7。当我们这样做时,Jackson 开始尝试对我们的 Domain 对象进行反序列化。在我们的情况下,这不是我们想要的。我们有域设置,因此域对象永远不会通过 Web 服务直接发送出去。一切都转换为 DTO,然后发送出去。所以基本上我们只是调用

return Response.ok(new SomeFooBarDTOObject(someFooBarDomainObject)).build()

这用于与以前版本的 Jersey/Jackson 一起使用。使用更新的代码,我们会收到如下错误:

Conflicting setter definitions for property "preferredItem": com.foo.domain.FooBar#setPreferredItem(1 params) vs com.foo.domain.FooBar#setPreferredItem(1 params)

即使我们从未尝试发送实际的域对象。我们如何告诉 Jackson 只查看通过 Web 服务实际接收或发送的对象。

这是导致问题的 Web 服务,我已将其简化为仅此。如果我从方法参数中取出 RestaurantItemDTO restaurantItemDTO 它可以工作,但如果我把它放在里面它就不行。

RestaurantItemDTO 的字段中只有基本类型。它引用域对象的唯一方法是通过构造函数参数,还有一个公共的无参数构造函数。所以它不是唯一的构造函数。

@Controller
@Path("/restaurant/restaurantItem")
public class RestaurantItemWebService {
    @PUT
    @Path("/ordersheets/{ordersheetId}/{locationId}/restaurantItems/{restaurantItemId}")
    @Produces(value = MediaType.APPLICATION_JSON)
    @Consumes(value = MediaType.APPLICATION_JSON)
    @Transactional
    @PreAuthorize("hasRole('" + PermissionNames.SOME_PERMISSION+ "')")
    public Response saveExistingRestaurantItem(@PathParam("ordersheetId") Long orderSheetID, @PathParam("restaurantItemId") Long restaurantItemID, RestaurantItemDTO restaurantItemDTO) {
        return Response.ok(restaurantItemDTO).build();
    }

【问题讨论】:

  • 那个错误对我来说听起来很可疑。您确定您不会意外地将域对象传递给 POST 方法或从 GET 方法返回它吗?查看堆栈跟踪会有所帮助。
  • 不幸的是没有堆栈跟踪,服务器返回 400 并列出消息,但日志中没有生成堆栈跟踪。它也从未真正命中我们的任何代码。如果我尝试调试 Web 服务,则永远不会遇到断点。我检查了 Web 服务,它只需要一个 DTO 对象。没有域对象。不过,我将添加 Web 服务的代码。

标签: java spring jersey jackson


【解决方案1】:

好吧,我无法弄清楚 Jackson 为何如此行事,但我确实发现问题在于我有一个 DTO 的构造函数,它引用了域对象,即使 Jackson 不应该调用该构造函数,因为有一个默认的公共无参数构造函数可用,它仍然试图映射域对象。我解决了这个问题,但在引用域对象的构造函数上使用了@JsonIgnore。

【讨论】:

    猜你喜欢
    • 2022-06-22
    • 2014-06-22
    • 2016-04-19
    • 2016-01-16
    • 1970-01-01
    • 2016-09-11
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    相关资源
    最近更新 更多