8

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

现在一切正常,使用 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 调用,一切正常。

谢谢你的帮助马克

4

3 回答 3

11

我也遇到过这个问题,问题是角度总是在 DELETE 请求上将 Content-Type 标头设置为 xml,并且当您指定您的 api 使用/生成带有注释的 JSON 时,球衣会抛出一个错误。

因此,要修复它(从客户端),请设置内容类型标头,例如:

.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);
}
于 2013-07-04T13:29:32.823 回答
0

使用 angularjs $resource(而不是 $http),请求中没有“payload”,内容类型设置为 text/plain。

所以恕我直言,最好是服务器端支持。“ Postel 定律指出,你应该在接受的内容上保持自由,在发送的内容上保持保守。——来源

@DELETE 
@Path("{id}")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN })
public void remove(@PathParam("id") Long id) { ...
于 2013-10-28T09:46:28.180 回答
0

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

@DELETE
@Path("{id}")
public final Course remove(@PathParam("id") final String id) {
  System.out.println("DELETE ID = " + id);
  return new Course();
}
于 2013-07-02T18:02:52.560 回答