当我尝试使用okhttp进行HTTP调用时,出现以下错误:
W/System.err: java.io.EOFException: source exhausted prematurely
W/System.err: at okio.InflaterSource.read(InflaterSource.java:83)
W/System.err: at okio.GzipSource.read(GzipSource.java:80)
W/System.err: at okio.Buffer.writeAll(Buffer.java:1135)
W/System.err: at okio.RealBufferedSource.readString(RealBufferedSource.java:199)
W/System.err: at okhttp3.ResponseBody.string(ResponseBody.java:176)
W/System.err: at com.ethanwang.andplay.OKHttpTaskTag.doInBackground(OKHttpTaskTag.java:41)
W/System.err: at com.ethanwang.andplay.OKHttpTaskTag.doInBackground(OKHttpTaskTag.java:20)
W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:295)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
W/System.err: at java.lang.Thread.run(Thread.java:818)
我只能找到以下相关问题:https://github.com/square/okhttp/issues/2193,但是我已经确保Content-Length
是响应正文的正确长度。这是我记录的okhttp请求和响应:
请求:
I/System.out: INFO: Sending request http://test.essaybot.com/msg/tag_search on Connection{test.essaybot.com:80, proxy=DIRECT@ hostAddress=test.essaybot.com/34.208.145.50:80 cipherSuite=none protocol=http/1.1}
I/System.out: Content-Type: application/x-www-form-urlencoded
I/System.out: Content-Length: 33
I/System.out: Host: test.essaybot.com
I/System.out: Connection: Keep-Alive
I/System.out: Accept-Encoding: gzip
I/System.out: User-Agent: okhttp/3.11.0
响应:
I/System.out: INFO: Received response for http://test.essaybot.com/msg/tag_search in 62.2ms
I/System.out: Cache-Control: no-cache
I/System.out: Content-Encoding: gzip
I/System.out: Content-Length: 139
I/System.out: Content-Type: application/json
I/System.out: Set-Cookie: PHP_SESSION=0Q4rZJplDjrUNB4ZbWAG; Path=/; Max-Age=2592000
I/System.out: Set-Cookie: VISITOR_ID=65xGr53M1xM0waK8; Path=/; Max-Age=31536000
I/System.out: Date: Wed, 29 Aug 2018 20:45:06 GMT
I/System.out: INFO: Received response body bytes:
I/System.out: [31, -117, 8, 0, 0, 0, 0, 0, 0, -1, 44, -51, 65, 10, -62, 64, 12, 5, -48, -85, 72, -42, 93, -72, -18, -50, -91, 103, 16, -111, -23, 52, -83, 31, 66, -90, 100, 50, -94, -120, 119, -105, 116, -70, 9, 47, -16, -109, -1, 37, 54, 123, 104, -95, -15, 60, -112, 113, 109, -30, 52, -34, -24, 50, -65, 88, -67, 25, -45, 16, 70, -34, 97, 30, 115, 49, -28, 20, -128, 9, -108, 107, 80, -33, 96, -1, -12, 12, 22, 100, 36, 57, 93, -43, 89, 4, 43, 107, -65, -34, -74, 61, 58, -49, -56, -114, -94, -31, 86, -35, -110, -32, -8, 54, -23, 20, 88, -95, 107, -81, 101, 115, -44, 99, -109, 92, -98, 69, 66, 21, -119, -18, -65, 63, 0, 0, 0, -1, -1]
I/System.out: With length: 139
该服务器在我们的Web和iOS端均可正常运行。直到大约两个月前,它在没有网络更改的情况下突然停止工作时,在android上也可以正常工作。还有什么可能导致此错误?
--------------------------------------更新了-------- ------------------------------
似乎缓冲区中的数据是可读的,因为从上面的调试器中,在缓冲区变量之后标注了可读的文本([size=185 text={"err_no":0,"result":["Adventure","Advice","Art","Africa","Airli…]
)。另外,来自调试器的数据与记录的数据不同:
data = {byte[8192]@4418}
0 = 123
1 = 34
2 = 101
3 = 114
4 = 114
5 = 95
6 = 110
7 = 111
8 = 34
9 = 58
10 = 48
11 = 44
12 = 34
13 = 114
14 = 101
15 = 115
16 = 117
17 = 108
18 = 116
19 = 34
20 = 58
21 = 91
22 = 34
23 = 65
24 = 100
25 = 118
26 = 101
27 = 110
28 = 116
29 = 117
30 = 114
31 = 101
32 = 34
33 = 44
34 = 34
35 = 65
36 = 100
37 = 118
38 = 105
39 = 99
40 = 101
41 = 34
42 = 44
43 = 34
44 = 65
45 = 114
46 = 116
47 = 34
48 = 44
49 = 34
50 = 65
51 = 102
52 = 114
53 = 105
54 = 99
55 = 97
56 = 34
57 = 44
58 = 34
59 = 65
60 = 105
61 = 114
62 = 108
63 = 105
64 = 110
65 = 101
66 = 115
67 = 34
68 = 44
69 = 34
70 = 65
71 = 110
72 = 120
73 = 105
74 = 101
75 = 116
76 = 121
77 = 34
78 = 44
79 = 34
80 = 65
81 = 114
82 = 116
83 = 105
84 = 102
85 = 105
86 = 99
87 = 105
88 = 97
89 = 108
90 = 32
91 = 73
92 = 110
93 = 116
94 = 101
95 = 108
96 = 108
97 = 105
98 = 103
99 = 101
100 = 110
101 = 99
102 = 101
103 = 34
104 = 44
105 = 34
106 = 65
107 = 112
108 = 112
109 = 115
110 = 34
111 = 44
112 = 34
113 = 65
114 = 100
115 = 100
116 = 105
117 = 99
118 = 116
119 = 105
120 = 111
121 = 110
122 = 34
123 = 44
124 = 34
125 = 65
126 = 117
127 = 115
128 = 116
129 = 114
130 = 97
131 = 108
132 = 105
133 = 97
134 = 34
135 = 44
136 = 34
137 = 65
138 = 105
139 = 114
140 = 98
141 = 110
142 = 98
143 = 34
144 = 44
145 = 34
146 = 65
147 = 103
148 = 105
149 = 110
150 = 103
151 = 34
152 = 44
153 = 34
154 = 65
155 = 100
156 = 118
157 = 101
158 = 114
159 = 116
160 = 105
161 = 115
162 = 105
163 = 110
164 = 103
165 = 34
166 = 44
167 = 34
168 = 65
169 = 108
170 = 99
171 = 111
172 = 104
173 = 111
174 = 108
175 = 34
176 = 44
177 = 34
178 = 65
179 = 115
180 = 105
181 = 97
182 = 34
183 = 93
184 = 125
185 = 0
186 = 0
187 = 0
188 = 0
189 = 0
190 = 0
191 = 0
192 = 0
193 = 0
194 = 0
195 = 0
196 = 0
197 = 0
198 = 0
199 = 0
-----------------------更新----------------------- -
我使用调试器来跟踪问题,并且好像压缩后的响应被解压缩了两次。如所附图片所示,InflaterSource.java中的读取被调用两次。异常是在第二次被解压缩时抛出的。
答案 0 :(得分:2)
服务器数据已损坏。应该包含一个gzip预告片以指示流的结尾,并且丢失了。
答案 1 :(得分:0)
您可以使用此代码获取输入流。我希望它对您有用。
private static String getResponseString(Response response) {
try {
InputStream inputStream;
String contentEncodingHeader = response.header("Content-Encoding");
if (contentEncodingHeader != null && contentEncodingHeader.equals("gzip")) {
// Read the zipped contents.
inputStream = new GZIPInputStream(response.body().byteStream());
} else {
// Read the normal contents.
inputStream = response.body().byteStream();
}
// Create and return buffered reader.
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
// Read stream.
StringBuilder sb = new StringBuilder("");
String line;
while ((line = br.readLine()) != null) {
sb.append(line.trim());
}
// Close everything.
response.body().close();
inputStream.close();
br.close();
return sb.toString();
} catch (IOException e) {
return "";
}
}
答案 2 :(得分:0)
我在对随机网站的改装GET请求中遇到此错误,
@Headers("Accept-Encoding: identity")
进行修复。
身份 指示身份功能(即无压缩或修改)。即使不存在该值,也始终被认为是可以接受的。