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
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
Share Improve this question edited Jun 29, 2013 at 15:12 mooonli asked Jun 29, 2013 at 10:54 mooonlimooonli 2,3935 gold badges23 silver badges32 bronze badges 03 Answers
Reset to default 11I 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);
}
I had same issue, Try returning new instance of Course object in your delete method.
@DELETE
@Path("{id}")
public final Course remove(@PathParam("id") final String id) {
System.out.println("DELETE ID = " + id);
return new Course();
}
Using angularjs $resource (instead of $http), without "payload" in the request, the content-type is setted as text/plain.
So IMHO it's better a server side support. "Postel's Law states that you should be liberal in what you accept and conservative in what you send. -- source"
@DELETE
@Path("{id}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN })
public void remove(@PathParam("id") Long id) { ...