001package com.box.sdk; 002 003import com.eclipsesource.json.Json; 004import com.eclipsesource.json.JsonObject; 005import com.eclipsesource.json.ParseException; 006import java.io.IOException; 007import java.io.InputStreamReader; 008import java.net.HttpURLConnection; 009import java.util.Map; 010 011/** 012 * Used to read HTTP responses containing JSON from the Box API. 013 * 014 * <p>This request type extends BoxAPIResponse to provide additional functionality for handling JSON strings. It reads 015 * the response body into a string and allows the JSON in the response to be logged.</p> 016 */ 017public class BoxJSONResponse extends BoxAPIResponse { 018 private static final int BUFFER_SIZE = 8192; 019 private JsonObject jsonObject; 020 021 /** 022 * Constructs a BoxJSONResponse without an associated HttpURLConnection. 023 */ 024 public BoxJSONResponse() { 025 super(); 026 } 027 028 /** 029 * Constructs a BoxJSONResponse using an HttpURLConnection. 030 * 031 * @param connection a connection that has already sent a request to the API. 032 */ 033 public BoxJSONResponse(HttpURLConnection connection) { 034 super(connection); 035 } 036 037 /** 038 * Constructs a BoxAPIResponse with an http response code and response body. 039 * 040 * @param responseCode http response code 041 * @param httpHeaders map of http headers 042 * @param body response body as Json Object 043 */ 044 public BoxJSONResponse(int responseCode, Map<String, String> httpHeaders, JsonObject body) { 045 super(responseCode, httpHeaders); 046 this.jsonObject = body; 047 } 048 049 /** 050 * Get response as Json Object. 051 * 052 * @return response as JsonObject 053 */ 054 public JsonObject getJsonObject() { 055 if (this.jsonObject != null) { 056 return this.jsonObject; 057 } else { 058 return Json.parse(this.getJSON()).asObject(); 059 } 060 } 061 062 /** 063 * Gets the body of the response as a JSON string. When this method is called, the response's body will be read and 064 * the response will be disconnected, meaning that the stream returned by {@link #getBody} can no longer be used. 065 * 066 * @return the body of the response as a JSON string. 067 */ 068 public String getJSON() { 069 if (this.jsonObject != null) { 070 return this.jsonObject.toString(); 071 } else { 072 InputStreamReader reader = new InputStreamReader(this.getBody(), StandardCharsets.UTF_8); 073 StringBuilder builder = new StringBuilder(); 074 char[] buffer = new char[BUFFER_SIZE]; 075 076 try { 077 int read = reader.read(buffer, 0, BUFFER_SIZE); 078 while (read != -1) { 079 builder.append(buffer, 0, read); 080 read = reader.read(buffer, 0, BUFFER_SIZE); 081 } 082 083 this.disconnect(); 084 reader.close(); 085 } catch (IOException e) { 086 throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e); 087 } 088 String jsonAsString = builder.toString(); 089 try { 090 this.jsonObject = Json.parse(jsonAsString).asObject(); 091 } catch (ParseException e) { 092 throw new RuntimeException("Error parsing JSON:\n" + jsonAsString, e); 093 } 094 return jsonAsString; 095 } 096 } 097 098 @Override 099 protected String bodyToString() { 100 String bodyString = super.bodyToString(); 101 if (bodyString == null) { 102 return this.getJSON(); 103 } else { 104 return bodyString; 105 } 106 } 107}