2014-05-15 14 views
9

Sto cercando di imparare la maglia creando un piccolo servizio RESTful. Voglio utilizzare i filtri per motivi specifici (ad esempio voglio utilizzare il contenitore ContainerResponseFilter per le intestazioni CORS per consentire richieste tra domini diversi). Tuttavia, non sono in grado di ottenere questi filtri per intercettare la mia chiamata. Ho visto tutti i post per questo problema e molti di loro dicono di registrarsi con il fornitore di annotazioni o in web.xml. Ho provato a registrare i file in web.xml oltre a dare un'annotazione @Provider per il contenitoreContainerRequestFilter ContainerResponseFilter dosent get called

Ecco il mio 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> 

qui sono i miei Filtri:

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 al mio progetto github.

Sono tipo bloccato qui per 2 giorni.

Grazie

+0

Quale contenitore/server di applicazioni e versione di Jersey stai utilizzando? Inoltre, hai provato a registrare i filtri nella tua classe di applicazione Jersey? – Baldy

+0

Sto usando la versione jersey 1.8. Sto usando VMware VFabric fornito con STS. Come registriamo i filtri nella classe di applicazione jersey? – user2973475

+0

Per registrare i tuoi filtri, aggiungili al metodo 'getClasses' nell'oggetto' javax.ws.rs.core.Application' anche se sembra che il tuo web.xml debba gestirlo per te. I tuoi metodi REST vengono chiamati? Come sai che i tuoi filtri non vengono chiamati? – Baldy

risposta

7

ho aggiunto una classe Jersey Applicazione e registrate il filtro della classe, che ha risolto il mio problema. aggiornato anche la mia versione in jersey a 2.x da 1.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

che ha funzionato per me in Jersey 2.24 distribuito in Tomcat 8.5 ma ho anche dovuto registrare la classe dell'applicazione in 'web.xml' come segue:' javax.ws.rs.Application MyApplication '(all'interno della definizione del servlet per' org.glassfish.jersey.servlet.ServletContainer') –

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>

In primo luogo, ho scritto una classe che implementa 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; 
} 

e poi avevo messo questo riferimento di questa classe in intit-param web.xml.

+1

Il codice che hai fornito è stato prelevato da qui [API REST compatibile CORS con Jersey e ContainerResponseFilter] (http://blog.usul.org/ cors-compliant-rest-api-with-jersey-and-containerresponsefilter /)? – Athafoud

3

ho risolto il problema su wildfly 10/resto facile come questo (CORSFilter è il mio 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

Grazie anche a questo era il mio problema. –

0

Se si estende la classe ResourceConfig il processo di registrazione di tutti i fornitori può essere uno noioso e probabilità ci sono che uno può anche perdere alcuni fornitori.

Che qui si può fare con un tipo di ResourceConfig è che si può utilizzare il metodo dei pacchetti nel costruttore di default per specificare il packages("") che conterrà le risorse di riposo e dei fornitori. Per esempio permette di dire che abbiamo un pacchetto di com.test.poc.rest che contiene tutti i servizi di riposo e di un altro pacchetto vale a dire com.test.poc.providers allora il nostro resourceConig sarà simile:

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. 
    } 
} 

e jersey braccio esegue la scansione per i vostri webservices annotati con @Path e per i fornitori annotato con @Provider.

Problemi correlati