Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 启用从AngularJS到Jersey的CORS Post请求_Java_Angularjs_Rest_Jersey_Cors - Fatal编程技术网

Java 启用从AngularJS到Jersey的CORS Post请求

Java 启用从AngularJS到Jersey的CORS Post请求,java,angularjs,rest,jersey,cors,Java,Angularjs,Rest,Jersey,Cors,我正在尝试将一个JSON文档从AngularJS应用程序发布到Jersey REST服务。请求失败,通知我: XMLHttpRequest无法加载http://localhost:8080/my.rest.service/api/order/addOrder. 请求的资源上不存在“Access Control Allow Origin”标头。起源'http://localhost因此,不允许访问。 泽西岛休息室功能 我已在响应上启用(我认为是)适当的标题:Access Control Allow

我正在尝试将一个JSON文档从AngularJS应用程序发布到Jersey REST服务。请求失败,通知我:

XMLHttpRequest无法加载http://localhost:8080/my.rest.service/api/order/addOrder. 请求的资源上不存在“Access Control Allow Origin”标头。起源'http://localhost因此,不允许访问。

泽西岛休息室功能 我已在响应上启用(我认为是)适当的标题:
Access Control Allow Origin
Access Control Allow Methods
,如下面的方法所示:

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/addOrder")
public Response addOrder(DBObject dbobject) {
    DB db = mongo.getDB("staffing");
    DBCollection col = db.getCollection("orders");
    col.insert(dbobject);
    ObjectId id = (ObjectId)dbobject.get("_id");
    return Response.ok()
            .entity(id)
            .header("Access-Control-Allow-Origin","*")
            .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
            .allow("OPTIONS")
            .build();
}
角度控制器 我已经声明了该应用程序,并使用类似堆栈溢出问题中建议的所有设置配置了$httpProvider:

var staffingApp = angular.module('myApp', ['ngRoute', 'ui.bootstrap']);
myApp.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.defaults.useXDomain = true;
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
    $httpProvider.defaults.headers.common["Accept"] = "application/json";
    $httpProvider.defaults.headers.common["Content-Type"] = "application/json";
 }]);
我还创建了此控制器以打开模态并处理表单:

    var modalCtrl = function($scope, $modal, $log, $http, $location) {          
    $scope.order = {
        activityTitle : null,
        anticipatedAwardDate : null,
        component : null,
        activityGroup : null,
        activityCategory : null,
        activityDescription : null
    };
    $scope.open = function () {
        var modalInstance = $modal.open({
            templateUrl: 'addOrder.html',
            windowClass: 'modal',
            controller: modalInstanceCtrl,
            resolve: {
                order : function () {
                    return $scope.order;
                    }
                }
            });
        modalInstance.result.then(function (oid) {
            $log.info("Form Submitted, headed to page...");
            $location.path("/orders/" + oid);
        }, function() { 
            $log.info("Form Cancelled")
        });
    };
};

var modalInstanceCtrl = function ($scope, $modalInstance, $log, $http, order) {
    $scope.order = order,
    $scope.ok = function () {
        $log.log('Submitting user info');
        $log.log(order);
        $log.log('And now in JSON....');
        $log.log(JSON.stringify(order));
        $http.post('http://localhost:8080/my.rest.service/api/order/addOrder', JSON.stringify(order)).success(function(data){
            $log.log("here's the data:\n");
            $log.log(data);
            $modalInstance.close(data._id.$oid)
        });
    };
    $scope.cancel = function () {
        $modalInstance.dismiss('cancel');
    };      
};
myApp.controller('modalCtrl', modalCtrl);
没有用,我试过:

  • 从响应标题中删除
    .allow(“选项”)
  • 从应用程序中删除$httpProvider配置
  • 将$httpProvider配置更改为调用myApp.config(函数($httpProvider){…}),传递函数本身而不是数组
Get请求使用相同的配置:

@GET
@Path("/listall/")
@Produces(MediaType.APPLICATION_JSON)
public Response listAll(){
    DB db = mongo.getDB("staffing");
    DBCollection col = db.getCollection("orders");
    List<DBObject> res = col.find().limit(200).toArray();
    return Response.ok()
            .entity(res.toString())
            .header("Access-Control-Allow-Origin","*")
            .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
            .allow("OPTIONS")
            .build();       
}
@GET
@路径(“/listall/”)
@产生(MediaType.APPLICATION_JSON)
公众回应列表(只提供英文版本){
DB=mongo.getDB(“人员配置”);
DBCollection col=db.getCollection(“订单”);
List res=col.find().limit(200).toArray();
返回Response.ok()
.entity(res.toString())
.header(“访问控制允许原点”、“*”)
.header(“访问控制允许方法”、“获取、发布、删除、放置”)
.允许(“选项”)
.build();
}
使用此工作正常的控制器:

