我有一个带有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调用,一切正常。
感谢您的帮助 马克
答案 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) { ...