如何使用JAX-RS和Jersey处理CORS

我正在开发一个Java脚本客户端应用程序,在服务器端,我需要处理CORS,我用JERSEY写在JAX-RS上的所有服务。 我的代码:

@CrossOriginResourceSharing(allowAllOrigins = true) @GET @Path("/readOthersCalendar") @Produces("application/json") public Response readOthersCalendar(String dataJson) throws Exception { //my code. Edited by gimbal2 to fix formatting return Response.status(status).entity(jsonResponse).header("Access-Control-Allow-Origin", "*").build(); } 

截至目前,我收到错误没有“访问控制允许来源”标题出现在请求的资源。 原因' http:// localhost:8080 '因此不被允许访问。“

请帮助我。

感谢和问候佛Puneeth

我不知道泽西岛有任何标准的CORS支持。 @CrossOriginResourceSharing ,据我所知,是一个CXF注释。 所以我不太确定你如何在Jersey中使用这个注释。

有了Jersey,为了处理CORS,我通常只使用一个ContainerResponseFilter 。 泽西岛1和2的ContainerResponseFilter有一点不同。 既然你没有提到你正在使用哪个版本,我会发布两个。

泽西岛2

 import java.io.IOException; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; @Provider public class CORSFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException { response.getHeaders().add("Access-Control-Allow-Origin", "*"); response.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); response.getHeaders().add("Access-Control-Allow-Credentials", "true"); response.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); } } 

如果您使用软件包扫描来发现提供程序和资源,那么@Provider注释应该为您处理configuration。 如果没有,那么你将需要显式注册ResourceConfigApplication子类。

使用ResourceConfig显式注册filter的示例代码:

 final ResourceConfig resourceConfig = new ResourceConfig(); resourceConfig.register(new CORSFilter()); final final URI uri = ...; final HttpServer httpServer = GrizzlyHttpServerFactory.createHttpServer(uri, resourceConfig); 

泽西岛1

 import com.sun.jersey.spi.container.ContainerRequest; import com.sun.jersey.spi.container.ContainerResponse; import com.sun.jersey.spi.container.ContainerResponseFilter; public class CORSFilter implements ContainerResponseFilter { @Override public ContainerResponse filter(ContainerRequest request, ContainerResponse response) { response.getHttpHeaders().add("Access-Control-Allow-Origin", "*"); response.getHttpHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true"); response.getHttpHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); return response; } } 

web.xmlconfiguration,可以使用

 <init-param> <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name> <param-value>com.yourpackage.CORSFilter</param-value> </init-param> 

或者你可以做ResourceConfig

 resourceConfig.getContainerResponseFilters().add(new CORSFilter()); 

或者使用@Provider注解进行包扫描。


编辑

请注意,上面的例子可以改进。 您需要了解CORS的工作原理。 请看这里 。 首先,你会得到所有答案的标题。 这可能并不理想。 您可能只需要处理预检(或OPTIONS)。 如果你想看到一个更好的CORSfilter,你可以看看RESTeasy CorsFilter的源代码

另一个答案可能是严格正确的,但误导。 缺less的部分是,你可以混合不同来源的filter。 即使认为泽西可能不提供CORSfilter(不是我检查的事实,但我相信其他答案),你可以使用tomcat自己的CORSfilter 。

我用泽西岛成功地使用了它。 我有我自己的基本authenticationfilter的实现,例如,与CORS一起。 最重要的是,CORSfilter是在Web XML中configuration的,而不是在代码中。

peeskillet的答案是正确的。 但是,当刷新网页(它只能在第一次加载时)出现这个错误:

 The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed. Origin 'http://127.0.0.1:8080' is therefore not allowed access. 

所以,而不是使用add方法来添加标题为响应,我使用put方法。 这是我的class

 public class MCORSFilter implements ContainerResponseFilter { public static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin"; public static final String ACCESS_CONTROL_ALLOW_ORIGIN_VALUE = "*"; private static final String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials"; private static final String ACCESS_CONTROL_ALLOW_CREDENTIALS_VALUE = "true"; public static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers"; public static final String ACCESS_CONTROL_ALLOW_HEADERS_VALUE = "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With, Accept"; public static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods"; public static final String ACCESS_CONTROL_ALLOW_METHODS_VALUE = "GET, POST, PUT, DELETE, OPTIONS, HEAD"; public static final String[] ALL_HEADERs = { ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS }; public static final String[] ALL_HEADER_VALUEs = { ACCESS_CONTROL_ALLOW_ORIGIN_VALUE, ACCESS_CONTROL_ALLOW_CREDENTIALS_VALUE, ACCESS_CONTROL_ALLOW_HEADERS_VALUE, ACCESS_CONTROL_ALLOW_METHODS_VALUE }; @Override public ContainerResponse filter(ContainerRequest request, ContainerResponse response) { for (int i = 0; i < ALL_HEADERs.length; i++) { ArrayList<Object> value = new ArrayList<>(); value.add(ALL_HEADER_VALUEs[i]); response.getHttpHeaders().put(ALL_HEADERs[i], value); //using put method } return response; } } 

并将此类添加到web.xml中的init-param

 <init-param> <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name> <param-value>com.yourpackage.MCORSFilter</param-value> </init-param> 

为了解决这个问题,我用了Micheal的回答,

  <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <executions> <execution> <id>run-embedded</id> <goals> <goal>run</goal> </goals> <phase>pre-integration-test</phase> <configuration> <port>${maven.tomcat.port}</port> <useSeparateTomcatClassLoader>true</useSeparateTomcatClassLoader> <contextFile>${project.basedir}/tomcat/context.xml</contextFile> <!--enable CORS for development purposes only. The web.xml file specified is a copy of the auto generated web.xml with the additional CORS filter added --> <tomcatWebXml>${maven.tomcat.web-xml.file}</tomcatWebXml> </configuration> </execution> </executions> </plugin> 

CORSfilter是tomcat站点的基本示例filter。

编辑
maven.tomcat.web-xml.filevariables是项目的pom定义的属性,它包含web.xml文件的path(位于我的项目中)

使用JAX-RS,您可以简单地将注释@CrossOrigin(origin = yourURL)到您的资源控制器。 在你的情况是@CrossOrigin(origin = "http://localhost:8080")但你也可以使用@CrossOrigin(origin = "*")来允许任何请求通过你的web服务。
你可以检查这个更多的信息。