myApp.controller('orderListCtrl', function ($scope, $http){
    $http.get('http://localhost:8080/my.rest.service/api/order/listall').success(function(data) {
        for (var i = 0; i < data.length; i++) {
            if (data[i].description.length > 200) {
                data[i].shortDesc = data[i].description.substring(0,196) + "...";
            } else {
                data[i].shortDesc = data[i].description;
            }
        };
        $scope.orders = data;
    });
});
myApp.controller('orderListCtrl',函数($scope,$http){
$http.get('http://localhost:8080/my.rest.service/api/order/listall)。成功(函数(数据){
对于(变量i=0;i200){
数据[i].shortDesc=data[i].description.substring(0196)+“…”;
}否则{
数据[i]。shortDesc=数据[i]。说明;
}
};
$scope.orders=数据;
});
});
更新#1: 我在同一个源上尝试了相同的请求,基本上是为Angular应用程序和locahost:8080的REST服务提供服务。这个配置是有效的,但需要对我的代码进行一些轻微的更改和一般性的清理,我在上面编辑了这些代码

Post仍然作为CORS请求失败,但是我仍然在寻找这个配置中缺少的部分

更新#2: 我已经调查了工作请求发送到浏览器时的标题,并将其与非工作请求进行了比较

工作get请求返回以下标头及其响应:

非工作post请求返回带有响应的标头,但缺少Access Control Allow Origin标头:

我相信这现在已经成为一个问题,在将响应返回给客户端之前,将从响应中剥离标题,这将导致浏览器请求失败

更新#3: 从Chrome的REST控制台扩展向同一URL提交测试POST请求将返回相应的响应头,如下面的屏幕帽所示。


此时,我无法确定是什么在删除Jersey和angularjs客户端之间的头文件,但我确信这是罪魁祸首。

在从angularjs调用我的Restful服务(用java-Jersey实现)时,我遇到了类似的CORS错误。为了解决这个问题,我在响应头中添加了访问控制允许原点:。我补充如下:

response.addHeader("Access-Control-Allow-Origin", "*"); 
有关更多信息,请查看-

CORS错误通常发生在angularjs代码(web项目)和webserivce代码(服务器端项目)位于不同的IP和端口号时

您的webservice实现看起来是正确的。所以,为了检查,请尝试在同一端口的本地主机上运行它们(例如8080)。如果所有代码都正确,它应该在那里工作

要单独运行它们,请尝试在webservice实现中添加访问控制允许源:,如上所示


希望这能有所帮助。

问题在于,在POST请求之前,在飞行前发送的OPTIONS请求处理不充分,并且带有正确的跨原点标头

我可以通过下载并实现在以下页面找到的CORS筛选器来解决此问题:


如果您遇到类似问题,请按照说明进行操作并进行测试,以确保您的选项请求不再失败,并且紧接着是成功的请求。

最好的方法是添加Jersey响应筛选器,该筛选器将为所有方法添加CORS头。您不必更改您的webservices实现

我会为Jersey 2.x做解释

1) 首先添加一个ResponseFilter,如下所示

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;

public class CorsResponseFilter implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext requestContext,   ContainerResponseContext responseContext)
    throws IOException {
        responseContext.getHeaders().add("Access-Control-Allow-Origin","*");
        responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");

  }
}
2) 然后在web.xml中,在jersey servlet声明中添加以下内容

    <init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
        <param-value>YOUR PACKAGE.CorsResponseFilter</param-value>
    </init-param>

jersey.config.server.provider.classnames
您的PACKAGE.CorsResponseFilter

实际上,您还有其他不需要过滤器的解决方案。将
Access Control Allow-*
标题添加到
GET
请求中是不够的,您必须创建一个
OPTIONS
端点以允许浏览器执行飞行前请求,即:

@OPTIONS
public Response corsMyResource(@HeaderParam("Access-Control-Request-Headers") String requestH) {
    ResponseBuilder rb = Response.ok();

    return buildResponse(rb, requestH);
}

请参阅以供参考。

您认为上面代码中的响应对象是什么?这在功能上与在响应生成器中包含相同的响应头不同吗?当我在rest webservice响应中只添加了“访问控制允许源代码”、“*”时,这对我来说是有效的。我看你已经设置好了响应。请尝试在相同的IP和端口号上运行您的代码,以便确保代码中没有问题。