How to send nested data to DELETE request in jersey client?

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 the client side, I want to use the Jersey 2.x client to send a request to remove the above web service. However, from the Jersey client API documentation, I did not find how to enclose the following data in a 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. 

In the Jersey SyncInvoker client SyncInvoker class does not support the delete method with the entity body as an argument. Therefore, I can only use POST or PUT to send data to the server as follows (but not for DELETE):

 Response response = webTarget.request().accept(MediaType.TEXT_PLAIN).post(Entity.form(formData)); 

But I want to use a DELETE query, as the query deletes some resources. How to send a DELETE request with the data of an object through a Jersey client?

+7
java rest jersey jax-rs
source share
4 answers

A DELETE with the body is not strictly forbidden , but it is very unusual and is ignored by some frameworks / servers. The need for an entity body may indicate that a DELETE not used because it is intended.

For example: if a GET /customers/4711 returns one client and you send DELETE /customers/4711 , the next GET on this resource should return 404 . You have removed the resource identified by the URL , for example, as defined in the specification .

Your URL /store/remove/from/group does not seem to identify the resource. Using identifiers like /store/4711 or /groups/4711 and sending DELETE to them would not suit your needs, because you want to β€œremove the repository from the group” without deleting the repository or the 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 the resource, so PUT , POST or PATCH are the appropriate methods. JSON-Patch is a good format for describing such changes. The request will look like this:

 PATCH /groups/4711 HTTP/1.1 Content-Type: application/json-patch [ { "op" : "remove" "path" : "stores/1" } ] 
+3
source share

Based on the code for Jersey version 2.18, the JerseyInvocation class uses a predefined HashMap to test the HTTP method and its Entity, as shown below:

 map.put("DELETE", EntityPresence.MUST_BE_NULL); map.put("GET", EntityPresence.MUST_BE_NULL); ... 

That's why we got this error: "Entity must be null for http method DELETE."

At the same time, note that it also provides the Jersey client configuration property ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION to determine whether to stop the stop or not, so we can use this property to suppress validation to continue sending the DELETE request with Entity. eg

  ClientConfig config = new ClientConfig(); config.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true); Client client = ClientBuilder.newClient(config); ... 
+15
source share

Just note: if you are using the resteasy implementation of the JAX RS Client API , you can use build().invoke() :

 client.target("$baseUrl$restEndPoint/$entityId") .request("application/json") .build("DELETE", Entity.entity(entity, MediaType.APPLICATION_JSON)) .invoke() 

But this does not work with jersey

+5
source share

You can use webTarget.request().accept(MediaType.TEXT_PLAIN).method("DELETE",yourEntity) to call DELETE with the entity in it.

0
source share

All Articles