JsonResponseHandler implements ResponseHandler<T, RuntimeException> { @Override @SuppressFBWarnings("VA_FORMAT_STRING_USES_NEWLINE") public T handle(Request request, Response response) { if (!successfulResponseCodes.contains(response.getStatusCode())) { throw new UnexpectedResponseException( String.format("Expected response code to be %s, but was %d: %s", successfulResponseCodes, response.getStatusCode(), response.getStatusMessage()), request, response); } String contentType = response.getHeader(CONTENT_TYPE); if (contentType == null) { throw new UnexpectedResponseException("Content-Type is not set for response", request, response); } if (!MediaType.parse(contentType).is(MEDIA_TYPE_JSON)) { throw new UnexpectedResponseException("Expected application/json response from server but got " + contentType, request, response); } byte[] bytes; try { bytes = ByteStreams.toByteArray(response.getInputStream()); } catch (IOException e) { throw new RuntimeException("Error reading JSON response from server", e); } try { return jsonCodec.fromJson(bytes); } catch (IllegalArgumentException e) { String json = new String(bytes, UTF_8); throw new IllegalArgumentException(String.format("Unable to create %s from JSON response:\n[%s]", jsonCodec.getType(), json), e); } } private  JsonResponseHandler(JsonCodec<T> jsonCodec); private  JsonResponseHandler(JsonCodec<T> jsonCodec, int firstSuccessfulResponseCode, int... otherSuccessfulResponseCodes); static JsonResponseHandler<T> createJsonResponseHandler(JsonCodec<T> jsonCodec); static JsonResponseHandler<T> createJsonResponseHandler(JsonCodec<T> jsonCodec, int firstSuccessfulResponseCode, int... otherSuccessfulResponseCodes); @Override T handleException(Request request, Exception exception); @Override @SuppressFBWarnings("VA_FORMAT_STRING_USES_NEWLINE") T handle(Request request, Response response);  }
@Test public void testValidJson() { User user = new User("Joe", 25); User response = handler.handle(null, mockResponse().jsonBody(user).build()); assertEquals(response.getName(), user.getName()); assertEquals(response.getAge(), user.getAge()); }
@Test public void testInvalidJson() { String json = "{\"age\": \"foo\"}"; try { handler.handle(null, mockResponse().contentType(JSON_UTF_8).body(json).build()); } catch (IllegalArgumentException e) { assertEquals(e.getMessage(), format("Unable to create %s from JSON response:\n[%s]", User.class, json)); assertInstanceOf(e.getCause(), IllegalArgumentException.class); assertEquals(e.getCause().getMessage(), "Invalid JSON bytes for [simple type, class com.proofpoint.http.client.TestFullJsonResponseHandler$User]"); } }
@Test(expectedExceptions = UnexpectedResponseException.class, expectedExceptionsMessageRegExp = "Expected application/json response from server but got text/plain; charset=utf-8") public void testNonJsonResponse() { handler.handle(null, mockResponse() .contentType(PLAIN_TEXT_UTF_8) .body("hello") .build()); }
@Test(expectedExceptions = UnexpectedResponseException.class, expectedExceptionsMessageRegExp = "Content-Type is not set for response") public void testMissingContentType() { handler.handle(null, mockResponse().body("hello").build()); }
@Test(expectedExceptions = UnexpectedResponseException.class) public void testJsonErrorResponse() { String json = "{\"error\": true}"; handler.handle(null, mockResponse() .status(INTERNAL_SERVER_ERROR) .contentType(JSON_UTF_8) .body(json) .build()); }
@Test public void testJsonReadException() throws IOException { InputStream inputStream = mock(InputStream.class); IOException expectedException = new IOException("test exception"); when(inputStream.read()).thenThrow(expectedException); when(inputStream.read(any(byte[].class))).thenThrow(expectedException); when(inputStream.read(any(byte[].class), anyInt(), anyInt())).thenThrow(expectedException); try { handler.handle(null, mockResponse() .contentType(JSON_UTF_8) .body(inputStream) .build()); fail("expected exception"); } catch (RuntimeException e) { assertEquals(e.getMessage(), "Error reading JSON response from server"); assertSame(e.getCause(), expectedException); } }