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

问题描述 投票:3回答:1

我开发了一个在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,....)”。

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

java angularjs web-services rest glassfish
1个回答
4
投票

正如我猜测的那样,错误是非常误导的,与问题无关。浏览器使用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" );
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.