2014-05-15 36 views
9

我想通过创建一个小的RESTful服务来学习球衣。我想使用过滤器的具体原因(如我想使用ContainerResponseFilterCORS标题,以允许跨域请求)。但是,我只是无法让这些过滤器拦截我的呼叫。我已经看到了这个问题的所有帖子,其中大多数人说要注册提供者或web.xml。 在web.xml中我试图注册该文件,以及给予@Provider标注为容器ContainerRequestFilter ContainerResponseFilter剂量被调用

这里是我的web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<!-- This web.xml file is not required when using Servlet 3.0 container, 
    see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html#d4e194 --> 
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/classes/spring/config/BeanLocations.xml</param-value> 
    </context-param> 

    <servlet> 
     <servlet-name>Jersey Web Application</servlet-name> 
     <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> 
     <init-param> 
      <param-name>com.sun.jersey.config.property.packages</param-name> 
      <param-value>com.rest.example</param-value> 
     </init-param> 
     <init-param> 
      <param-name>jersey.config.server.provider.packages</param-name> 
      <param-value>com.rest.example.cors</param-value> 
     </init-param> 
     <init-param> 
      <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name> 
      <param-value>com.rest.example.CORSFilter</param-value> 
     </init-param> 
     <init-param> 
      <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name> 
      <param-value>com.rest.example.RequestFilter</param-value> 
     </init-param> 

    </servlet> 
    <servlet-mapping> 
     <servlet-name>Jersey Web Application</servlet-name> 
     <url-pattern>/webresources/*</url-pattern> 
    </servlet-mapping> 

</web-app> 

这里是我的过滤器:

package com.rest.example.cors; 

import javax.ws.rs.ext.Provider; 

import com.sun.jersey.spi.container.ContainerRequest; 
import com.sun.jersey.spi.container.ContainerResponse; 
import com.sun.jersey.spi.container.ContainerResponseFilter; 

@Provider 
public class CORSFilter implements ContainerResponseFilter { 

    public ContainerResponse filter(ContainerRequest creq, 
      ContainerResponse cresp) { 

      cresp.getHttpHeaders().putSingle("Access-Control-Allow-Origin", "*"); 
      cresp.getHttpHeaders().putSingle("Access-Control-Allow-Credentials", "true"); 
      cresp.getHttpHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD"); 
      cresp.getHttpHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With"); 

      return cresp; 
    } 
} 


package com.rest.example.cors; 

import javax.ws.rs.ext.Provider; 

import com.sun.jersey.spi.container.ContainerRequest; 
import com.sun.jersey.spi.container.ContainerRequestFilter; 

@Provider 
public class RequestFilter implements ContainerRequestFilter { 

    public ContainerRequest filter(ContainerRequest request) { 
     System.out.println("request filter"); 
     return request; 
    } 

} 

Link到我的github项目。

我有点困在这里2天。

感谢

+0

您使用什么容器/应用程序服务器和泽西版本?另外,你有没有尝试在你的泽西岛应用课程中注册你的过滤器? – Baldy

+0

我使用球衣版本1.8。我正在使用STS附带的VMware VFabric。我们如何在泽西应用程序类中注册过滤器? – user2973475

+0

要注册你的过滤器,把它们添加到你的'javax.ws.rs.core.Application'对象的'getClasses'方法中,尽管它看起来你的web.xml应该为你处理。你的REST方法是否被调用?你怎么知道你的过滤器没有被调用? – Baldy

回答

7

我加了泽西应用类,注册类中的过滤器,它解决了我的问题。还升级了我的球衣版本1.x的从2.X到

public class MyApplication extends ResourceConfig { 

    /** 
    * Register JAX-RS application components. 
    */ 
    public MyApplication() { 
     register(RequestContextFilter.class); 
     register(JacksonFeature.class); 
     register(CustomerResource.class); 
     register(Initializer.class); 
     register(JerseyResource.class); 
     register(SpringSingletonResource.class); 
     register(SpringRequestResource.class); 
     register(CustomExceptionMapper.class); 
    } 
} 
+2

在泽西2.24部署在Tomcat 8.5中,但我还必须在'web.xml'中注册应用程序类,如下所示:'​​javax.ws.rs.Application MyApplication '(在'org.glassfish.jersey.servlet.ServletContainer'的servlet定义内) –

1

<init-param> 
 
    <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name> 
 
    <param-value>org.anchepedheplatform.infrastructure.core.filters.ResponseCorsFilter</param-value> 
 
</init-param>

首先,我写它实现com.sun.jersey.spi.container.ContainerResponseFilter

import javax.ws.rs.core.Response; 
import javax.ws.rs.core.Response.ResponseBuilder; 

import com.sun.jersey.spi.container.ContainerRequest; 
import com.sun.jersey.spi.container.ContainerResponse; 
import com.sun.jersey.spi.container.ContainerResponseFilter; 

/** 
* Filter that returns a response with headers that allows for Cross-Origin 
* Requests (CORs) to be performed against the platform API. 
*/ 
public class ResponseCorsFilter implements ContainerResponseFilter { 

    @Override 
    public ContainerResponse filter(final ContainerRequest request, final ContainerResponse response) { 
     final ResponseBuilder resp = Response.fromResponse(response.getResponse()); 
     resp.header("Access-Control-Allow-Origin", "*") 
     .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); 
     final String reqHead = request.getHeaderValue("Access-Control-Request-Headers"); 
     if (null != reqHead && !reqHead.equals(null)) { 
     resp.header("Access-Control-Allow-Headers", reqHead);} 
     response.setResponse(resp.build()); 
     return response; 
} 

一类,后来我已经把这个类的引用在intit-param web.xml中。

+1

您提供的代码来自[CORS兼容的REST API与Jersey和ContainerResponseFilter](http://blog.usul.org/ cors-compliant-rest-api-with-jersey-and-containerresponsefilter /)? – Athafoud

3

我解决了这个问题上Wildfly 10 /休息容易像这样(CORSFilter是我ContainerResponseFilter):

import java.util.HashSet; 
import java.util.Set; 

import javax.ws.rs.ApplicationPath; 
import javax.ws.rs.core.Application; 

@ApplicationPath("/rest") 
public class JaxRsActivator extends Application { 

    @Override 
    public Set<Class<?>> getClasses() { 
     final Set<Class<?>> resources = new HashSet<Class<?>>(); 

     resources.add(CORSFilter.class); 

     return resources; 
    } 
} 
+0

谢谢,这也是我的问题。 –

0

如果要扩展的ResourceConfig类注册的所有供应商的过程可能是乏味的一个机会有没有人可以错过少数提供者。

这里可以用ResourceConfig类型做什么,你可以在默认的构造函数中使用包方法来指定将包含你的休息资源和提供者的packages("")。对于实例可以说,我们有一整套com.test.poc.rest其中包含了所有的休息服务和其他包即com.test.poc.providers那么我们resourceConig看起来像:

public class CustomResourceConfig extends ResourceConfig{ 
    public CustomResourceConfig(){ 
     super(); 
     packages("com.test.poc.rest;com.test.poc.providers"); 
     //register any custom features 
     register(JacksonFeature.class);   // enabling JSON feature. 
    } 
} 

和繁荣的球衣将立即扫描你的web服务与@Path注释并为供应商注释为@Provider