To ensure that special characters like "\n", "\t", etc are preserved in the request json body, convert the json string into object.

This commit is contained in:
Trisha Anand 2020-04-03 14:27:10 +00:00 committed by Shrikant Kandula
parent 742f5a194f
commit 5911234276
2 changed files with 37 additions and 9 deletions

View File

@ -70,6 +70,11 @@
<version>2.9.8</version> <version>2.9.8</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
</dependencies> </dependencies>

View File

@ -10,6 +10,7 @@ import com.appsmith.external.plugins.BasePlugin;
import com.appsmith.external.plugins.PluginExecutor; import com.appsmith.external.plugins.PluginExecutor;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.GsonBuilder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.bson.internal.Base64; import org.bson.internal.Base64;
import org.pf4j.Extension; import org.pf4j.Extension;
@ -31,6 +32,7 @@ import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.Map;
public class RestApiPlugin extends BasePlugin { public class RestApiPlugin extends BasePlugin {
private static int MAX_REDIRECTS = 5; private static int MAX_REDIRECTS = 5;
@ -50,9 +52,10 @@ public class RestApiPlugin extends BasePlugin {
DatasourceConfiguration datasourceConfiguration, DatasourceConfiguration datasourceConfiguration,
ActionConfiguration actionConfiguration) { ActionConfiguration actionConfiguration) {
String requestBody = (actionConfiguration.getBody() == null) ? "" : actionConfiguration.getBody(); String requestBodyAsString = (actionConfiguration.getBody() == null) ? "" : actionConfiguration.getBody();
String path = (actionConfiguration.getPath() == null) ? "" : actionConfiguration.getPath(); String path = (actionConfiguration.getPath() == null) ? "" : actionConfiguration.getPath();
String url = datasourceConfiguration.getUrl() + path; String url = datasourceConfiguration.getUrl() + path;
boolean isContentTypeJsonInRequest = false;
HttpMethod httpMethod = actionConfiguration.getHttpMethod(); HttpMethod httpMethod = actionConfiguration.getHttpMethod();
if (httpMethod == null) { if (httpMethod == null) {
@ -62,14 +65,15 @@ public class RestApiPlugin extends BasePlugin {
WebClient.Builder webClientBuilder = WebClient.builder(); WebClient.Builder webClientBuilder = WebClient.builder();
if (datasourceConfiguration.getHeaders() != null) { if (datasourceConfiguration.getHeaders() != null) {
addHeadersToRequest(webClientBuilder, datasourceConfiguration.getHeaders()); isContentTypeJsonInRequest = addHeadersToRequestAndAscertainContentType(webClientBuilder, datasourceConfiguration.getHeaders(),
isContentTypeJsonInRequest);
} }
if (actionConfiguration.getHeaders() != null) { if (actionConfiguration.getHeaders() != null) {
addHeadersToRequest(webClientBuilder, actionConfiguration.getHeaders()); isContentTypeJsonInRequest = addHeadersToRequestAndAscertainContentType(webClientBuilder, actionConfiguration.getHeaders(),
isContentTypeJsonInRequest);
} }
URI uri = null; URI uri = null;
try { try {
uri = createFinalUriWithQueryParams(url, actionConfiguration.getQueryParameters()); uri = createFinalUriWithQueryParams(url, actionConfiguration.getQueryParameters());
@ -80,7 +84,7 @@ public class RestApiPlugin extends BasePlugin {
} }
WebClient client = webClientBuilder.build(); WebClient client = webClientBuilder.build();
return httpCall(client, httpMethod, uri, requestBody, 0) return httpCall(client, httpMethod, uri, requestBodyAsString, 0, isContentTypeJsonInRequest)
.flatMap(clientResponse -> clientResponse.toEntity(byte[].class)) .flatMap(clientResponse -> clientResponse.toEntity(byte[].class))
.map(stringResponseEntity -> { .map(stringResponseEntity -> {
HttpHeaders headers = stringResponseEntity.getHeaders(); HttpHeaders headers = stringResponseEntity.getHeaders();
@ -146,15 +150,26 @@ public class RestApiPlugin extends BasePlugin {
.doOnError(e -> Mono.error(new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, e))); .doOnError(e -> Mono.error(new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, e)));
} }
private Mono<ClientResponse> httpCall(WebClient webClient, HttpMethod httpMethod, URI uri, String requestBody, int iteration) { private Mono<ClientResponse> httpCall(WebClient webClient, HttpMethod httpMethod, URI uri, String requestBodyAsString,
int iteration, boolean isJsonContentType) {
if (iteration == MAX_REDIRECTS) { if (iteration == MAX_REDIRECTS) {
System.out.println("Exceeded the http redirect limits. Returning error"); System.out.println("Exceeded the http redirect limits. Returning error");
return Mono.error(new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, "Exceeded the HTTO redirect limits of " + MAX_REDIRECTS)); return Mono.error(new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, "Exceeded the HTTO redirect limits of " + MAX_REDIRECTS));
} }
Object requestBodyAsObject;
if (isJsonContentType) {
GsonBuilder gson = new GsonBuilder();
Map<String, String> requestBodyAsMap = gson.create().fromJson(requestBodyAsString, Map.class);
requestBodyAsObject = requestBodyAsMap;
} else {
requestBodyAsObject = requestBodyAsString;
}
return webClient return webClient
.method(httpMethod) .method(httpMethod)
.uri(uri) .uri(uri)
.body(BodyInserters.fromObject(requestBody)) .body(BodyInserters.fromObject(requestBodyAsObject))
.exchange() .exchange()
.doOnError(e -> Mono.error(new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, e))) .doOnError(e -> Mono.error(new AppsmithPluginException(AppsmithPluginError.PLUGIN_ERROR, e)))
.flatMap(res -> { .flatMap(res -> {
@ -174,7 +189,8 @@ public class RestApiPlugin extends BasePlugin {
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
e.printStackTrace(); e.printStackTrace();
} }
return httpCall(webClient, httpMethod, redirectUri, requestBody, iteration + 1); return httpCall(webClient, httpMethod, redirectUri, requestBodyAsString, iteration + 1,
isJsonContentType);
} }
return Mono.just(response); return Mono.just(response);
}); });
@ -206,12 +222,19 @@ public class RestApiPlugin extends BasePlugin {
} }
} }
private void addHeadersToRequest(WebClient.Builder webClientBuilder, List<Property> headers) { private boolean addHeadersToRequestAndAscertainContentType(WebClient.Builder webClientBuilder,
List<Property> headers,
boolean isContentTypeJson) {
for (Property header : headers) { for (Property header : headers) {
if (header.getKey() != null && !header.getKey().isEmpty()) { if (header.getKey() != null && !header.getKey().isEmpty()) {
webClientBuilder.defaultHeader(header.getKey(), header.getValue()); webClientBuilder.defaultHeader(header.getKey(), header.getValue());
if (header.getKey().equals("Content-Type") &&
header.getValue().equals(MediaType.APPLICATION_JSON_VALUE)) {
isContentTypeJson = true;
}
} }
} }
return isContentTypeJson;
} }
private URI createFinalUriWithQueryParams(String url, List<Property> queryParams) throws URISyntaxException { private URI createFinalUriWithQueryParams(String url, List<Property> queryParams) throws URISyntaxException {