I have the following server-side code in Jersey 2.x:
@Path("/store/remove/from/group") @DELETE @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.TEXT_PLAIN) public Response removeStoresFromGroup(@FormParam("storeName") List<String> storeNames, @FormParam("groupName") String groupName) { //...... }
On client side, I want to use Jersey 2.x client to send a delete request to the above web service. However, from the documentation of Jersey client API, I didn’t find how to enclose the following data in DELETE request:
WebTarget webTarget = client.target("/store/remove/from/group"); MultivaluedMap<String, String> formData = new MultivaluedHashMap<String, String>(); List<String> storeName = new ArrayList<String>(); storeName.add("Store1"); storeName.add("Store2"); storeName.add("Store3"); formData.addAll("storeName", storeName); formData.add("groupName", "Group A"); Response response = webTarget.request().accept(MediaType.TEXT_PLAIN).delete(); //The delete() method doesn't take any entity body in the request.
From the Jersey client API, the SyncInvoker
class doesn’t support a delete
method with entity body as its argument. So I can only use either POST or PUT to send the data to the server like the following (but not for DELETE):
Response response = webTarget.request().accept(MediaType.TEXT_PLAIN).post(Entity.form(formData));
But I want to use DELETE request since the request is deleting some resources. How to send DELETE request with some entity data via Jersey client?
Advertisement
Answer
A DELETE
with an entity body is not strictly forbidden but it’s very uncommon and ignored by some frameworks/servers. The need of an entity body may indicate that a DELETE
is not used as it is intended.
For instance: If a GET /customers/4711
returns one customer and you send a DELETE /customers/4711
the next GET
on this resource should return a 404
. You deleted a resource identified by a URL like defined in the spec.
Your URL /store/remove/from/group
does not seem to identify a resource. Using identifiers like /store/4711
or /groups/4711
and sending a DELETE
on them would not fit your needs because you want to “remove a store from a group” not delete a store or a group.
Assuming you have a group resource
{ "id" : 4711, "stores" : [123, 456, 789] }
and you want a result like
{ "id" : 4711, "stores" : [123, 789] }
you are not deleting anything. You are modifying a resource so PUT
, POST
or PATCH
are appropiate methods. JSON-Patch is a good format for describing such changes. A request would look like this:
PATCH /groups/4711 HTTP/1.1 Content-Type: application/json-patch [ { "op" : "remove" "path" : "stores/1" } ]