2

I am using Jersey Framework (JAX-RS implementation) for building RESTful Web Services.

I'm not able to use the @DELETE REST method, since its throwing an exception when I try to invoke it.The following @DELETE method is used to delete an Employee:

@Path("/employees")
public class EmpResource {

@DELETE
@Consumes(MediaType.APPLICATION_JSON)
public Response deleteEmployee(JAXBElement<String> r) throws ClassNotFoundException, SQLException {

    String name = r.getValue();
    String response = DAOaccess.deleteEmp(name);
    return Response.noContent().build();    

}

And I'm using the following block of code to invoke the service:

Client client = Client.create();
WebResource webResource = client.resource("http://localhost:8080/RestApp/sample/employees");
String input = "{\"name\":\"John\"}";
ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).delete(ClientResponse.class,input);

When I run my client, it throws the following exception:

Exception in thread "main" com.sun.jersey.api.client.ClientHandlerException: java.net.ProtocolException: HTTP method DELETE doesn't support output
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:151)
at com.sun.jersey.api.client.Client.handle(Client.java:648)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:680)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.delete(WebResource.java:599)

It would be great if someone could guide me on how to resolve it?

Chillax
  • 4,418
  • 21
  • 56
  • 91

10 Answers10

12

It's a java's bug in the implementation of the HTTPUrlConnection class:

http://bugs.sun.com/view_bug.do?bug_id=7157360

It should be solved in java 8.....

Meanwhile, in the real word, to send a json to a REST service you must send path parameter(s) like @Micer says or make your own HttpUrlConnection setting the requestmethod to POST and overriding it with the "X-HTTP_method-Override" to say that you want a DELETE doing something like this:

  public static void remove(String dflowname) throws IOException, ParseException {
    String jsonResponse = "";

    URL url = new URL(deleteuri);
    HttpURLConnection connection = null;
    connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("POST");
    // We have to override the post method so we can send data
    connection.setRequestProperty("X-HTTP-Method-Override", "DELETE");
    connection.setDoOutput(true);

    // Send request
    OutputStreamWriter wr = new OutputStreamWriter(
      connection.getOutputStream());
    wr.write(dflowname);
    wr.flush();

    // Get Response
    BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    String line;
    while ((line = rd.readLine()) != null) {
      jsonResponse = jsonResponse.concat(line);
    }
    wr.close();
    rd.close();

    JSONParser parser = new JSONParser();
    JSONObject obj = (JSONObject) parser.parse(jsonResponse);
    System.out.println(obj.get("status").toString());
  }

source: https://groups.google.com/a/openflowhub.org/forum/#!msg/floodlight-dev/imm_8drWOwU/Uu4h_u3H6HcJ

inigoD
  • 1,681
  • 14
  • 26
4

For me it helped to remove input parameter from delete() method on client

ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).delete(ClientResponse.class);

and send it over @pathParam instead:

public String delete(@PathParam("input") String input){...}
Micer
  • 8,731
  • 3
  • 79
  • 73
  • Can you please explain little bit more? – Saurabh Gadariya May 07 '17 at 10:58
  • @Saurabh I removed input (`String input = "{\"name\":\"John\"}";`) parameter from `delete()` method and specified it as `@PathParam` in method declaration instead. Should be pretty straighforward. – Micer May 09 '17 at 14:49
2

Delete with a payload works fine in Jersey clients 2.x.x.

Client code example below.

    public CalculateResult unoverrideSubscription(String partyId, String serviceCode) {


    CalculateResult svc = r.path("/party-subscriptions").path(partyId)
            .path(serviceCode)
            .path("price")
            .request(MediaType.APPLICATION_JSON).delete(CalculateResult.class);

    return svc;// toGenericResponse(sr);
}
Matthew Payne
  • 2,996
  • 2
  • 19
  • 15
1

This seem to be because of a bug (https://bugs.openjdk.java.net/browse/JDK-7157360) in Java 1.7 implementation of HttpURLConnection class. I tried using JDK1.8 and it worked like a charm.

Kamal.J
  • 11
  • 2
1

Spent some time attempting to identify what will and won't currently work using WebLogic 12 & Sun / JRocket 1.6.

The error "ProtocolException: HTTP method DELETE doesn't support output" seems to be a bit misleading. This error is caused not by returning output from the RS but attempting to pass in an object to be processed on a delete request.

You can receive an object when passing in keys/identifiers via @QueryParams...

@DELETE
@Path("deleteThis")
public Response deleteThis(@QueryParam("objectId") String objectId)

using

    ClientResponse response = webResource.path("deleteThis").queryParam("objectId", "1").delete(ClientResponse.class);

or via @PathParams...

@DELETE
@Path("deleteThis/{objectId}")
public ReturnedObject deleteThis(@PathParam("objectId") int objectId)

using

    ReturnedObject myReturnedObject = webResource.path("deleteThis").path("1").delete(ReturnedObject.class);

This error is produced when you are passing in an object to be used as an argument

@DELETE
@Path("deleteThis")
public Response deleteRuleSettingTest(ArgumentObject myObject)

using

ArgumentObject myArgumentObject = ...
ClientResponse response = webResource.path("deleteThis").delete(ClientResponse.class, myArgumentObject);

Additionally. Reviewed the source code for the sun.net.www.protocol.http.HttpURLConnection class. This error is produced when the method is not PUT or POST but only when the protocol is 'http'. Enabled and pointed my client to a secure port on my container and the last example (the one that causes the exception) works successfully. Makes me wonder if this is actually a java bug as some have suggested.

Al Rosine
  • 31
  • 4
1

You have to create one filter for all types of requests

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
Yatender Singh
  • 3,098
  • 3
  • 22
  • 31
0

As the error says,

HTTP method DELETE doesn't support output

So you must change the signature of your method to

public Response deleteEmployee(...)

In the method don't return a String but for example

return Response.noContent().build();
0

The return type of @DELETE method should be void. You cannot return any thing. On success the reponse status will be can be 200 or 204

Community
  • 1
  • 1
basiljames
  • 4,777
  • 4
  • 24
  • 41
0

I usually use DELETE like void:

@DELETE
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Path("/")
public void deleteSomeBean(@QueryParam("id") String id) throws Exception

and in client:

webResource.path(SERVICE_PATH).queryParam("id", someBean.getId()).delete();gith

Like here: TemplateRestService

and here: TemplateServiceRestTest

Azee
  • 1,809
  • 17
  • 23
0

i did come across the same issue with Java 1.7.it works in JDK1.8