0
# Response Handling
1
2
Comprehensive response handling with status codes, headers, body access, and response chaining for redirects and caching.
3
4
## Capabilities
5
6
### Response
7
8
Immutable HTTP response with status, headers, and body. Body is one-shot value that may be consumed only once.
9
10
```java { .api }
11
/**
12
* An HTTP response. Instances of this class are not immutable: the response
13
* body is a one-shot value that may be consumed only once.
14
*/
15
public final class Response {
16
public Request request();
17
public Protocol protocol();
18
public int code();
19
public boolean isSuccessful();
20
public String message();
21
public Handshake handshake();
22
public List<String> headers(String name);
23
public String header(String name);
24
public String header(String name, String defaultValue);
25
public Headers headers();
26
public ResponseBody body();
27
public Builder newBuilder();
28
public boolean isRedirect();
29
public Response networkResponse();
30
public Response cacheResponse();
31
public Response priorResponse();
32
public List<Challenge> challenges();
33
public CacheControl cacheControl();
34
}
35
```
36
37
**Basic Usage:**
38
39
```java
40
Response response = client.newCall(request).execute();
41
try {
42
if (response.isSuccessful()) {
43
String responseBody = response.body().string();
44
System.out.println("Response: " + responseBody);
45
} else {
46
System.err.println("Request failed: " + response.code() + " " + response.message());
47
}
48
} finally {
49
response.body().close();
50
}
51
```
52
53
### Status Code Handling
54
55
Check response status and handle different HTTP status codes.
56
57
```java { .api }
58
/**
59
* Returns the HTTP status code.
60
* @return the status code (200, 404, 500, etc.)
61
*/
62
public int code();
63
64
/**
65
* Returns true if the code is in [200..300), which means the request was
66
* successfully received, understood, and accepted.
67
* @return true if successful
68
*/
69
public boolean isSuccessful();
70
71
/**
72
* Returns the HTTP status message or null if it is unknown.
73
* @return the status message
74
*/
75
public String message();
76
77
/**
78
* Returns true if this response redirects to another resource.
79
* @return true if this is a redirect response
80
*/
81
public boolean isRedirect();
82
```
83
84
**Usage Examples:**
85
86
```java
87
Response response = client.newCall(request).execute();
88
89
switch (response.code()) {
90
case 200:
91
// Success
92
String data = response.body().string();
93
break;
94
case 401:
95
// Unauthorized
96
System.err.println("Authentication required");
97
break;
98
case 404:
99
// Not found
100
System.err.println("Resource not found");
101
break;
102
case 500:
103
// Server error
104
System.err.println("Server error: " + response.message());
105
break;
106
default:
107
if (response.isSuccessful()) {
108
// Other 2xx codes
109
String data = response.body().string();
110
} else {
111
// Other error codes
112
System.err.println("Request failed: " + response.code());
113
}
114
}
115
116
// Check for redirects
117
if (response.isRedirect()) {
118
String location = response.header("Location");
119
System.out.println("Redirected to: " + location);
120
}
121
```
122
123
### Header Access
124
125
Access response headers with various helper methods.
126
127
```java { .api }
128
/**
129
* Returns all values for the specified header name.
130
* @param name the header name (case-insensitive)
131
* @return list of header values
132
*/
133
public List<String> headers(String name);
134
135
/**
136
* Returns the value of the specified header, or null if not present.
137
* @param name the header name (case-insensitive)
138
* @return the header value or null
139
*/
140
public String header(String name);
141
142
/**
143
* Returns the value of the specified header, or defaultValue if not present.
144
* @param name the header name (case-insensitive)
145
* @param defaultValue the default value to return
146
* @return the header value or defaultValue
147
*/
148
public String header(String name, String defaultValue);
149
150
/**
151
* Returns all response headers.
152
* @return the Headers object
153
*/
154
public Headers headers();
155
```
156
157
**Usage Examples:**
158
159
```java
160
Response response = client.newCall(request).execute();
161
162
// Get single header
163
String contentType = response.header("Content-Type");
164
String contentLength = response.header("Content-Length", "0");
165
166
// Get multiple header values
167
List<String> setCookies = response.headers("Set-Cookie");
168
169
// Access all headers
170
Headers headers = response.headers();
171
for (int i = 0; i < headers.size(); i++) {
172
System.out.println(headers.name(i) + ": " + headers.value(i));
173
}
174
175
// Check specific headers
176
String server = response.header("Server");
177
String lastModified = response.header("Last-Modified");
178
String etag = response.header("ETag");
179
```
180
181
### Response Body Access
182
183
Access response body using various methods with proper resource management.
184
185
```java { .api }
186
/**
187
* Returns the response body.
188
* @return the ResponseBody (must be closed after use)
189
*/
190
public ResponseBody body();
191
```
192
193
**Usage Examples:**
194
195
```java
196
Response response = client.newCall(request).execute();
197
try {
198
ResponseBody body = response.body();
199
200
// Get as string (consumes the body)
201
String content = body.string();
202
203
// Alternative: Get as bytes
204
// byte[] bytes = body.bytes();
205
206
// Alternative: Get as InputStream
207
// InputStream inputStream = body.byteStream();
208
209
// Alternative: Get as Reader
210
// Reader reader = body.charStream();
211
212
// Get content type and length
213
MediaType contentType = body.contentType();
214
long contentLength = body.contentLength();
215
216
} finally {
217
response.body().close(); // Important: always close
218
}
219
```
220
221
### Protocol Information
222
223
Get information about the HTTP protocol used for the response.
224
225
```java { .api }
226
/**
227
* Returns the HTTP protocol, such as Protocol.HTTP_1_1 or Protocol.HTTP_2.
228
* @return the Protocol used
229
*/
230
public Protocol protocol();
231
```
232
233
**Usage Examples:**
234
235
```java
236
Response response = client.newCall(request).execute();
237
Protocol protocol = response.protocol();
238
239
switch (protocol) {
240
case HTTP_1_0:
241
System.out.println("Using HTTP/1.0");
242
break;
243
case HTTP_1_1:
244
System.out.println("Using HTTP/1.1");
245
break;
246
case SPDY_3:
247
System.out.println("Using SPDY/3.1");
248
break;
249
case HTTP_2:
250
System.out.println("Using HTTP/2");
251
break;
252
}
253
```
254
255
### TLS Handshake Information
256
257
Access TLS handshake information for HTTPS responses.
258
259
```java { .api }
260
/**
261
* Returns the TLS handshake of the connection that carried this response,
262
* or null if the response was received without TLS.
263
* @return the Handshake or null
264
*/
265
public Handshake handshake();
266
```
267
268
**Usage Examples:**
269
270
```java
271
Response response = client.newCall(request).execute();
272
Handshake handshake = response.handshake();
273
274
if (handshake != null) {
275
// HTTPS connection
276
String cipherSuite = handshake.cipherSuite();
277
List<Certificate> peerCerts = handshake.peerCertificates();
278
List<Certificate> localCerts = handshake.localCertificates();
279
280
System.out.println("Cipher Suite: " + cipherSuite);
281
System.out.println("Peer Certificates: " + peerCerts.size());
282
} else {
283
// HTTP connection
284
System.out.println("No TLS handshake (HTTP connection)");
285
}
286
```
287
288
### Request Information
289
290
Access the original request that generated this response.
291
292
```java { .api }
293
/**
294
* The wire-level request that initiated this HTTP response. This is not
295
* necessarily the same request issued by the application.
296
* @return the Request
297
*/
298
public Request request();
299
```
300
301
**Usage Examples:**
302
303
```java
304
Response response = client.newCall(request).execute();
305
Request originalRequest = response.request();
306
307
// Compare original vs final request (after redirects/auth)
308
System.out.println("Original URL: " + request.urlString());
309
System.out.println("Final URL: " + originalRequest.urlString());
310
311
// Check if request was modified
312
if (!request.urlString().equals(originalRequest.urlString())) {
313
System.out.println("Request was redirected");
314
}
315
```
316
317
### Response Chain Information
318
319
Access information about response chains from redirects and caching.
320
321
```java { .api }
322
/**
323
* Returns the raw response received from the network. Will be null if this
324
* response didn't use the network, such as when the response is fully cached.
325
* @return the network Response or null
326
*/
327
public Response networkResponse();
328
329
/**
330
* Returns the raw response received from the cache. Will be null if this
331
* response didn't use the cache.
332
* @return the cache Response or null
333
*/
334
public Response cacheResponse();
335
336
/**
337
* Returns the response for the HTTP redirect or authorization challenge that
338
* triggered this response, or null if this response wasn't triggered by an
339
* automatic retry.
340
* @return the prior Response or null
341
*/
342
public Response priorResponse();
343
```
344
345
**Usage Examples:**
346
347
```java
348
Response response = client.newCall(request).execute();
349
350
// Check if response came from cache
351
Response cacheResponse = response.cacheResponse();
352
Response networkResponse = response.networkResponse();
353
354
if (cacheResponse != null && networkResponse == null) {
355
System.out.println("Response served from cache");
356
} else if (cacheResponse == null && networkResponse != null) {
357
System.out.println("Response served from network");
358
} else if (cacheResponse != null && networkResponse != null) {
359
System.out.println("Conditional request: cache validated with network");
360
}
361
362
// Check redirect chain
363
Response prior = response.priorResponse();
364
int redirectCount = 0;
365
while (prior != null) {
366
redirectCount++;
367
System.out.println("Redirect " + redirectCount + ": " + prior.request().urlString());
368
prior = prior.priorResponse();
369
}
370
```
371
372
### Authentication Challenges
373
374
Handle authentication challenges from 401/407 responses.
375
376
```java { .api }
377
/**
378
* Returns the authorization challenges appropriate for this response's code.
379
* If the response code is 401 unauthorized, this returns the
380
* "WWW-Authenticate" challenges. If the response code is 407 proxy
381
* unauthorized, this returns the "Proxy-Authenticate" challenges.
382
* @return list of Challenge objects
383
*/
384
public List<Challenge> challenges();
385
```
386
387
**Usage Examples:**
388
389
```java
390
Response response = client.newCall(request).execute();
391
392
if (response.code() == 401 || response.code() == 407) {
393
List<Challenge> challenges = response.challenges();
394
for (Challenge challenge : challenges) {
395
String scheme = challenge.getScheme();
396
String realm = challenge.getRealm();
397
System.out.println("Auth challenge: " + scheme + " realm=" + realm);
398
399
if ("Basic".equalsIgnoreCase(scheme)) {
400
// Handle Basic authentication
401
String credentials = Credentials.basic("username", "password");
402
// Retry request with credentials...
403
}
404
}
405
}
406
```
407
408
### Cache Control
409
410
Access cache control directives from the response.
411
412
```java { .api }
413
/**
414
* Returns the cache control directives for this response. This is never null,
415
* even if this response contains no Cache-Control header.
416
* @return the CacheControl object
417
*/
418
public CacheControl cacheControl();
419
```
420
421
**Usage Examples:**
422
423
```java
424
Response response = client.newCall(request).execute();
425
CacheControl cacheControl = response.cacheControl();
426
427
// Check cache directives
428
if (cacheControl.noCache()) {
429
System.out.println("Response should not be cached");
430
}
431
if (cacheControl.noStore()) {
432
System.out.println("Response should not be stored");
433
}
434
435
int maxAge = cacheControl.maxAgeSeconds();
436
if (maxAge != -1) {
437
System.out.println("Response valid for " + maxAge + " seconds");
438
}
439
```
440
441
### Response Builder
442
443
Create modified responses using the builder pattern.
444
445
```java { .api }
446
/**
447
* Returns a new Builder based on this response.
448
* @return a new Builder with this response's configuration
449
*/
450
public Builder newBuilder();
451
```
452
453
**Usage Examples:**
454
455
```java
456
Response originalResponse = client.newCall(request).execute();
457
458
// Create modified response (e.g., in an interceptor)
459
Response modifiedResponse = originalResponse.newBuilder()
460
.header("Custom-Header", "Custom-Value")
461
.build();
462
463
// Note: This is typically used in interceptors to modify responses
464
```