【问题标题】:Jersey CORS working for GET but not POSTJersey CORS 为 GET 但不为 POST 工作
【发布时间】:2013-05-19 01:36:41
【问题描述】:

我的 Jersey CORS 请求不适用于 POST,但适用于 GET 请求。标头被映射到 Jersey 请求,如下面对同一资源的 GET 请求的屏幕截图所示。

但是,对以下方法进行 POST 会使我最终得到 XMLHttpRequest cannot load http://production.local/api/workstation. Origin http://workstation.local:81 is not allowed by Access-Control-Allow-Origin.

这是网络活动的屏幕截图:

有关失败的 POST 请求的详细信息:

这是我的资源:

@Path("/workstation")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public class WorkstationResource {

    @InjectParam
    WorkstationService workstationService;

    @POST
    public WorkstationEntity save (WorkstationEntity workstationEntity) {
        workstationService.save(workstationEntity);
        return workstationEntity;
    }

    @GET
    @Path("/getAllActive")
    public Collection<WorkflowEntity> getActive () {
        List<WorkflowEntity> workflowEntities = new ArrayList<WorkflowEntity>();
        for(Workflow workflow : Production.getWorkflowList()) {
            workflowEntities.add(workflow.getEntity());
        }
        return workflowEntities;
    }
}

我的 CORS 过滤器:

public class ResponseCorsFilter implements ContainerResponseFilter {

    @Override
    public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {

        Response.ResponseBuilder responseBuilder = Response.fromResponse(response.getResponse());
        responseBuilder
                .header("Access-Control-Allow-Origin", "*")
                .header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");

        String reqHead = request.getHeaderValue("Access-Control-Request-Headers");

        if(null != reqHead && !reqHead.equals(null)){
            responseBuilder.header("Access-Control-Allow-Headers", reqHead);
        }

        response.setResponse(responseBuilder.build());

        return response;
    }
}

我在 Main 类中的 Jersey 配置:

//add jersey servlet support
ServletRegistration jerseyServletRegistration = ctx.addServlet("JerseyServlet", new SpringServlet());
jerseyServletRegistration.setInitParameter("com.sun.jersey.config.property.packages", "com.production.resource");
jerseyServletRegistration.setInitParameter("com.sun.jersey.spi.container.ContainerResponseFilters", "com.production.resource.ResponseCorsFilter");
jerseyServletRegistration.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", Boolean.TRUE.toString());
jerseyServletRegistration.setInitParameter("com.sun.jersey.config.feature.DisableWADL", Boolean.TRUE.toString());
jerseyServletRegistration.setLoadOnStartup(1);
jerseyServletRegistration.addMapping("/api/*");

【问题讨论】:

  • @SotiriosDelimanolis - 是的,我允许跨域。这不应该让它正常工作吗?
  • 对环境了解不够,只是指出想到的事情。也许你错过了什么。
  • 您显示的第一个请求是 OPTIONS 请求还是 POST/GET?另外,你用的是什么浏览器?
  • 此外,您应该更改过滤器以附加您想要接受的其他标题,而​​不是有两个 Access-Control-Allow-Headers 行。这可能会导致问题。
  • 您确定这不是 JSON 映射问题吗?我发现我有时对很少登录 POJO 映射函数感到非常神秘。尝试添加一个没有对象参数的 post 方法并测试一个帖子。

标签: java jersey


【解决方案1】:

很难判断也很难调试,因为是 浏览器 在检查响应(标头)时产生了该错误。

即使经过非常仔细的检查,您的代码看起来也很正常,除了Access-Control-Allow-Headersfilter() 中设置了两次或可能设置了两次。虽然RFC 2616 (HTTP 1.1) Section 4.2 基本上允许它满足某些条件,但我不会在这里赌博。您无法控制浏览器 X 版本 N 的处理方式。

与其使用不同的值两次设置相同的标头,不如将第二组值附加到现有标头。

【讨论】:

  • 我已经进行了更改,不幸的是它没有解决问题
  • 如果你能看到我摸不着头脑....所有主要浏览器的行为是否一致?您可以在其中一个中启用调试日志记录的任何机会,例如Chrome?
  • 我以前从未使用过 Chrome 的调试日志。我会调查的。 Chrome 是我唯一支持的浏览器 - 它是公司内部使用的应用程序。
  • 不过,请用 FF 和 IE 进行测试,看看它们是否表现出相同的行为 - 了解这一点很重要。
【解决方案2】:

虽然我认为这是一个 CORS 问题,但事实证明这是一个泽西岛问题......

第 256 行的org.glassfish.grizzly.servlet.ServletHandler 处理异常...

    FilterChainInvoker filterChain = getFilterChain(request);
    if (filterChain != null) {
        filterChain.invokeFilterChain(servletRequest, servletResponse);
    } else {
        servletInstance.service(servletRequest, servletResponse);
    }
} catch (Throwable ex) {
    LOGGER.log(Level.SEVERE, "service exception:", ex);
    customizeErrorPage(response, "Internal Error", 500);
}

在我的日志中,我看到的只是service exception:,后面什么都没有。当我调试这条线时,我最终看到了错误javax.servlet.ServletException: org.codehaus.jackson.map.JsonMappingException: Conflicting setter definitions for property "workflowProcess": com.production.model.entity.WorkstationEntity#setWorkflowProcess(1 params) vs com.production.model.entity.WorkstationEntity#setWorkflowProcess(1 params),它给了我一些我可以实际使用的东西。

【讨论】:

    猜你喜欢
    • 2018-02-06
    • 2014-06-23
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 2013-06-07
    • 2021-07-04
    • 2020-08-23
    • 1970-01-01
    相关资源
    最近更新 更多