PUT requests disapprove of JsonAnyGetter / JsonAnySetter annotations

I have an object that needs to accept arbitrary fields from a client, let's entities a Blob

. I defined my entity using annotations @JsonAnyGetter

/ @JsonAnySetter

to capture any fields that are not explicitly displayed:

@Document
public class Blob {
  @Id
  private ObjectId id;

  private Map<String, Object> additionalFields = new HashMap<>();

  Blob() {
  }

  public ObjectId getId() {
    return id;
  }

  @JsonAnySetter
  public void setAdditionalFields(final String key, final Object value) {
    this.additionalFields.put(key, value);
  }

  @JsonAnyGetter
  public Map<String, Object> getAdditionalFields() {
    return additionalFields;
  }
}

      

And then I have a rest repository that gives me the main CRUD endpoints:

public interface BlobRepository extends CrudRepository<Blob, ObjectId> {
}

      

POST works as expected and the response returns all fields to me:

POST /blobs HTTP/1.1
Content-Type: application/json
Accept: application/json

{
  "name": "bob",
  "size": "small",
  "color": "green"
}

HTTP/1.1 201 
Location: http://localhost:8080/blobs/5919e2e292034b6765507cd4
Content-Type: application/json;charset=UTF-8

{
  "name" : "bob",
  "size" : "small",
  "color": "green",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/blobs/5919e2e292034b6765507cd4"
    },
    "blob" : {
      "href" : "http://localhost:8080/blobs/5919e2e292034b6765507cd4"
    }
  }
}

      

The problem is when I'm trying to update an existing blob with a PUT request:

PUT /blobs/5919e2e292034b6765507cd4 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
  "name": "bobby",
  "size": "large",
  "color": "blue"
}

HTTP/1.1 200 
Location: http://localhost:8080/blobs/5919e2e292034b6765507cd4
Content-Type: application/json;charset=UTF-8

{
  "name" : "bob",
  "size" : "small",
  "color": "green",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/blobs/5919d09d92034b5b219802b3"
    },
    "blob" : {
      "href" : "http://localhost:8080/blobs/5919d09d92034b5b219802b3"
    }
  }
}

      

None of the new fields are accepted, only the old value remains. Disappointingly though, PATCH requests work as expected:

PATCH /blobs/5919e2e292034b6765507cd4 HTTP/1.1
Content-Type: application/json
Accept: application/json

{
  "name": "bobby",
  "size": "large",
  "color": "blue"
}

HTTP/1.1 200 
Location: http://localhost:8080/blobs/5919e2e292034b6765507cd4
Content-Type: application/json;charset=UTF-8

{
  "name" : "bobby",
  "size" : "large",
  "color": "blue",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/blobs/5919d09d92034b5b219802b3"
    },
    "blob" : {
      "href" : "http://localhost:8080/blobs/5919d09d92034b5b219802b3"
    }
  }
}

      

I could be wrong, but I don't think it has to do with the semantics of PUT vs PATCH, as I am sending the full object to all fields, which I would expect a PUT to replace (or ideally merge) an existing object with new fields.

I created a repo with a minimal spring project and some tests that show the problem. Any passes would be appreciated.

+3


source to share





All Articles