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?
Just to note: if you use
resteasy
implementation ofJAX RS Client API
, you may usebuild().invoke()
:But it does not work with
jersey
You can use
webTarget.request().accept(MediaType.TEXT_PLAIN).method("DELETE",yourEntity)
to invoke aDELETE
with an entity in it.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 aDELETE
is not used as it is intended.For instance: If a
GET /customers/4711
returns one customer and you send aDELETE /customers/4711
the nextGET
on this resource should return a404
. 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 aDELETE
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
and you want a result like
you are not deleting anything. You are modifying a resource so
PUT
,POST
orPATCH
are appropiate methods. JSON-Patch is a good format for describing such changes. A request would look like this:Based on the code in Jersey 2.18 version, The class
JerseyInvocation
use a predefined HashMap to validate HTTP method and its Entity as below:That's why we got this error "Entity must be null for http method DELETE".
While, please note that it also provide a Jersey client configuration property
ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION
to determine whether to stop the rest execution or not, so here we can use this property to suppress validation in order to continue to send aDELETE
request with Entity. e.g.