最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AngularJS and Jersey REST DELETE operation fails with 415 Status code - Stack Overflow

programmeradmin3浏览0评论

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 0
Add a ment  | 

3 Answers 3

Reset to default 11

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);
}

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) { ...
发布评论

评论列表(0)

  1. 暂无评论