ajax json jax-rs resteasy cors

Solicitud Ajax con JAX-RS/RESTEasy implementando CORS



json (4)

Tengo dos servidores (Apache y JBoss AS7) y necesito proporcionar acceso a todos los métodos http a un cliente. Todas estas solicitudes deben enviarse a través de ajax. Ejemplo del código de cliente:

$.ajax({ type: "get", url: "http://localhost:9080/myproject/services/mobile/list", crossDomain: true, cache: false, dataType: "json", success: function(response) { console.log(response); }, error: function (jqXHR, textStatus, errorThrown) { console.log(textStatus); console.log(jqXHR.responseText); console.log(errorThrown); } });

En JBoss AS7 estoy usando RESTEasy, implementando CORS de la siguiente manera:

@Path("/mobile") @Provider @ServerInterceptor public class GroupMobile implements MessageBodyWriterInterceptor { @Inject private GroupDAO groupDAO; @GET @Path("/list") @Produces(MediaType.APPLICATION_JSON) public List<Group> getGroups() { return groupDAO.listAll(); } @Override public void write(MessageBodyWriterContext context) throws IOException, WebApplicationException { context.getHeaders().add("Access-Control-Allow-Origin", "*"); context.proceed(); } @OPTIONS @Path("/{path:.*}") public Response handleCORSRequest( @HeaderParam("Access-Control-Request-Method") final String requestMethod, @HeaderParam("Access-Control-Request-Headers") final String requestHeaders) { final ResponseBuilder retValue = Response.ok(); if (requestHeaders != null) retValue.header("Access-Control-Allow-Headers", requestHeaders); if (requestMethod != null) retValue.header("Access-Control-Allow-Methods", requestMethod); retValue.header("Access-Control-Allow-Origin", "*"); return retValue.build(); } }

web.xml y beans.xml son archivos vacíos. Cuando accedo a MyIP: 8080 (Apache), aparece el mensaje de error:

XMLHttpRequest cannot load http://localhost:9080/myproject/services/mobile/list?_=1359480354190. Origin http://MyIP:8080 is not allowed by Access-Control-Allow-Origin.

¿Alguien sabe lo que está mal?


El problema que está teniendo es que está intentando hacer scripts de sitios cruzados. Usted accedió a la página en http://MyIP:8080 y, por lo tanto, el navegador le impide acceder a recursos fuera de ese dominio. Esto es muy específico para el navegador y las soluciones basadas en el navegador serán todas diferentes (puede deshabilitar la seguridad en Chrome de forma global, y en cada sitio en IE).

Si carga la página como http://localhost:8080 , debería permitirle acceder a la consulta. Alternativamente, puede implementar un proxy que reenviará la solicitud.


Parece que el problema está relacionado con https://issues.jboss.org/browse/RESTEASY-878 . Es posible que no pueda detectar las solicitudes de verificación previa de CORS con MessageBodyWriterInterceptor . Intente utilizar filtros de servlet ( @WebFilter ) en su lugar.


Bueno, he implementado una pequeña solución, primero hago un interceptor en mi proyecto Web Creé una clase llamada "CORSInterceptor", la clase es del camino.

import org.jboss.resteasy.annotations.interception.ServerInterceptor; import org.jboss.resteasy.core.ResourceMethod; import org.jboss.resteasy.core.ServerResponse; import org.jboss.resteasy.spi.Failure; import org.jboss.resteasy.spi.HttpRequest; import org.jboss.resteasy.spi.interception.MessageBodyWriterContext; import org.jboss.resteasy.spi.interception.MessageBodyWriterInterceptor; import org.jboss.resteasy.spi.interception.PreProcessInterceptor; import javax.ws.rs.WebApplicationException; import javax.ws.rs.ext.Provider; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; @Provider @ServerInterceptor public class CorsInterceptor implements PreProcessInterceptor, MessageBodyWriterInterceptor { /** * The Origin header set by the browser at each request. */ private static final String ORIGIN = "Origin"; /** * The Access-Control-Allow-Origin header indicates which origin a resource it is specified for can be * shared with. ABNF: Access-Control-Allow-Origin = "Access-Control-Allow-Origin" ":" source origin string | "*" */ private static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin"; // private static final ThreadLocal<String> REQUEST_ORIGIN = new ThreadLocal<String>(); // private final Set<String> allowedOrigins; public CorsInterceptor(){ this.allowedOrigins = new HashSet<String>(); this.allowedOrigins.add("*"); } @Override public ServerResponse preProcess(HttpRequest request, ResourceMethod method) throws Failure, WebApplicationException { if (!allowedOrigins.isEmpty()) { REQUEST_ORIGIN.set(request.getHttpHeaders().getRequestHeaders().getFirst(ORIGIN)); } return null; } @Override public void write(MessageBodyWriterContext context) throws IOException, WebApplicationException { if (!allowedOrigins.isEmpty() && (allowedOrigins.contains(REQUEST_ORIGIN.get()) || allowedOrigins.contains("*"))) { context.getHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN, REQUEST_ORIGIN.get()); } context.proceed(); } }

En File Web.xml , lo agrego

<context-param> <param-name>resteasy.providers</param-name> <param-value><package>.CorsInterceptor</param-value> </context-param>

paquete : ubicación de la clase.

Solicite JQuery que he usado.

$.ajax({ type: ''GET'', dataType: "json", crossDomain : true, cache:false, url: "http://localhost:12005/ProyectoWebServices/ws/servicioTest", success: function (responseData, textStatus, jqXHR) { alert("Successfull: "+responseData); }, error: function (responseData, textStatus, errorThrown) { alert("Failed: "+responseData); } });

funcionó bien para mí. Espero que pueda ayudarte.


El último resteasy (3.0.9-Final) incluye una clase de utilidad org.jboss.resteasy.plugins.interceptors.CorsFilter .

Puede agregar el objeto CorsFilter al conjunto de objetos singleton de la Aplicación o agregarlo directamente a ProviderFactory en ResteasyDeployment.

La siguiente es la clase de aplicación de muestra:

import java.util.HashSet; import java.util.Set; import javax.ws.rs.ApplicationPath; import org.jboss.resteasy.plugins.interceptors.CorsFilter; @ApplicationPath("/api") public class RestApplication extends javax.ws.rs.core.Application { Set<Object> singletons; @Override public Set<Class<?>> getClasses() { HashSet<Class<?>> clazzes = new HashSet<>(); clazzes.add(VersionService.class); return clazzes; } @Override public Set<Object> getSingletons() { if (singletons == null) { CorsFilter corsFilter = new CorsFilter(); corsFilter.getAllowedOrigins().add("*"); singletons = new LinkedHashSet<Object>(); singletons.add(corsFilter); } return singletons; } }