J'essaie d'apprendre le maillot en créant un petit service RESTful. Je souhaite utiliser les filtres pour des raisons spécifiques (par exemple, je veux utiliser les en-têtes ContainerResponseFilter pour CORS pour autoriser les requêtes entre domaines). Cependant, je ne parviens tout simplement pas à faire intercepter mes filtres par ces filtres. J'ai vu toutes les publications de ce problème et la plupart d'entre elles disent de s'enregistrer auprès du fournisseur d'annotation ou dans web.xml . J'ai essayé d'enregistrer les fichiers dans web.xml et de donner une annotation @Provider
pour le conteneur
Voici mon 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>
Voici mes filtres:
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;
}
}
Lien à mon projet github.
J'ai ajouté une classe Jersey Application et enregistré le filtre dans la classe, ce qui a résolu mon problème. Également mis à niveau ma version du maillot de la version 1.x à la version 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);
}
}
J'ai résolu le problème sur Wildfly 10/reste facile comme ceci (CORSFilter est mon 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;
}
}
<init-param>
<param-name>com.Sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>org.anchepedheplatform.infrastructure.core.filters.ResponseCorsFilter</param-value>
</init-param>
Tout d'abord, j'ai écrit une classe qui implémente 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;
}
et plus tard, j'avais mis cette référence de cette classe dans intit-param web.xml.
Si vous élargissez la classe ResourceConfig
, le processus d’enregistrement de tous les fournisseurs peut être fastidieux et il y a de fortes chances pour qu’il soit possible de rater quelques fournisseurs.
Ce que l’on peut faire ici avec un type de ResourceConfig
est que vous pouvez utiliser la méthode packages dans le constructeur par défaut pour spécifier la packages("")
qui contiendra vos ressources restantes et les fournisseurs. Par exemple, disons que nous avons un paquetage com.test.poc.rest
qui contient tous les services restants et un autre paquetage, à savoir com.test.poc.providers
, alors notre ressourceConig ressemblera à ceci:
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.
}
}
et boom jersey va maintenant rechercher vos services Web annotés avec @Path
et les fournisseurs annotés avec @Provider
.