0
# Response Handling
1
2
The Response class provides multiple ways to consume HTTP response content with automatic resource management. Each response can only be consumed once.
3
4
## Response Consumption Methods
5
6
The Response class offers several methods to consume response content:
7
8
```java { .api }
9
public Content returnContent() throws ClientProtocolException, IOException;
10
public HttpResponse returnResponse() throws IOException;
11
public void saveContent(File file) throws IOException;
12
public void discardContent();
13
public <T> T handleResponse(ResponseHandler<T> handler) throws ClientProtocolException, IOException;
14
```
15
16
### Content Access
17
18
Get response content as a reusable Content object:
19
20
```java
21
import org.apache.http.client.fluent.Request;
22
import org.apache.http.client.fluent.Content;
23
24
// Get content as Content object
25
Content content = Request.Get("https://api.example.com/data")
26
.execute()
27
.returnContent();
28
29
// Access content in multiple ways
30
String text = content.asString();
31
byte[] bytes = content.asBytes();
32
InputStream stream = content.asStream();
33
```
34
35
### Direct HttpResponse Access
36
37
Get the underlying HttpResponse for advanced processing:
38
39
```java
40
import org.apache.http.HttpResponse;
41
import org.apache.http.StatusLine;
42
import org.apache.http.Header;
43
44
HttpResponse response = Request.Get("https://api.example.com/data")
45
.execute()
46
.returnResponse();
47
48
// Access response metadata
49
StatusLine statusLine = response.getStatusLine();
50
int statusCode = statusLine.getStatusCode();
51
String reasonPhrase = statusLine.getReasonPhrase();
52
53
// Access headers
54
Header[] headers = response.getAllHeaders();
55
Header contentType = response.getFirstHeader("Content-Type");
56
```
57
58
### Save to File
59
60
Save response content directly to a file:
61
62
```java
63
import java.io.File;
64
65
File outputFile = new File("/path/to/output.txt");
66
67
Request.Get("https://api.example.com/download")
68
.execute()
69
.saveContent(outputFile);
70
```
71
72
The `saveContent` method:
73
- Throws `HttpResponseException` for HTTP error status codes (>= 300)
74
- Automatically closes file streams
75
- Marks response as consumed
76
77
### Discard Content
78
79
Discard response content without processing (useful for HEAD requests or when only status matters):
80
81
```java
82
Request.Head("https://api.example.com/check")
83
.execute()
84
.discardContent();
85
```
86
87
### Custom Response Handlers
88
89
Process responses with custom logic using ResponseHandler:
90
91
```java
92
import org.apache.http.client.ResponseHandler;
93
import org.apache.http.HttpResponse;
94
import org.apache.http.util.EntityUtils;
95
96
// Custom handler to extract specific header
97
ResponseHandler<String> headerHandler = new ResponseHandler<String>() {
98
@Override
99
public String handleResponse(HttpResponse response) throws IOException {
100
Header locationHeader = response.getFirstHeader("Location");
101
return locationHeader != null ? locationHeader.getValue() : null;
102
}
103
};
104
105
String location = Request.Post("https://api.example.com/create")
106
.bodyString("{\"name\":\"test\"}", ContentType.APPLICATION_JSON)
107
.execute()
108
.handleResponse(headerHandler);
109
110
// Custom handler to parse JSON (example with manual parsing)
111
ResponseHandler<Map<String, Object>> jsonHandler = new ResponseHandler<Map<String, Object>>() {
112
@Override
113
public Map<String, Object> handleResponse(HttpResponse response) throws IOException {
114
String json = EntityUtils.toString(response.getEntity());
115
// Parse JSON manually or with your preferred JSON library
116
// This is just a placeholder example
117
return parseJson(json);
118
}
119
};
120
```
121
122
## Content Class
123
124
The Content class provides a reusable container for response data:
125
126
```java { .api }
127
public class Content {
128
public static final Content NO_CONTENT;
129
130
public Content(byte[] raw, ContentType type);
131
public ContentType getType();
132
public byte[] asBytes();
133
public String asString();
134
public String asString(Charset charset);
135
public InputStream asStream();
136
public String toString();
137
}
138
```
139
140
### Content Usage Examples
141
142
```java
143
import org.apache.http.entity.ContentType;
144
import java.nio.charset.StandardCharsets;
145
146
Content content = Request.Get("https://api.example.com/data")
147
.execute()
148
.returnContent();
149
150
// Get content type information
151
ContentType contentType = content.getType();
152
String mimeType = contentType.getMimeType();
153
Charset charset = contentType.getCharset();
154
155
// Access content as different types
156
byte[] rawBytes = content.asBytes();
157
String defaultString = content.asString();
158
String utf8String = content.asString(StandardCharsets.UTF_8);
159
InputStream stream = content.asStream();
160
161
// Content is reusable
162
String copy1 = content.asString();
163
String copy2 = content.asString(); // Same content, multiple accesses allowed
164
165
// Empty content constant
166
Content empty = Content.NO_CONTENT;
167
```
168
169
## ContentResponseHandler
170
171
A built-in ResponseHandler implementation that converts HttpResponse messages to Content instances. This class is used internally by the fluent API but can also be used directly for custom response processing.
172
173
```java { .api }
174
public class ContentResponseHandler extends AbstractResponseHandler<Content> {
175
public ContentResponseHandler();
176
public Content handleEntity(HttpEntity entity) throws IOException;
177
}
178
```
179
180
### Usage Examples
181
182
The ContentResponseHandler is used internally by `returnContent()` but can be used explicitly:
183
184
```java
185
import org.apache.http.client.fluent.ContentResponseHandler;
186
187
// Explicit usage
188
Content content = Request.Get("https://api.example.com/data")
189
.execute()
190
.handleResponse(new ContentResponseHandler());
191
192
// Equivalent to returnContent()
193
Content sameContent = Request.Get("https://api.example.com/data")
194
.execute()
195
.returnContent();
196
```
197
198
### Custom Response Processing
199
200
Use ContentResponseHandler with Async operations:
201
202
```java
203
import org.apache.http.client.fluent.Async;
204
import org.apache.http.client.fluent.ContentResponseHandler;
205
import java.util.concurrent.Future;
206
207
Async async = Async.newInstance();
208
209
// Use ContentResponseHandler explicitly in async operations
210
Future<Content> future = async.execute(
211
Request.Get("https://api.example.com/data"),
212
new ContentResponseHandler()
213
);
214
215
Content content = future.get();
216
String response = content.asString();
217
```
218
219
### Error Handling
220
221
ContentResponseHandler automatically handles HTTP error status codes and entity processing:
222
223
```java
224
try {
225
ContentResponseHandler handler = new ContentResponseHandler();
226
Content content = Request.Get("https://api.example.com/data")
227
.execute()
228
.handleResponse(handler);
229
230
System.out.println("Response: " + content.asString());
231
} catch (HttpResponseException e) {
232
System.err.println("HTTP error " + e.getStatusCode() + ": " + e.getMessage());
233
} catch (IOException e) {
234
System.err.println("I/O error: " + e.getMessage());
235
}
236
```
237
238
## Response State Management
239
240
Each Response object can only be consumed once. After calling any consumption method, the response is marked as consumed:
241
242
```java
243
Response response = Request.Get("https://api.example.com/data").execute();
244
245
// First consumption - works
246
Content content = response.returnContent();
247
248
// Second consumption - throws IllegalStateException
249
try {
250
response.returnResponse(); // This will fail
251
} catch (IllegalStateException e) {
252
System.err.println("Response already consumed: " + e.getMessage());
253
}
254
```
255
256
## Error Handling
257
258
Response handling methods can throw:
259
260
- `ClientProtocolException` - For HTTP protocol errors
261
- `IOException` - For I/O errors during response processing
262
- `HttpResponseException` - For HTTP error status codes (thrown by `saveContent()`)
263
- `IllegalStateException` - For attempts to consume already-consumed responses
264
265
### Error Handling Examples
266
267
```java
268
import org.apache.http.client.ClientProtocolException;
269
import org.apache.http.client.HttpResponseException;
270
271
try {
272
Content content = Request.Get("https://api.example.com/data")
273
.execute()
274
.returnContent();
275
276
String data = content.asString();
277
System.out.println("Response: " + data);
278
279
} catch (ClientProtocolException e) {
280
System.err.println("Protocol error: " + e.getMessage());
281
} catch (IOException e) {
282
System.err.println("I/O error: " + e.getMessage());
283
}
284
285
// Handling HTTP error status codes with saveContent
286
try {
287
Request.Get("https://api.example.com/nonexistent")
288
.execute()
289
.saveContent(new File("output.txt"));
290
} catch (HttpResponseException e) {
291
System.err.println("HTTP error " + e.getStatusCode() + ": " + e.getMessage());
292
}
293
```
294
295
## Best Practices
296
297
1. **Choose the right consumption method**: Use `returnContent()` for text/JSON responses, `saveContent()` for file downloads, `discardContent()` when you only need status
298
2. **Handle HTTP error codes**: Check status codes when using `returnResponse()` or catch `HttpResponseException` with `saveContent()`
299
3. **Process responses quickly**: Don't hold Response objects for long periods as they tie up connection pool resources
300
4. **Use Content for caching**: Content objects are thread-safe and can be cached/reused unlike Response objects