2009-09-10 42 views
10

Tengo una situación en la que un servlet proporciona datos comprimidos a un script PHP. Comprimo los datos en el lado de Java no hay problema, pero PHP parece incapaz de descomprimir.Comprimir con Java Descomprimir con PHP

Aquí está el código relevante fragmentos Java lateral:

OutputStream o=response.getOutputStream(); 

GZIPOutputStream gz=new GZIPOutputStream(o); 
gz.write(GridCoder.encode(rs,id, perPage, page).getBytes()); 
gz.close(); 
o.close(); 

PHP lateral:

$xml= gzuncompress($xml); 

por favor alguien puede apuntar en la dirección correcta.

+0

¿Recibió los errores? puedes publicar los registros? – rogeriopvl

+0

Asegúrate de que tu código java esté configurando el encabezado HTTP 'Content-Encoding: gzip'. – Asaph

+0

Advertencia: gzuncompress(): error de datos. Intenté hacer eco de los datos sin tratar de descomprimirlos para asegurarme de que estoy obteniendo datos reales y recibo un bloque de datos que comienza: [ Content Content-Encoding está configurado en gZip en el Java Side ... –

Respuesta

9

Acabo de ver su pregunta y estaba curioso al respecto. Así que hice mi propio caso de prueba. Salí de todas las cosas relacionadas con Servlet salir del problema y codificado así:

import java.io.*; 
import java.util.zip.GZIPOutputStream; 

public class GZIPTestcase { 

    public static void main(String[] args) throws Throwable { 
     GZIPOutputStream gzipOutputStream = new GZIPOutputStream(new FileOutputStream(new File("/Users/malax/foo2.gz"))); 
     PrintWriter pw = new PrintWriter(gzipOutputStream); 

     pw.println("All your base are belong to us!"); 
     pw.flush(); 
     pw.close(); 
    } 
} 

El GNU gunzip fue capaz de descomprimir los datos. Entonces intento descomprimirlo con PHP. Falló con el mismo error que obtuviste. I investigarse más a fondo y encontré los métodos siguientes:

  • gzdecode()
  • gzinflate()

gzinflate no funciona bien, gzdecode solamente se envía con wich PHP6 i havn't instalado. Quizás puedas probar esto. (Según http://bugs.php.net/bug.php?id=22123 esto funcionará)

Im dudo que el problema esté en el lado de Java porque el gunzip de GNU puede desinflar los datos así que debe ser correcto. Es posible que desee investigar más a fondo en el lado de PHP.

Hay una pregunta real para .NET y PHP donde el cartel original tiene el mismo problema que usted tiene: Can PHP decompress a file compressed with the .NET GZipStream class?. PHP tampoco parece poder descomprimir los datos del equivalente .NET de GZIPOutputStream.

Disculpa que no tengo una "solución", pero de todos modos podría haberte apuntado en la dirección correcta.

EDIT: He encontrado una entrada en el PHP Bugtracker lo que explica el problema: http://bugs.php.net/bug.php?id=22967 Parece que gzuncompress no puede descomprimir los datos GZIP con encabezados que se producirán sea el GZIPOutputStream. Como se indica en la entrada de Bugtracker, intente recortar el encabezado.

6

Trate de usar DeflaterOutputStream en lugar de GZIPOutputStream

El PHP funciones ponen en libzlib que implementa desinflarse. Gzip es una bestia completamente diferente.

Nombrar las funciones PHP gz XXX solo aumenta la confusión.

+0

Esto funcionó para mí. – shady

+0

nice one, funciona bien – radhoo

3

Encontré una manera de solucionarlo, usando una publicación de Devon_C_Miller y Malax como una guía.

Código

para Java:

String body = "Lorem ipsum shizzle ma nizle"; 

    URL url = new URL("http://some.url/file.php?id=" + uid); 
    URLConnection conn = url.openConnection(); 
    conn.setDoOutput(true); 
    conn.setRequestProperty("Content-encoding", "deflate"); 
    conn.setRequestProperty("Content-type", "application/octet-stream"); 

    DeflaterOutputStream dos = new DeflaterOutputStream(conn.getOutputStream()); 

    dos.write(body.getBytes()); 
    dos.flush(); 
    dos.close(); 

lado PHP:

$content = http_get_request_body(); 

    $uncontent = gzuncompress($content); 
+0

+1. Intenté muchas soluciones, entre ellas, "cortar el encabezado no reconocido por PHP", pero solo funcionó. Gracias. – firebear

+0

que no funciona con cadenas que tienen compresión después de> 300b ... no tengo idea de por qué, pero en esos casos 'DeflaterOutputStream' actúa como' GZIPOutputStream' (dando los mismos resultados, no descomprimible por PHP) –

+0

@FlashThunder No puedo reproduzca su problema utilizando PHP 5.6.15 y Java 8. Puedo hacer gzuncompress() en PHP una cadena UTF-8 de texto aleatorio de 1 millón de caracteres comprimida con Java DeflaterOutputStream (usando una respuesta similar a la de firebear). Eso es 300KB comprimido, y 1MB comprimido, muy por encima de su 300b. Aquí está el código utilizado para probar tu error: https://gist.github.com/cordje/48a957333cd045afa3792c82334d9b06 –

0

La combinación de 'Java deflactor + PHP gzuncompress' trabajó para mí. Cliente: Android 4.1.1, sitio del servidor: php 5.3

Para quién está buscando una solución para comprimir solo partes del cuerpo de la solicitud en algunos casos, por ejemplo como yo, usando el formulario HTTP para publicar algunos parámetros y un archivo, el siguiente es el fragmento que usé en el lado de Android:

public static byte[] compressString(String data) throws IOException { 
     byte[] compressed = null; 
     byte[] byteData = data.getBytes(); 
     ByteArrayOutputStream bos = new ByteArrayOutputStream(byteData.length); 
     Deflater compressor = new Deflater(); 
     compressor.setLevel(Deflater.BEST_COMPRESSION); 
     compressor.setInput(byteData, 0, byteData.length); 
     compressor.finish(); 

     // Compress the data 
     final byte[] buf = new byte[1024]; 
     while (!compressor.finished()) { 
      int count = compressor.deflate(buf); 
      bos.write(buf, 0, count); 
     } 
     compressor.end(); 
     compressed = bos.toByteArray(); 
     bos.close(); 
     return compressed; 
    } 
Cuestiones relacionadas