У меня есть ситуация, когда сервлет предоставляет сжатые данные в PHP-скрипт. Я сжимаю данные на стороне Java без проблем, но PHP кажется неспособным распаковывать.
Ниже приведены соответствующие фрагменты кода Java Side:
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);
Может кто-то, пожалуйста, назовите меня в правильном направлении.
Я только что увидел ваш вопрос, и мне было любопытно. Поэтому я сделал свой собственный тестовый сценарий. Я оставил все связанные с Servlet вещи из проблемы и закодировал что-то вроде этого:
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. Это не удалось с той же ошибкой, что и вы. Далее я исследовал и нашел следующие методы:
gzinflate тоже не работает, gzdecode отправляется только с PHP6, который я не установил. Может быть, вы могли бы попробовать это. (Согласно http://bugs.php.net/bug.php?id=22123 это будет работать)
Я сомневаюсь, что проблема на стороне Java, потому что GNZ-gunzip может дефлировать данные, чтобы они были правильными. Возможно, вам захочется исследовать дальше на стороне PHP.
Существует нерешенный вопрос для .NET и PHP, где исходный плакат имеет ту же проблему, что и у вас: может ли PHP распаковать файл, сжатый классом .NET GZipStream? , PHP, похоже, не способен распаковывать данные из .NET-эквивалента GZIPOutputStream.
Извините, что у меня нет «решения», но я, возможно, указал вам в правильном направлении.
EDIT: я нашел запись в PHP Bugtracker, которая объясняет проблему: http://bugs.php.net/bug.php?id=22967 Кажется, что gzuncompress не может распаковать данные GZIP с заголовками, которые будут выпущены GZIPOutputStream. Как указано в записи Bugtracker, попробуйте обрезать заголовок.
Попробуйте использовать DeflaterOutputStream вместо GZIPOutputStream
Функции PHP вызывают в libzlib, который реализует DEFLATE. Gzip совсем другой зверь.
Именование функций PHP gz XXX только добавляет путаницы.
Я нашел способ исправить это, используя сообщение 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);
Сочетание «Java Deflater + 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; }