AngularJS和Jersey REST DELETE操作失败,状态代码为415

时间:2013-06-29 10:54:29

标签: javascript rest tomcat angularjs jersey

我有一个带有Jersey后端应用程序的AngularJS web应用程序。

现在一切正常,使用ngResource从AngularJS中访问REST资源。唯一的问题是使用DELETE选项。

我有以下代码使用我的ngResource删除课程:

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

在后端(泽西岛),我有以下代码:

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

如果我尝试删除项目,则从Angular调用以下URL:

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

这很好(在我之后)。如果我从CURL调用这个url,我会将后端的ssystem.out发布到控制台。

在客户端应用程序(AngularJS)中,我在浏览器控制台上收到以下异常:

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

任何人都知道问题可能是什么? POST + GET工作正常。

我有以下消费/产生注释:

@Consumes({ MediaType.APPLICATION_JSON })

@Produces({MediaType.APPLICATION_JSON})

提前感谢您的帮助。

电贺 马克


编辑:

我试图用$ http替换AngularJS中的REST服务访问方式。

现在我的服务如下:

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

}]);

结果仍然相同。应用程序调用例如

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

并收到

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

如果我在Curl上调用相同的DELETE调用,一切正常。

感谢您的帮助 马克

3 个答案:

答案 0 :(得分:11)

我也遇到过这个问题,问题是angular总是在DELETE请求上将Content-Type标头设置为xml,并且当你指定你的api使用注释消耗/生成JSON时,jersey会发现错误。

因此要修复它(从客户端),请设置content-type标头,例如:

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

但是,由于我不理解/不知道的原因,如果没有数据,angular会从请求中删除内容类型标头。如果不是因为浏览器(至少是chrome)将始终发送内容类型的事实,这将是有意义的......无论如何,你将不得不在角度源中找到这个的麻烦:

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

并摆脱它。我不知道如何在不编辑源代码的情况下执行此操作。也许有更好的JS知识的人,呃,知道如何。


或者,从服务器端,您可以像Rob建议的那样进行操作,并更改Jersey配置以允许使用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);
}

答案 1 :(得分:0)

我遇到了同样的问题,请尝试在删除方法中返回Course对象的新实例。

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

答案 2 :(得分:0)

使用angularjs $ resource(而不是$ http),在请求中没有“payload”时,content-type被设置为text / plain。

所以恕我直言,服务器端支持更好。 “Postel's Law声明你应该对自己所接受的内容持开放态度,并对所发送的内容采取保守态度。source

@DELETE 
@Path("{id}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN })
public void remove(@PathParam("id") Long id) { ...