or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-execution.mdauthentication-security.mdcaching.mdconnection-management.mdform-data-multipart.mdhttp-client.mdhttp-utilities.mdindex.mdinterceptors.mdrequest-building.mdrequest-response-bodies.mdresponse-handling.md

response-handling.mddocs/

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

```