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