У меня есть статический вспомогательный метод, отвечающий за получение сжатой строки JSON из нашего приложения Rails и декомпрессии данных перед возвратом представления String
.GZIPInputStream - поврежденный трейлер GZIP
Я написал два теста JUnit, которые проверяют правильность разбора JSON, и еще один базовый тест, который определяет, возвращается ли строка с длиной больше нуля с сервера.
Проблема: При запуске тестового набора, то первый метод испытания успешно правильно, а другой терпит неудачу с IOException
и сообщением «Corrupt GZIP трейлера» (см код ниже). Я решил, что это не сам тест, который терпит неудачу, так как «успешный» тест отменяется, когда я запускаю тесты в противоположном порядке (другими словами, несмотря ни на что, это всегда второй тест, который терпит неудачу, независимо от того, какой из двух тестов выполняется вторым).
Это вспомогательный метод:
public static String doHTTPGet(String urlString) throws IOException{
URL weatherAPI = new URL(urlString);
HttpURLConnection apiConnection = (HttpURLConnection) weatherAPI.openConnection();
apiConnection.setRequestMethod("GET");
apiConnection.setRequestProperty("Accept-Encoding", "gzip");
apiConnection.connect();
BufferedInputStream bufferedInputStream = new BufferedInputStream(apiConnection.getInputStream());
byte[] inputByteBuffer = new byte[10 * 1024];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(10 * 1024); // initialize the output stream with at least one buffer's worth of bytes
while(bufferedInputStream.read(inputByteBuffer) > -1){
outputStream.write(inputByteBuffer);
}
outputStream.close();
bufferedInputStream.close();
apiConnection.disconnect();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(outputStream.toByteArray());
byteArrayInputStream.close();
GZIPInputStream gis = new GZIPInputStream(byteArrayInputStream);
InputStreamReader inputStreamReader = new InputStreamReader(gis, "UTF-8");
BufferedReader reader = new BufferedReader(inputStreamReader);
String decompressedResponse = "";
String line;
// readLine() is generating the IOException on the second pass.
while((line = reader.readLine()) != null){
decompressedResponse += line;
}
reader.close();
inputStreamReader.close();
gis.close();
return decompressedResponse;
}
Ошибка возникает в направлении нижней части вспомогательного метода, на линии while((line = reader.readLine()) != null)...
. В частности, ошибка возникает на reader.readLine()
.
И методы два испытания:
@Test
public void testHttpGet(){
try {
// FILTERED_API_URL_WITH_TOKEN is merely the URL with an auth token
String apiResponse = HTTPHelper.doHTTPGet(GlobalConstants.FILTERED_API_URL_WITH_TOKEN);
assertNotNull(apiResponse);
assertTrue("The size of the API response should be greater than zero. It is an empty string.", apiResponse.length() > 0);
} catch (IOException e) {
e.printStackTrace();
assertTrue("An exception occured while trying to perform the HTTP Get to the api at URL " + GlobalConstants.FILTERED_API_URL_WITH_TOKEN, false);
}
}
@Test
public void testAPIContent(){
try {
// the getAPIJson() method basically does the same as the testHttpGet
// method, but converts the string to a json
JSONObject jsonObject = XMLProducerFromAPI.getAPIJson();
System.out.println(jsonObject);
assertNotNull(jsonObject);
} catch (IOException e) {
e.printStackTrace();
assertTrue("An IOException occured. See stack trace", false);
} catch (JSONException e) {
e.printStackTrace();
assertTrue("A JSONException occured. See stack trace", false);
}
}
Я прочитал this question и the answer, но я не верю, что его это применимо, (или, может быть, это и я понял, дайте мне знать, если это случай), и я попробовал их подход и получил только одно сообщение.
Поскольку метод doHTTPGet
является статическим, а созданные объекты выполняются таким образом внутри тела метода, ничто (потоки, объекты соединения и т. Д.) Не должно использоваться повторно. Честно говоря, я в тупике.
Вопрос: Я сделал что-то не так в моем вспомогательном коде или неправильно понял какой-либо объект, что даст сообщение «Corrupt GZIP Trailer»? Короче говоря, что может вызвать эту ошибку в моем сценарии?
Как всегда, пожалуйста, дайте мне знать, если я оставил что-либо из этого вопроса.
EDIT
Это трассировки стека:
java.io.IOException: Corrupt GZIP trailer
at java.util.zip.GZIPInputStream.readTrailer(GZIPInputStream.java:200)
at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:92)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at com.weathertx.xmlserver.support.HTTPHelper.doHTTPGet(HTTPHelper.java:60)
at com.weathertx.xmlserver.tests.HttpHelperTest.getAPIResponse(HttpHelperTest.java:47)
at com.weathertx.xmlserver.tests.HttpHelperTest.testHttpGet(HttpHelperTest.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
К сожалению, API, о котором идет речь, ограничен IP, поэтому, к сожалению, я не могу предоставить доступ, не зная IP каждого. –