【问题标题】:CORS Response Filter not invoked Resteasy / JAX-RS 2.0未调用 CORS 响应过滤器 Resteasy / JAX-RS 2.0
【发布时间】:2016-07-23 19:24:59
【问题描述】:

我正在尝试实现 CORS 响应文件管理器以允许从我的 JavaScript 前端进行跨域引用。我使用的是 Wildfly 10.0.final,它是 Resteasy 附带的,如果我理解正确的话是 JAX-RS 2.0 恭维。

编辑:将@Provider 添加到 CorsResponseFilter,并作为单例添加到 RestServiceConfig。

我需要做什么才能调用我的 CorsResponseFilter?

PS。阅读这些帖子,但它们无助于解决问题。

ContainerRequestFilter ContainerResponseFilter dosent get called

ResourceConfig and Application

CorsResponseFilter.java

@Provider
public class CorsResponseFilter implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {

    MultivaluedMap<String, Object> headers = responseContext.getHeaders();
    headers.add("Access-Control-Allow-Origin", "*");
    //headers.add("Access-Control-Allow-Origin", "http://podcastpedia.org"); //allows CORS requests only coming from podcastpedia.org       
    headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
    headers.add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, X-Codingpedia");        
    headers.add("Access-Control-Max-Age", "1209600");
}

}

RestServiceConfig.java

public class RestServiceConfig extends Application {

    private final Set<Object> singletons = new HashSet<>();

    public RestServiceConfig() {
        singletons.add(new CorsResponseFilter());  
        singletons.add(new ApplicationService());
        singletons.add(new TweetObsService());
    }

    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }
}

web.xml

...
<listener>
    <listener-class>
        org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
    </listener-class>
</listener>

<servlet>
    <servlet-name>resteasy-servlet</servlet-name>
    <servlet-class>
        org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
    </servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>org.mycorp.myapp.service.RestServiceConfig</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
        <param-value>org.clearbyte.obs.service.CorsResponseFilter</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>resteasy-servlet</servlet-name>
    <url-pattern>/service/*</url-pattern>
</servlet-mapping>
<context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/service</param-value>
</context-param>

...

Wildfly 日志控制台

13:56:01,672 INFO  [org.jboss.resteasy.resteasy_jaxrs.i18n] RESTEASY002225: Deploying javax.ws.rs.core.Application: class org.clearbyte.obs.service.RestServiceConfig
13:56:01,672 INFO  [org.jboss.resteasy.resteasy_jaxrs.i18n] RESTEASY002200: Adding class resource org.clearbyte.obs.service.TweetObsService from Application class org.clearbyte.obs.service.RestServiceConfig
13:56:01,672 INFO  [org.jboss.resteasy.resteasy_jaxrs.i18n] RESTEASY002200: Adding class resource org.clearbyte.obs.service.ApplicationService from Application class org.clearbyte.obs.service.RestServiceConfig

【问题讨论】:

  • 我已经尝试过了,但我得到了相同的结果。
  • 在其上添加@Provider 注释,看看会发生什么。您仍然需要将其添加到 singletons 虽然
  • 我不确定它是否适用于 RESTeasy,即处理请求的方式。我知道 RESTeasy 已经拥有它自己的CorsFilter。看看this post。您可以使用该过滤器
  • 是否需要在 web.xml 中声明使用内置 CORS 过滤器并在 Wildfly 10.0.final 中包含 RestEasy 3.0.9?
  • 你不能。它需要以编程方式进行配置,这意味着您不能只使用标准的 JAX-RS API 依赖项。您需要拥有 resteasy-jaxrs 依赖项。按照您想要的方式配置后,只需将其添加为单例即可。

标签: filter cors jax-rs resteasy


【解决方案1】:

所以我从头开始了一个新项目来消除错误源。感谢您对使用 @Provider 和添加 OPTIONS 的意见。另外,我从 web.xml 中删除了所有配置 REST。

@Provider 是过滤器工作的必要条件

ServiceCorsFilter.java

@Provider
public class ServiceCorsFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        responseContext.getHeaders().putSingle("Access-Control-Allow-Origin", "*");
        responseContext.getHeaders().putSingle("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, DELETE");
        responseContext.getHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type");                       
    }    
}

@ApplicationPath 使 web.xml 配置过时

ServiceConfig.java

    @ApplicationPath("service")
public class ServiceConfig extends Application {

    private Set<Object> singletons = new HashSet<>();

    public ServiceConfig() {
        singletons.add(new UserServiceV1());
        singletons.add(new ServiceCorsFilter());
    }

    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }

}

这是留在 web.xml 中的内容

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <display-name>MyApp</display-name>
    <!-- No REST related config due the the @Provider and inheritance of Application-->
</web-app>

【讨论】:

  • 通过使用@ApplicationPath("/service") 注释您的ServiceConfig.java,您应该能够从web.xml 删除几乎整个servlet 和上下文设置。
  • 正确我已经更新了 web.xml 和答案以反映这一点。
【解决方案2】:

我会尝试将其声明为标准过滤器,而不是 servlet 调度程序的参数:

<filter>
    <filter-name>CorsHeadersFilter</filter-name> 
    <filter-class>org.clearbyte.obs.service.CorsResponseFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>CorsHeadersFilter</filter-name> 
    <url-pattern>/service/*</url-pattern> 
</filter-mapping>

【讨论】:

    【解决方案3】:

    某些浏览器(即:Chrome)在发出请求之前会发送一个 OPTION 请求。 由于您明确指定'GET''PUT''POST''DELETE','OPTION'调用不会获取标题信息:)

    将 OPTION 添加到您的列表中应该可以解决问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-13
      • 1970-01-01
      • 2018-01-15
      • 2014-02-03
      • 2017-09-14
      • 1970-01-01
      相关资源
      最近更新 更多