Idéalement, vous devriez utiliser une bibliothèque de haut niveau pour gérer ce genre de choses pour vous. De cette façon, chaque fois qu'une nouvelle version de HTTP est publiée, le mainteneur de la bibliothèque fait tout le travail pour vous et vous avez juste besoin de la version mise à jour de la bibliothèque. Cela dit, c'est un bon exercice que d'essayer de le faire soi-même.
laisse supposer que vous lisez une réponse HTTP comme un flux d'octets à partir d'un socket TCP. S'il n'y avait pas d'encodage gzip, mettre toute la réponse dans une chaîne pouvait fonctionner. Cependant, la présence d'un en-tête "Content-Encoding: gzip" signifie que le corps de la réponse sera (comme vous l'avez noté) binaire.
Vous pouvez identifier le début du corps de la réponse comme le premier octet suivant la première occurrence de la séquence de chaînes "\ r \ n \ r \ n" (ou les 4 octets 0x0d, 0x0a, 0x0d, 0x0a).
L'encodage gzip a un en-tête spécial, et vous devez tester les 3 premiers octets du corps pour que:
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();
}
}
L'erreur « Non au format gzip » est produit par GZIPInputStream si les 3 premiers octets ne le font pas correspondre aux valeurs d'en-tête GZIP magiques, donc le test pour ceux-ci aidera à résoudre votre problème particulier.
Il y a aussi une somme de contrôle CRC dans le format GZIP, cependant si cela est manquant ou incorrect, vous devriez voir une erreur différente.
J'essaye d'analyser une réponse HTTP où le corps de la réponse est compressé avec GZip. Cependant, la réponse entière est simplement stockée dans une chaîne, donc une partie de la chaîne contient des caractères binaires. Êtes-vous en train de dire qu'il n'est pas possible de convertir cette "chaîne GZip" en une chaîne de texte? – Matt
@Matt: Vous ne devriez pas stocker la réponse dans une chaîne pour commencer. Si c'est binaire, il ne devrait pas être dans du texte, sauf s'il s'agit de base64. Le concept de "partie de la chaîne contient des données binaires" ne fonctionne vraiment pas. On dirait que vous devez changer votre approche. –
La réponse est initialement présentée comme un octet [], c'est tout ce que j'ai à disposition. Puis-je l'utiliser? – Matt