杰克逊不使用二传手

时间:2016-10-29 23:00:52

标签: java json rest jackson jax-rs

我知道过去曾提出这类问题,但问题并不完全相同,所以我找到了提出这个问题的权利。

我将JERSEY与JACKSON一起用于REST Web服务(JAVA 1.8_011 + Tomcat v7.0 + windows 7 + JERSEY-common 2.23.2 + JACKSON 2.8.2)

我的一个POJO字段有以下setter:

public void setEndDate(LocalDateTime endDate) {
    if (this.startDate != null && this.startDate.isAfter(endDate))
    {
        throw new IllegalArgumentException("Start date must to be before End date");
    }
    this.endDate = endDate;
}

我的网络服务如下:

@PUT
@Path("/updateCoupon")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public String updateCoupon(Coupon coupon)  {

    try 
    {
        //Coupon tmpCoupon = new Coupon(coupon);
        System.out.println("*" + coupon.getEndDate().toString() + "*");
        getFacade().updateCoupon(coupon);
        return "ok";
    } 
    catch (FacadeException | IllegalArgumentException e) 
    {
        return e.getMessage();
    }

}

JSON:

{ 
    "startDate":"2016-11-04T00:00",
    "endDate":"2016-11-09T00:00",
    "amount":7,
    "id":143,
    "image":"390_290_5cc10a4d-9a3f-4cfc-8.jpg",
    "message":"gfd",
    "price":3.34,
    "title":"n37",
    "type":"HEALTH"
 }

经过调试和测试后,问题是JSON没有使用我的setter从JSON转换为POJO(它发生在更多的setter中,因此setter自身不是问题)

由于

1 个答案:

答案 0 :(得分:1)

您当前的优惠券代码取决于调用setter的顺序。如果在setStartDate之前调用setEndDate,则setEndDate中的验证实际上不能使用startDate字段。

要解决此问题,您可以:

  • 从bean中删除setter并转换为使用执行验证逻辑的构造函数进行初始化
  • 使用静态工厂方法并用@JsonCreator标记它,以便杰克逊将使用它而不是构造函数
  • 上述两件事的某种组合
  • 切换到某种bean对象创建器,它允许您在调用所有setter之后创建一个check方法(基本上是第二个选项的自动版本),例如Immutables或FreeBuilder