1

I know this kind of question was raised in the past but not exactly the same issue so i found the right to ask this question.

I'm using JERSEY together with JACKSON for REST web service (JAVA 1.8_011 + Tomcat v7.0 + windows 7 + JERSEY-common 2.23.2 + JACKSON 2.8.2)

One of my POJO field has the following 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;
}

my web service is the following:

@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"
 }

After debugging and tests the problem is that the JSON does not use my setter to transform from JSON to the POJO (it happens in more setters so the setter it self is not the issue)

Thanks

Doe Johnson
  • 1,374
  • 13
  • 34
Tal Roth
  • 11
  • 3
  • what is the exception you get when you uncomment ? – s7vr Oct 29 '16 at 23:54
  • throw new IllegalArgumentException("Start date must to be before End date"); – Tal Roth Oct 30 '16 at 04:50
  • 1
    What exactly are you expecting? Which line of code fails? The sample json in your post has a start date before the end date so I don't understand what the issue is. – Phil Oct 31 '16 at 00:24
  • This is the problem, there is no exception thrown, the json i gave is just for formatting example. Once i send end date earlier than start date it should throw exception, in my case it keeps it as is and use end date earlier than start date. After i post this thread i found that the problem might be the exception mapper of Jackson that "block" from me to catch the exception – Tal Roth Oct 31 '16 at 05:03
  • May I point out that, in your context, validation concerns should be tackled with JSR303 a.k.a Bean Validation? There's already a solved question here on SO involving [start date should be before end date](http://stackoverflow.com/questions/1700295/java-bean-validation-jsr303-constraints-involving-relationship-between-several) – Doe Johnson Oct 31 '16 at 15:34

1 Answers1

1

Your current code for Coupon is dependent on the order that the setters are invoked. If setEndDate is invoked before setStartDate, the validation in setEndDate can't actually use the startDate field.

To fix the problem, you could:

  • remove setters from your bean and convert to initializing with a constructor that performs validation logic
  • use a static factory method and label it with @JsonCreator, so that Jackson will use that instead of the constructor
  • some combination of the two things above
  • switch to some kind of bean object creator which lets you author a check method to be run after all setters have been invoked (essentially an automatic version of the second option), such as Immutables, or FreeBuilder
Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
  • Hi, Thanks for your answer but this is not the issue I have another setter which doesn't based on another field and it does the same. Also i use annotation to define the invocation order and it also didn't help In addition it does not enter into the setter when the "translate" from JSON to the POJO perform by JACKSON. I tried annotation like @Jsonsetter without success – Tal Roth Oct 29 '16 at 23:28
  • Is the setter labeled with `@JsonProperty`? – Mark Elliot Oct 29 '16 at 23:33
  • +1 for this answer: if you HAVE to check co-constraints between values, you MUST use constructor or factory method ("creator", annotated with `@JsonCreator`) -- order of setters will be based on order in which JSON properties are encountered in content, and relying on that is dangerous in itself. – StaxMan Oct 31 '16 at 22:12