Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS and Jersey REST DELETE operation fails with 415 Status code

I have a AngularJS webapplication with a Jersey Backend Application.

Now everything is working fine using ngResource to access REST resource out of AngularJS. The only problem is with the DELETE option.

I have the following code to delete a course using my ngResource:

    Course.deleteCourse = function(course) {
    course.$remove({
        courseId:course.id
    });
    return course;
};

In the backend (Jersey) I have the following code:

    @DELETE
@Path("{id}")
public final void remove(@PathParam("id") final String id) {
    System.out.println("DELETE ID = " + id);
}

If I try to delete an item the following url is called from Angular:

DELETE http://localhost:8080/manager-api/courses/5

This is fine (after me). If I call this url from CURL, i get the ssystem.out from the Backend posted to the console.

In the client-app (AngularJS) i get the following exception on the browser console:

DELETE http://localhost:8080/manager-api/courses/5 415 (Unsupported Media Type) 

Anyone an idea what the problem might be? POST + GET are working fine.

I have the following consume/produce annotations:

@Consumes({ MediaType.APPLICATION_JSON })

@Produces({ MediaType.APPLICATION_JSON })

Thanks in advance for your help.

Greets Marc


EDIT:

I have tried to replace the way of accessing the REST services out of AngularJS with $http.

Now my service looks as below:

MyApp.factory("Course", ["$http", function ($http) {
var courseBaseUrl = "/api/courses/";

return {
    show: function show(courseId) {
        return $http.get(courseBaseUrl + courseId);
    },
    list: function list() {
        return $http.get(courseBaseUrl, {});
    },
    remove: function remove(courseId) {
        return $http.delete(courseBaseUrl + courseId, {});
    },
    save: function save(course) {
        return $http.post(courseBaseUrl, course, {});
    }
};

}]);

The result is still the same. The application calls e.g

DELETE http://localhost:8080/manager-api/courses/1

and receives a

DELETE http://localhost:8080/manager-api/courses/1 415 (Unsupported Media Type) 

If I call the same DELETE call on Curl, everything works fine.

Thanks for your help Marc

like image 540
mooonli Avatar asked Jun 29 '13 10:06

mooonli


People also ask

How to delete an object in angular web services?

We can perform the delete operation using angular http delete method () . http delete method () URL using HTTP delete method. This is the rest web service used to update any article or information. This is of any type of object that will be passed to the rest web service server.

Is it possible to implement REST services using AngularJS?

Very good example to learn and implement Rest services using AngularJS. Thank you Ravi. The Download link is available but you might have to wait until the page completely loads for it to show up.

What is the use of HTTP delete method in angular?

The delete method defines the imported which means that sending that some HTTP delete request multiple times will have the same effect on the server and will not additionally affect the state. We can perform the delete operation using angular http delete method () . http delete method () URL using HTTP delete method.

How to make HTTP request from an angular app?

Before making HTTP requests from your Angular app you need to do a couple of things. 1. Add the HttpClientModule to the imports array of your AppModule like below on lines 3 and 10. 2. Import the HttpClient into your component and add it to the constructor () params like below on lines 2 and 8.


Video Answer


1 Answers

I came across this as well, the problem is angular always sets the Content-Type header to xml on DELETE requests and jersey will chuck an error as you have specified that your api consumes/produces JSON with the annotations.

So to fix it (from the client side), set the content-type header, eg:

.config(function($httpProvider) {
  /**
   * make delete type json
   */
  $httpProvider.defaults.headers["delete"] = {
    'Content-Type': 'application/json;charset=utf-8'
  };
})

However, for reasons I dont understand/dont know of, angular will strip away the content-type header from the request if it has no data. This would make sense if it wasn't for the fact that browsers (chrome at least) will always send a content-type... Anyway you will have to go to the trouble of finding this in the angular source:

  // strip content-type if data is undefined
  if (isUndefined(config.data)) {
    delete reqHeaders['Content-Type'];
  }

and get rid of it. I dont know of a way to do this without editing the source. Maybe someone with better JS know-how, erm, knows how.


Alternatively, from the server side, you can do as Rob has suggested and change the Jersey configuration to allow consuming MediaType.APPLICATION_XML

@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public final void remove(@PathParam("id") final String id) {
    System.out.println("DELETE ID = " + id);
}
like image 93
paullth Avatar answered Oct 14 '22 23:10

paullth