无法为JAX-B生成架构,仅在CORS调用REST服务期间发生

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法为JAX-B生成架构,仅在CORS调用REST服务期间发生相关的知识,希望对你有一定的参考价值。

我开发了一个在Glassfish 4中运行的REST服务/资源,并且还在AngularJS中开发了一个UI。当我通过WAR文件(以及REST代码)将UI代码部署到Glassfish并通过访问Glassfish应用程序(http://localhost:8080)的浏览器直接测试访问时,一切都按预期工作。

但是,奇怪的是,当我将UI代码分别部署到Tomcat服务器(在端口8090上运行)时,其中一个GET请求(返回一个带有Map keyValues = new HashMap()类型的实体的Response; 。甚至没有访问我的任何实体类)我在Glassfish服务器日志中收到以下错误:

严重:无法为JAX-B元素生成模式com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:IllegalAnnotationExceptions属性的2个计数“salesOrderUid”具有XmlID注释,但其类型不是String。此问题与以下位置有关:at public int business.salesOrderMgmt.entity.SalesOrder.getSalesOrderUid()at business.salesOrderMgmt.entity.SalesOrder at private business.salesOrderMgmt.entity.SalesOrder business.salesOrderMgmt.entity.SalesOrderLine.salesOrder at私有java.util.List中的business.salesOrderMgmt.entity.SalesOrderLine业务中的私有java.util.List business.salesOrderMgmt.entity.Item.catalogItems中的business.salesOrderMgmt.entity.CatalogItem上的business.salesOrderMgmt.entity.CatalogItem.salesOrderLine中的business.salesOrderMgmt.entity.CatalogItem.salesOrderLine。 salesOrderMgmt.entity.Item at private business.salesOrderMgmt.entity.Item business.salesOrderMgmt.entity.ProductCategoryItem.item at business.salesOrderMgmt.entity.ProductCategoryItem Class有两个同名的属性“salesOrderUid”这个问题与以下位置有关:at private int business.salesOrderMgmt.entity.SalesOrder.getSalesOrderUid()at business.salesOrderMgmt.entity.SalesOrder at private business.salesOrderMgmt.enti私有java.util中business.salesOrderMgmt.entity.CatalogItem的私有java.util.List business.salesOrderMgmt.entity.CatalogItem.salesOrderLines中的business.salesOrderMgmt.entity.SalesOrderLine中的ty.SalesOrder business.salesOrderMgmt.entity.SalesOrderLine.salesOrder。列表business.salesOrderMgmt.entity.Item.catalogItems在business.salesOrderMgmt.entity.Item at private business.salesOrderMgmt.entity.Item business.salesOrderMgmt.entity.ProductCategoryItem.item at business.salesOrderMgmt.entity.ProductCategoryItem此问题与以下位置:at private int business.salesOrderMgmt.entity.SalesOrder.salesOrderUid at business.salesOrderMgmt.entity.SalesOrder business.salesOrderMgmt.entity.SalesOrderLine.salesOrder at business.salesOrderMgmt.entity.SalesOrderLine at at business.salesOrderMgmt.entity.SalesOrder at business.salesOrderMgmt.entity.SalesOrder私有java.util中的business.salesOrderMgmt.entity.CatalogItem上的private java.util.List business.salesOrderMgmt.entity.CatalogItem.salesOrderLines。列表business.salesOrderMgmt.entity.Item.catalogItems位于business.salesOrderMgmt.entity.Item位于business.salesOrderMgmt.entity.Item business.salesOrderMgmt.entity.ProductCategoryItem.item位于business.salesOrderMgmt.entity.ProductCategoryItem

在Chrome控制台中,我收到以下错误(我认为这是误导性的,因为我在服务器端设置了“Access-Control-Allow-Origin”标头,然后将响应对象返回给客户端/请求者。

请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,'http://localhost:8090'原产地不允许进入。

我认为Chrome /客户端错误是误导性的,因为在服务器端我为每个响应添加了一个标头(“Access-Control-Allow-Origin”,“http://localhost:8090”)...适用于其他请求,所以为什么不能它对这个有用吗?

对我来说最奇怪的是REST资源方法没有访问据称具有无效id类型的实体类。它使用传递给它的参数来调用服务来计算税金和运费,这些参数代表promotionCode,zipCode和subTotal - 不访问SalesOrder实体对象。

此特定REST调用与其他正在运行的调用之间存在两个差异:1)此特定调用将参数与请求一起传递,而其他调用则不传递,2)此请求过滤器检测HTTP方法(OPTIONS)。

请注意,除了我的所有REST资源方法之外,我还包括以下方法参数“resourceMethod(@QueryParam(”callback“)String callback,....)”。

可能导致这些神秘错误的任何想法?

答案

正如我猜测的那样,错误是非常误导的,与问题无关。浏览器使用OPTIONS请求“抢占”GET请求,该请求未向浏览器返回预期信息以指示浏览器/客户端应用程序可能继续。

我必须做两件事:1)在请求过滤器中捕获OPTIONS方法并在响应上设置头,以及2)在响应过滤器集头中允许CORS以及方法和其他头...代码片段如下:

