Распаковка PHP gzcompress в Java

Я пытаюсь распаковать объект json в Java, который был изначально сжат в PHP. Вот как это сжимается в PHP:

function zip_json_encode(&$arr) {
$uncompressed = json_encode($arr);
return pack('L', strlen($uncompressed)).gzcompress($uncompressed);
}

и декодируется (снова в PHP):

function unzip_json_decode(&$data) {
$uncompressed = @gzuncompress(substr($data,4));
return json_decode($uncompressed, $array_instead_of_object);
}

Это помещается в MySQL, и теперь он должен быть извлечен из базы данных Java. Мы вытаскиваем его из ResultSet как это:

String field = rs.getString("field");

Затем я передаю эту строку в метод для ее распаковки. Вот где он разваливается.

private String decompressHistory(String historyString) throws SQLException {
StringBuffer buffer = new StringBuffer();
try {
byte[] historyBytes = historyString.substring(4).getBytes();
ByteArrayInputStream bin = new ByteArrayInputStream(historyBytes);
InflaterInputStream in = new InflaterInputStream(bin, new Inflater(true));
int len;
byte[] buf = new byte[1024];
while ((len = in.read(buf)) != -1) {
// buf should be decoded, right?
}

} catch (IOException e) {
e.getStackTrace();
}
return buffer.toString();

}

Не совсем уверен, что здесь происходит, но любые указатели будут оценены!

0

Решение

Вам нужно избавиться от true в Inflater(true), Используйте только Inflater(), true заставляет его ожидать необработанных данных. Без true, это ожидает zlib-обернутые дефляционные данные. РНР gzcompress() производит zlib-обернутые данные deflate.

1

Другие решения

Сжатые данные являются двоичными, байтами []. Использование String, текста Unicode не только требует преобразования, но и является дефектным.

Например, это включает преобразование:

byte[] historyBytes = historyString.substring(4).getBytes();
byte[] historyBytes = historyString.substring(4).getBytes("ISO-8859-1");

Первая версия использует кодировку платформы по умолчанию, что делает приложение непереносимым.

Первое, что нужно сделать, это использовать двоичные данные в базе данных как VARBINARY или BLOB.

ImputStream field = rs.getBinaryStream("field");
try (InputStream in = new GZIPInputStream(field)) {
...
}

Или так. Имейте в виду другой ответ.

1

В итоге ни одно из вышеперечисленных решений не сработало, но оба имеют свои достоинства. Когда мы извлекаем данные из mysql и приводим их к байтам, у нас есть несколько пропущенных символьных байтов (67). Это сделало невозможным распаковку на стороне Java. Что касается ответов выше. Марк прав, что gzcompress () использует zlib, и поэтому вы должны использовать класс Inflater () в Java.

Joop правильно, что преобразование данных является ошибочным. Наш стол был слишком большим, чтобы преобразовать его в varbinary или blob. Тот может решили проблему, но у нас не сработало. Мы закончили тем, что java сделали запрос к нашему приложению PHP, а затем просто распаковали сжатые данные на стороне PHP. Это сработало хорошо. Надеюсь, это полезно для всех, кто сталкивается с этим.

0
По вопросам рекламы [email protected]