2012-02-07 17 views
10

Hemos creado algunos servicios web REST (jax-rs) usando Apache CXF. Devuelven una respuesta JSON.¿Filtro de servlet frente a interceptor CXF para modificar el contenido de solicitud y respuesta?

Ahora necesito modificar algunos de los parámetros de solicitud y el contenido de la respuesta. (Básicamente, necesitamos codificar/encriptar algunos de los datos que devuelve el servicio, y decodificar/descifrar los mismos datos cuando se utiliza como parámetro en una llamada de servicio posterior).

Parece que tengo al menos 4 opciones aquí:

  1. utilizar un filtro de servlet
  2. Utilice un interceptor de CXF
  3. uso a JAX-RS filtrar
  4. no utilice ningún patrón particular, y realizar la codificación/decodificación en el real servicio de lógica.

He usado Servlet Filters antes, y entiendo exactamente cómo modificar los parámetros de solicitud y el cuerpo de la respuesta, así que me inclino por eso. Sin embargo, estoy abierto a usar un interceptor CXF o un filtro JAX-RS si esa es la forma más "correcta" de resolver esto cuando se usa CXF. Pero basado en la documentación, realmente no entiendo cómo para hacer esto. Por ejemplo, ¿uso el método setContent del objeto Message para cambiar la respuesta JSON? ¿Cuál es el parámetro de formato en ese caso, solo String.class?

Respuesta

8

Respondiendo a mi pregunta aquí ... Terminé usando un filtro JAX-RS, y funcionó bien, una vez que supere la falta de documentación. Utilicé la documentación (bastante dispersa) de http://cxf.apache.org/docs/jax-rs-filters.html. Tenga en cuenta que a pesar de su nombre, un filtro JAX-RS es una bestia específica de CXF, no parte del estándar JAX-RS (por lo que yo sé).

Aquí es un código de ejemplo:

@Context 
private HttpServletRequest httpRequest; 
@Context 
private UriInfo uriInfo; 

/** 
* @see org.apache.cxf.jaxrs.ext.ResponseHandler#handleResponse(org.apache.cxf.message.Message, org.apache.cxf.jaxrs.model.OperationResourceInfo, javax.ws.rs.core.Response) 
*/ 
public Response handleResponse(Message message, OperationResourceInfo opResourceInfo, Response response) { 
    try { 

     // log the injected context data; useful for debugging CXF problems 
     logContextData(httpRequest, uriInfo); 

     OutputStream os = message.getContent(OutputStream.class); 
     String relevantData = getDataFromRequest(httpRequest); 
     message.setContent(OutputStream.class, new MyOutputStreamWrapper(os, relevantData)); 

    } catch (CustomException e) { 
      // return some status that is related to CustomException 
     return Response.status(Status.UNAUTHORIZED).build(); 
    } catch (Exception e) { 
     return Response.status(Status.INTERNAL_SERVER_ERROR).build(); 
    } 

    return response; 
} 

/** 
* @see org.apache.cxf.jaxrs.ext.RequestHandler#handleRequest(org.apache.cxf.message.Message, org.apache.cxf.jaxrs.model.ClassResourceInfo) 
*/ 
public Response handleRequest(Message message, ClassResourceInfo classResourceInfo) { 
    try { 

     // log the injected context data; useful for debugging CXF problems 
     logContextData(); 

     String updatedQueryString = buildNewQueryString(this.uriInfo, httpRequest); 

     message.put(Message.QUERY_STRING, updatedQueryString); 


     // returning null tells CXF to continue the request (i.e. a non-null value would halt the request) 
     return null; 

    } catch (CustomException e) { 
     // return some status that is related to CustomException 
     return Response.status(Status.UNAUTHORIZED).build(); 
    } catch (Exception e) { 
     return Response.status(Status.INTERNAL_SERVER_ERROR).build(); 
    } 
} 

deben tener en cuenta que la aplicación de MyOutputStreamWrapper es la parte importante en la modificación del contenido de la respuesta. No pude incluir esa fuente aquí (de hecho, mi implementación tiene un nombre diferente) debido a consideraciones de seguridad.

+2

Sería bueno si pudiera explicar la razón detrás de hacer su elección. – andthereitgoes

+0

tengo la misma pregunta, si CXF ha proporcionado el interceptor, ¿por qué todavía necesita tener el filtro? – Chailie

+3

@Chailie - no había una razón fuerte para usar el filtro JAX-RS sobre CXF Interceptor, creo que la razón principal por la que lo elegí fue que era específico de JAX-RS, pero un Interceptor CXF también habría funcionado. (Sin embargo, habría requerido la misma cantidad de codificación personalizada). Tenga en cuenta que JAX-RS 2.0 ya está disponible, por lo que los filtros e interceptores JAX-RS se han convertido en parte de la especificación y definitivamente serían el camino a seguir con la tecnología actual. tecnología. –

Cuestiones relacionadas