Estoy tratando de escribir un simple Jersey de la aplicación que envía los archivos a partir de un Jersey de cliente con un Jersey de servidor y la espalda. Sin embargo, los archivos sólo parecen ser codificados en el camino desde el cliente al servidor, pero no de la otra manera. Me pregunto cómo puedo cambiar este comportamiento.

Estoy probando esto en un ejemplo sencillo:

public class GZipEncodingTest extends JerseyTest {

  private static final String PATH = "/";
  private static final String QUESTION = "foo", ANSWER = "bar";
  private static final String ENCODING_GZIP = "gzip";

  @Path(PATH)
  public static class MyResource {
    @POST
    public Response handle(String question) throws IOException {
      assertEquals(QUESTION, question);
      return Response.ok(ANSWER).build(); //(1)
    }
  }

  @Override
  protected Application configure() {
    enable(TestProperties.LOG_TRAFFIC);
    enable(TestProperties.DUMP_ENTITY);
    return new ResourceConfig(MyResource.class, GZipEncoder.class);
  }

  @Override
  @SuppressWarnings("unchecked")
  protected void configureClient(ClientConfig config) {
    config.register(new EncodingFeature(ENCODING_GZIP, GZipEncoder.class));
  }

  @Test
  public void testHeaders() throws Exception {
    Response response = target().path(PATH).request().post(Entity.text(QUESTION));
    assertEquals(ANSWER, response.readEntity(String.class));
  }
}

De la sesión de volcado, puedo decir que la petición es como se pretendía: la codificación del contenido se indica en el encabezado y aplicados en el mensaje de solicitud de cuerpo. El Accept-Encoding también se establece. El servidor entiende el que se aplica la compresión gzip y baja la cremallera de la solicitud del cuerpo del mensaje. Sin embargo, ignora el hecho de que el cliente acepta un formato gzip, respuesta y envía el mensaje de respuesta del cuerpo sin comprimir.

Cuando me anexar encoding(ENCODING_GZIP) en línea (1) en el Responseel constructor de la cadena, obtengo el resultado que estoy buscando. Sin embargo, quiero aplicar la codificación si fue marcado como aceptable en la solicitud. Además, quiero aliado esta característica de la aplicación amplia y no sólo para las respuestas específicas.

Yo por supuesto, puede añadir esta función manualmente con un WriterInterceptor:

public class GZipWriterInterceptor implements WriterInterceptor {
  @Override
  public void aroundWriteTo(WriterInterceptorContext context) 
      throws IOException, WebApplicationException {
    context.getHeaders().add(HttpHeaders.CONTENT_ENCODING, ENCODING_GZIP);
    context.proceed();
  }
}

pero estoy convencido de que esto es innecesario, la caldera de la placa.

La EncodingFeature parece ser sólo una parte de la biblioteca de cliente. Yo soy básicamente buscando la posibilidad de hacer el Jersey servidor codifica la información como gzip siempre que la solicitud sugirió la codificación a través de accept-encoding.

Cuando trato de buscar soluciones en la web, me encuentro con un montón. La mayoría de ellos se refieren a Jersey 1. Algunos de ellos sugieren que la adición de un oyente a la GrizzlyServer (que sería Jersey específico y no JAX-RS?). Entonces hay un montón de clases dentro de la camiseta 2 árbol de dependencia que sugieren la codificación GZip:

  • org.glassfish.grizzly.http.GZipContentEncoding
  • org.glassfish.jersey.message.GZipEncoder
  • org.glassfish.grizzly.compression.zip.GZipEncoder
  • org.glassfish.grizzly.compression.zip.GZipDecoder
  • org.glassfish.grizzly.compression.zip.GZipFilter

He encontrado que las personas en la web sugieren el uso de cualquiera de ellos, aunque me gusta pensar que org.glassfish.jersey parece ser la opción correcta ya que es un Jersey de dependencia. Por no hablar de aquellos que se encuentran en el ApacheConnector relacionados con las bibliotecas. No tengo idea de cuál debo usar realmente.

Consulte stackoverflow.com/questions/19751014/…
Bueno, mi problema es un poco más complejo. Yo quería reconstruir la codificación gzip. He replanteado mi pregunta aquí: stackoverflow.com/questions/19794014/…
Todavía estoy tratando de reconstruir el solución oficial a este problema mediante la obtención de la GZip ejemplo para trabajar. Sin embargo, sólo se trabaja de una manera, pero no en el otro. La solución que sugieren parece un hack para mí, para ser honesto.

OriginalEl autor Rafael Winterhalter | 2013-11-04

1 Comentario

  1. 18

    Me lo imaginé mirando a través de la camiseta de la biblioteca. Por el lado del servidor, la configuración siguiente es necesario:

    @Override
    @SuppressWarnings("unchecked")
    protected Application configure() {
        ResourceConfig resourceConfig = new ResourceConfig(MyResource.class);
        EncodingFilter.enableFor(resourceConfig, GZipEncoder.class);
        return resourceConfig;
    }

    Bajo la convers, EncodingFilter#enableFor(ResourceConfig.Class<? extends ContentEncoder>[])registra una EncodingFilter y el GZipEncoder con la ResourceConfig.

    Supongo que la razón detrás de este desvío en el registro radica en el hecho de que cualquier codificación que debe ocurrir en dos etapas. En primer lugar, la EncodingFilter (que es una ContainerResponseFilter modifica el encabezado de la respuesta de la configuración de Content-Encoding a gzip. Al mismo tiempo, un filtro puede modificar la entidad corriente de el cuerpo del mensaje, ya que el filtro se invoca antes de que esta corriente es creado. Por lo tanto, la secuencia de modificación debe ser procesado por un WriterInterceptor que se activa después de que el procesamiento del filtro y también después de la creación de la entidad corriente.

    Por esta razón, sólo el registro de la GZipEncoder de trabajo para la solicitud de decodificación cuando el Content-Encoding encabezado se establece en gzip por el cliente que se produce independientemente de la creación del servidor.

    El ejemplo que me dio con mi ‘GZipWriterInterceptor’ es, básicamente, un mal implementado la versión de la EncodingFilter. Por supuesto, el encabezado debe ser establecido en un filtro y no en un interceptor. Es dice en la documentación:

    Mientras que los filtros están pensados principalmente para manipular la solicitud y
    los parámetros de respuesta como los encabezados HTTP, Uri y/o métodos HTTP,
    los interceptores son destinados a manipular a las entidades, a través de la manipulación de
    entidad flujos de entrada/salida

    Por lo tanto, la codificación gzip simplemente no puede ser activado por el registro de un GZipEncoder, debe estar registrado con un filtro, así. Esta es la razón por la que me espera para ser incluido en un Feature.

    Importante: Hay dos EncodingFilter clases dentro de Jersey. Uno pertenece a el cliente, el otro pertenece a la implementación del servidor. No utilice el mal, ya que hacer cosas distintas. Desafortunadamente, usted tendrá en su ruta de clase cuando se ejecuta la unidad de pruebas, ya que se basan en la interfaz de cliente.

    es muy horrible… esta solución es sólo para Jersey 2.0+
    los punteros para 1x(1.6)?

    OriginalEl autor Rafael Winterhalter

Dejar respuesta

Please enter your comment!
Please enter your name here