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.util.List; 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 BoxJSONResponse(BoxAPIResponse response) { 029 this( 030 response.getResponseCode(), 031 response.getRequestMethod(), 032 response.getRequestUrl(), 033 response.getHeaders(), 034 new JsonObject() 035 ); 036 } 037 038 /** 039 * Constructs a BoxAPIResponse with an http response code and response body. 040 * 041 * @param responseCode http response code 042 * @param headers map of http headers 043 * @param body response body as Json Object 044 */ 045 public BoxJSONResponse(int responseCode, 046 String requestMethod, 047 String requestUrl, 048 Map<String, List<String>> headers, 049 JsonObject body 050 ) { 051 super(responseCode, requestMethod, requestUrl, headers); 052 this.jsonObject = body; 053 } 054 055 /** 056 * Get response as Json Object. 057 * 058 * @return response as JsonObject 059 */ 060 public JsonObject getJsonObject() { 061 if (this.jsonObject != null) { 062 return this.jsonObject; 063 } else { 064 return Json.parse(this.getJSON()).asObject(); 065 } 066 } 067 068 /** 069 * Gets the body of the response as a JSON string. When this method is called, the response's body will be read and 070 * the response will be disconnected, meaning that the stream returned by {@link #getBody} can no longer be used. 071 * 072 * @return the body of the response as a JSON string. 073 */ 074 public String getJSON() { 075 if (this.jsonObject != null) { 076 return this.jsonObject.toString(); 077 } else if (this.getBody() == null) { 078 return null; 079 } else { 080 InputStreamReader reader = new InputStreamReader(this.getBody(), StandardCharsets.UTF_8); 081 StringBuilder builder = new StringBuilder(); 082 char[] buffer = new char[BUFFER_SIZE]; 083 084 try { 085 int read = reader.read(buffer, 0, BUFFER_SIZE); 086 while (read != -1) { 087 builder.append(buffer, 0, read); 088 read = reader.read(buffer, 0, BUFFER_SIZE); 089 } 090 091 this.close(); 092 reader.close(); 093 } catch (IOException e) { 094 throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e); 095 } 096 String jsonAsString = builder.toString(); 097 try { 098 this.jsonObject = Json.parse(jsonAsString).asObject(); 099 } catch (ParseException e) { 100 throw new RuntimeException("Error parsing JSON:\n" + jsonAsString, e); 101 } 102 return jsonAsString; 103 } 104 } 105 106 @Override 107 protected String bodyToString() { 108 String bodyString = super.bodyToString(); 109 if (bodyString == null) { 110 return this.getJSON(); 111 } else { 112 return bodyString; 113 } 114 } 115}