Home > Blockchain >  Could not read JSON: Can not construct instance from String value
Could not read JSON: Can not construct instance from String value

Time:09-23

I have pojo class Ticket

public class Ticket implements Serializable{

  @JsonProperty("lineItemStatus")
  private String revisionStatus;
  public String getRevisionStatus() {
    return revisionStatus;
  }
  
  public void setRevisionStatus(String revisionStatus) {
    this.revisionStatus = revisionStatus; 
  }

  public void setRevisionStatus(RevisionStatus revisionStatus) {
    String status = "";
    if (revisionStatus != null) {
      switch (revisionStatus) {
      case added: {
        status = "New";
        break;
      }
      case updated: {
        status = "Modified";
        break;
      }
      }
    }
    this.revisionStatus = status;
  }
}

Also I have an enum

public enum RevisionStatus {
    added {
      @Override
      public String getName() {
        return this.name();
      }
    },
    updated {
      @Override
      public String getName() {
        return this.name();
      }
    }
    public abstract String getName();
  }

During GET request , I use setRevisionStatus(RevisionStatus revisionStatus) method and i get response like for example {"lineItemStatus": "Modified"} which is fine But problem occurs during PUT request . During PUT request, my requirement is that I should be able to send payloads like for {"lineItemStatus": "Modified"} or {"lineItemStatus": "New"} or {"lineItemStatus": "abc"} , meaning lineItemStatus should be able to accept any String value . I am using @RequestBody Ticket ticket for receiving the payload. The debugger doesn't come inside the controller and fails at the payload step . How do I handle this error without making any changes inside Enum ?

CodePudding user response:

You can do it by updating your enum:

public enum RevisionStatus {
  added("New") {

    @Override
    public String getName() {
      return this.name();
    }
  },
  updated("Modified") {

    @Override
    public String getName() {
      return this.name();
    }
  };

  private String status;

  private RevisionStatus(String status) {
    this.status = status;
  }

  public abstract String getName();

  /**
   * @return the status
   */
  public String getStatus() {
    return status;
  }
  
  @JsonCreator
  public static RevisionStatus fromValue(String text) {
    if(StringUtils.isNoneBlank(text)) {
      for (RevisionStatus b : RevisionStatus.values()) {
        if (String.valueOf(b.toString()).equalsIgnoreCase(text.trim())) {
          return b;
        }
      }
    }
    return null;
  }
}

Here we have updated enum to value enum. And fromValue() method with @JsonCreator annotation will bind this String value with the Enum constant.

Additionally this way you won't need that switch cases during get method. As getStatus() method will give you the status value directly. And that will improve your code design also.

Just an additional point here, I don't see any need of this getName() method, as the placed where getName() is called, directly name() can be called. As that is also a public method.

  • Related