İdeal olarak, bu şeyleri sizin için halletmek için üst düzey bir kitaplık kullanmalısınız. Bu şekilde, yeni bir HTTP sürümü yayınlandığında, kütüphane yöneticisi umarım tüm zor işleri sizin için yapar ve sadece kütüphanenin güncellenmiş versiyonuna ihtiyacınız vardır.
Bu arada, bunu kendiniz yapmayı denemek için güzel bir egzersiz.
Bir TCP soketinden bir bayt akışı olarak bir HTTP Yanıtı okuduğunuzu varsayalım. Eğer gzip kodlaması yoksa, tüm cevabı bir String'e koymak işe yarayabilir. Bununla birlikte, "Content-Encoding: gzip" başlığının bulunması, yanıt gövdesinin (sizin de belirttiğiniz gibi) ikili olması anlamına gelir.
Yanıt gövdesinin başlangıcını, "\ r \ n \ r \ n" (veya 4 bayt 0x0d, 0x0a, 0x0d, 0x0a) dizesi dizisinin ilk oluşumunu izleyen ilk bayt olarak belirleyebilirsiniz.
gzip kodlaması özel başlık vardır ve bunun için ilk 3 vücut bayt test etmelidir: İlk 3 bayt yoksa
byte[] buf; // from the HTTP Response stream
// ... insert code here to populate buf from HTTP Response stream
// ...
int bodyLen = 1234; // populate this value from 'Content-length' header
int bodyStart = 123; // index of byte buffer where body starts
if (bodyLen > 4 && buf[bodyStart] == 0x1f && buf[bodyStart + 1] == (byte) 0x8b && buf[bodyStart + 2] == 0x08) {
// gzip compressed body
ByteArrayInputStream bais = new ByteArrayInputStream(buf);
if (bodyStart > 0) bais.skip(bodyStart);
// Decompress the bytes
byte[] decompressedBytes = new byte[bodyLen * 4];
int decompressedDataLength = 0;
try {
// note: replace this try-catch with try-with-resources here where possible
GZIPInputStream gzis = new GZIPInputStream(bais);
decompressedDataLength = gzis.read(decompressedBytes);
gzis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
"Değil GZIP formatında" hata GZIPInputStream tarafından üretilir Sihirli GZIP üstbilgi değerlerini eşleştirin, bu nedenle bunlara yönelik test yapmak, sorununuzu çözmenize yardımcı olur.
Ayrıca, GZIP biçiminde bir CRC sağlama toplamı vardır, ancak eksik veya yanlışsa, farklı bir hata görmeniz gerekir.
Yanıt gövdesinin GZip ile sıkıştırıldığı bir HTTP yanıtını ayrıştırmaya çalışıyorum. Ancak, tüm yanıt basitçe bir dizede saklanır, böylece dizenin bir kısmı ikili karakterler içerir. Bu "GZip dizesini" bir metin dizesine dönüştürmenin mümkün olmadığını mı söylüyorsunuz? – Matt
@Matt: Yanıtın başlanması için bir dizede saklanmamalısınız. İkiliyse, base64 olmadıkça, metinde olmamalıdır. "Dizenin bir kısmı ikili veri içerir" kavramı gerçekten işe yaramıyor. Yaklaşımını değiştirmen gerekiyormuş gibi geliyor. –
Yanıt başlangıçta bir byte [] olarak sunuldu, yani elimdeki tüm bu var. Bunu kullanabilir miyim? – Matt