如何使用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。 如果没有,那么你将需要显式注册ResourceConfig
或Application
子类。
使用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服务。
你可以检查这个更多的信息。