Сжатие с помощью Java Распаковка с помощью PHP - PullRequest
10 голосов
/ 10 сентября 2009

У меня есть ситуация, когда сервлет предоставляет сжатые данные в PHP-скрипт. Я сжимаю данные на стороне Java без проблем, но PHP кажется не в состоянии распаковать.

Вот подходящие фрагменты кода Java сторона:

  OutputStream o=response.getOutputStream();

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

PHP Сторона:

$xml= gzuncompress($xml);

Может кто-нибудь, пожалуйста, укажите мне правильное направление.

Ответы [ 4 ]

9 голосов
/ 11 сентября 2009

Я только что увидел ваш вопрос и мне было любопытно. Итак, я сделал свой собственный тест-кейс. Я оставил все проблемы, связанные с сервлетом, вне проблемы и закодировал что-то вроде этого:

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();
    }
}

GNU gunzip смог распаковать данные. Затем я пытаюсь распаковать его с помощью PHP. Не удалось с той же ошибкой, которую вы получили. Я исследовал дальше и нашел следующие методы:

  • gzdecode ()
  • gzinflate ()

gzinflate тоже не работает, gzdecode поставляется только с PHP6, который у меня не установлен. Может быть, вы могли бы попробовать это. (Согласно http://bugs.php.net/bug.php?id=22123 это будет работать)

Я сомневаюсь, что проблема на стороне Java, потому что GNZ gunzip может выкачать данные, поэтому они должны быть правильными. Возможно, вы захотите продолжить исследование на стороне PHP.

Существует реальный вопрос для .NET и PHP, где у оригинального плаката та же проблема, что и у вас: Может ли PHP распаковать файл, сжатый с помощью класса .NET GZipStream? . Похоже, что PHP не может распаковать данные из .NET-эквивалента GZIPOutputStream.

Извините, что у меня нет "решения", но я все равно мог бы указать вам правильное направление.

РЕДАКТИРОВАТЬ: Я нашел запись в PHP Bugtracker, которая объясняет проблему: http://bugs.php.net/bug.php?id=22967 Похоже, что gzuncompress не может распаковать данные GZIP с заголовками, которые будут созданы GZIPOutputStream. Как указано в записи Bugtracker, попробуйте обрезать заголовок.

6 голосов
/ 11 сентября 2009

Попробуйте использовать DeflaterOutputStream вместо GZIPOutputStream

Функции PHP вызывают libzlib, который реализует DEFLATE. Gzip совершенно другой зверь.

Наименование функций PHP gz XXX только добавляет путаницы.

3 голосов
/ 20 мая 2011

Я нашел способ исправить это, используя сообщение Devon_C_Miller и Malax в качестве руководства.

Код для 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();

PHP сторона:

   $content = http_get_request_body();

   $uncontent = gzuncompress($content);
0 голосов
/ 21 июля 2014

Комбинация Java Deflater + 1001 * PHP gzuncompress работала для меня. Клиент: Android 4.1.1, сайт сервера: php 5.3

Для тех, кто ищет решение для сжатия только части тела запроса в некоторых случаях, например, как я, используя HTTP-форму для публикации некоторых параметров и файла, ниже приведен фрагмент, который я использовал на стороне 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;
    }
...