@Provider
@PreMatching
public class RESTRequestFilter implements ContainerRequestFilter {

    private final static Logger log = Logger.getLogger( RESTRequestFilter.class.getName() );

    @Override
    public void filter( ContainerRequestContext requestCtx ) throws IOException {
        log.info( "Executing REST request filter" );
          requestCtx.getHeaders().add( "Access-Control-Allow-Credentials", "true" );
          requestCtx.getHeaders().add( "Access-Control-Allow-Origin", "http://localhost:8090");
          requestCtx.getHeaders().add( "Access-Control-Allow-Methods", "OPTIONS, GET, POST, DELETE, PUT" );
          requestCtx.getHeaders().add( "Access-Control-Allow-Headers", "Content-Type" );

        // When HttpMethod comes as OPTIONS, just acknowledge that it accepts...
        if ( requestCtx.getRequest().getMethod().equals( "OPTIONS" ) ) {
           log.info( "HTTP Method (OPTIONS) - Detected!" );

            // Just send a OK signal back to the browser (Abort the filter chain with a response.)
           Response response = Response.status( Response.Status.OK )
                   .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
                   .header("Access-Control-Allow-Origin", "http://localhost:8090")
                   .header("Access-Control-Allow-Headers", "Content-Type, accept, headers")
                   .build();           
           requestCtx.abortWith( response );

        }

    }

}

@Provider
@PreMatching
public class RESTResponseFilter implements ContainerResponseFilter {

    private final static Logger log = Logger.getLogger( RESTResponseFilter.class.getName() );

    @Override
    public void filter( ContainerRequestContext requestCtx, ContainerResponseContext responseCtx ) throws IOException {
        log.info( "Executing REST response filter" );

        // The following was required to permit testing outside the Application Server Container
//        responseCtx.getHeaders().add( "Access-Control-Allow-Origin", "http://127.0.0.1:53307" );
        responseCtx.getHeaders().add( "Access-Control-Allow-Origin", "http://localhost:8090");
        responseCtx.getHeaders().add( "Access-Control-Allow-Credentials", "true" );
        responseCtx.getHeaders().add( "Access-Control-Allow-Methods", "OPTIONS, GET, POST, DELETE, PUT" );
        responseCtx.getHeaders().add( "Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Authorization, X-Requested-With" );
    }
}

以上是关于无法为JAX-B生成架构,仅在CORS调用REST服务期间发生的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Spring Boot Data Rest 中启用 CORS

Spring CORS 仅在某些资源上失败

AWS Api Gateway 仅在 OPTIONS 调用时不响应 CORS 标头

如何将 CORS 预检缓存应用于整个域

启用 Cors 服务的 ionic post in rest 服务错误

调用 REST API、JavaScript 时的 CORS 策略 [重复]