2014-05-15 68 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