简体   繁体   中英

How to resolve: java.util.zip.ZipException: Not in GZIP format

Line InputStream is = new GZIPInputStream (con.getInputStream ()); returns this "java.util.zip.ZipException: Not in GZIP format" exception. Does anyone know how to solve this?

my code:

private String getJsonFromRapidAPI(final String url) throws Exception {

        final String token = generateSessionToken();
        final HttpClient httpclient = new DefaultHttpClient();
        final HttpGet httpget = new HttpGet(url);

        String fileContents = null;
        StringBuilder sb = new StringBuilder();
        BufferedReader in = null;

        if (inetAddress == null) {
            inetAddress = InetAddress.getLocalHost();
        }

        final String serverIP = inetAddress.getHostAddress();

        URL urlToCall = new URL(url);
        HttpURLConnection con = (HttpURLConnection) urlToCall.openConnection();
        con.setRequestProperty("Accept", "application/json");
        con.setRequestProperty("Accept-Encoding", "gzip");
        con.setRequestProperty("Authorization", token);
        con.setRequestProperty("Customer-Ip", serverIP);
        con.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");

        InputStream is = new GZIPInputStream(con.getInputStream());

        StringWriter writer = new StringWriter();
        IOUtils.copy(is, writer, "UTF-8");

        return writer.toString();

    }

Two issues here:

  • You can tell a server you want GZIP encoding. That doesn't mean it'll neccessarily comply.

As a consequence, your current code goes: Well, I asked for gzip, so I will assume i Must gunzip the stream. That's incorrect - you need to ask for gzip as you do, but you need to let 'should I GZipInputStream the response' depend on whether the server actually did that. To figure this out, use con.connect to actually connect ( .getInputStream implies it, but now we need to fetch some response info before opening the inputstream so you need to explicitly connect now), and you can call ."gzip".equals(con.getContentEncoding()) to figure it out. If that is true , then wrap con.getInputStream() in GZIPInputStream. If it isn't, don't do that.

  • More generally you're abusing HttpURLConnection.

HttpURLConnection's job is to deal with the stream/processing of the data itself. That means headers like Transfer-Encoding , Host , and Accept-Encoding aren't 'your turf', you shouldn't be messing with this stuff. It needs to send 'hey, I can support gzip!' and it needs to wrap the response in a GZIPInputStream if the server says: "Great, okay, therefore I gzipped it for you.".

Unfortunately HttpURLConnection is extremely basic and messes up this distinction itself, for example it looks at the Transfer-Encoding header you set and will chunk sends (I think - oof, I haven't used this class in forever because its so bad).

If you have needs to make things even slightly complicated (and I'd say this qualifies), then stop using it. There's OkHttp from square. Java itself (Available in JDK11 and up, I think) calls HttpURLConnection obsolete and has replaced it - here is a tutorial , and even apache has HttpComponents but note that this is outdated and as with most apache java libraries, oof, it's bad API design. I wouldn't use that one, even if it is rather popular. It's still much better than HttpURLConnection though!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM