如何在JAX-RS Web服务上启用跨域请求?

Nai*_*ili 67 jax-rs cross-domain cors java-ee-7 wildfly-8

我开发了一组宁静的Web服务.由于错误,我无法从远程客户端调用任何这些方法 No 'Access-Control-Allow-Origin' header is present on the requested resource.

这些服务在localhost上完美运行.是否有任何更改或配置要在服务器端解决此问题.即启用跨域请求.

我正在使用WildFly 8,JavaEE 7

Joe*_*son 106

我想知道同样的事情,所以经过一些研究后我发现最简单的方法就是使用JAX-RS ContainerResponseFilter添加相关的CORS头.这样您就不需要用CXF替换整个​​Web服务堆栈(Wildfly使用CXF是某种形式,但它看起来并不像JAX-RS那样只使用JAX-WS).

无论您使用此过滤器,它都会将标头添加到每个REST Web服务.

package com.yourdomain.package;

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Provider
public class CORSFilter implements ContainerResponseFilter {

   @Override
   public void filter(final ContainerRequestContext requestContext,
                      final ContainerResponseContext cres) throws IOException {
      cres.getHeaders().add("Access-Control-Allow-Origin", "*");
      cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
      cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
      cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
      cres.getHeaders().add("Access-Control-Max-Age", "1209600");
   }

}
Run Code Online (Sandbox Code Playgroud)

然后当我用curl测试时,响应有CORS头:

$ curl -D - "http://localhost:8080/rest/test"
HTTP/1.1 200 OK
X-Powered-By: Undertow 1
Access-Control-Allow-Headers: origin, content-type, accept, authorization
Server: Wildfly 8
Date: Tue, 13 May 2014 12:30:00 GMT
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Transfer-Encoding: chunked
Content-Type: application/json
Access-Control-Max-Age: 1209600
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD
Run Code Online (Sandbox Code Playgroud)

我的理解是,它是@Provider注释,告诉JAX-RS运行时使用过滤器,没有注释没有任何反应.

我的想法有关使用ContainerResponseFilter新泽西州例子.

  • 是的我使用了你在这里发布的相同解决方案.但我相信我们通过允许每个跨域连接来解决安全问题. (8认同)
  • `Access-Control-Allow-Credentials:true`这一行实际上与`"Access-Control-Allow-Origin","*"`冲突,因为它可能是安全问题,或者(至少在Chrome中)只是否认.如果要允许凭据,则需要指定特定的源,而不是通配符. (2认同)

nem*_*ixx 17

我遇到了类似的问题,并尝试使用@Alex Petty的解决方案,但除了必须在我的类中的每个JAX-RS端点上设置CORS头之外,如下:

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getMemberList() {
    List<Member> memberList = memberDao.listMembers();
    members.addAll(memberList);
    return Response
            .status(200)
            .header("Access-Control-Allow-Origin", "*")
            .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
            .header("Access-Control-Allow-Credentials", "true")
            .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
            .header("Access-Control-Max-Age", "1209600")
            .entity(memberList)
            .build();
}
Run Code Online (Sandbox Code Playgroud)

我必须进一步定义一个catch-all OPTIONS端点,它将为类中的任何其他OPTIONS请求返回CORS头,从而捕获排序的所有端点:

@OPTIONS
@Path("{path : .*}")
public Response options() {
    return Response.ok("")
            .header("Access-Control-Allow-Origin", "*")
            .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
            .header("Access-Control-Allow-Credentials", "true")
            .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
            .header("Access-Control-Max-Age", "1209600")
            .build();
}
Run Code Online (Sandbox Code Playgroud)

只有在这样做之后,才能正确使用来自其他域或主机上的Jquery Ajax客户端的JAX-RS API端点.


Ale*_*tty 12

我发现了一种更简单(特定于RestEasy)的方法,可以在不使用过滤器的情况下在Wildfly上启用CORS,并且可以在资源级别控制API响应头配置.

例如:

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getMemberList() {
    List<Member> memberList = memberDao.listMembers();
    members.addAll(memberList);
    return Response
            .status(200)
            .header("Access-Control-Allow-Origin", "*")
            .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
            .header("Access-Control-Allow-Credentials", "true")
            .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
            .header("Access-Control-Max-Age", "1209600")
            .entity(memberList)
            .build();
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*tty 11

通过使用此lib,我很幸运为我的API(在Wildfly上)配置跨源资源共享(CORS):

<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>2.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

它很容易设置.只需将上面的依赖项添加到您的pom,然后将以下配置添加到web.xml文件的webapp部分.

<filter>
    <filter-name>CORS</filter-name>
    <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>

    <init-param>
        <param-name>cors.allowGenericHttpRequests</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>cors.allowOrigin</param-name>
        <param-value>*</param-value>
    </init-param>

    <init-param>
        <param-name>cors.allowSubdomains</param-name>
        <param-value>false</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportedMethods</param-name>
        <param-value>GET, HEAD, POST, DELETE, OPTIONS</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportedHeaders</param-name>
        <param-value>*</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportsCredentials</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>cors.maxAge</param-name>
        <param-value>3600</param-value>
    </init-param>

</filter>

<filter-mapping>
    <!-- CORS Filter mapping -->
    <filter-name>CORS</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)

如果您愿意,也可以使用属性文件对其进行配置.这个lib就像一个魅力,为您提供了很多配置灵活性!

  • 我尝试了此操作,但看不到此添加到标题中。 (2认同)

Ale*_*x R 7

没有其他答案对我有用,但这样做:

import javax.ws.rs.core.Response;

然后将服务方法的返回类型更改为Response,并将return语句更改为:

return Response.ok(resp).header("Access-Control-Allow-Origin", "*").build();
Run Code Online (Sandbox Code Playgroud)

resp原始响应对象在哪里.