All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.cloud.rest.api.client.RequestBuilder Maven / Gradle / Ivy

Go to download

Java HTTP client library for HTTP handling, when building clients for RESTful APIs.

The newest version!
package com.sap.cloud.rest.api.client;

import static com.sap.cloud.rest.api.client.utils.ValidateArgument.isNotEmptyOrNull;
import static com.sap.cloud.rest.api.client.utils.ValidateArgument.isNotNull;
import static java.text.MessageFormat.format;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import org.apache.http.Header;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.message.BasicNameValuePair;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sap.cloud.rest.api.client.exceptions.RequestBuilderException;
import com.sap.cloud.rest.api.client.model.Request;
import com.sap.cloud.rest.api.client.model.multipart.EntityPart;
import com.sap.cloud.rest.api.client.model.multipart.MultipartEntity;

/**
 * A builder for {@link Request}s. Initialize using the static methods to create
 * a builder for a specific HTTP method.
 * 
 * Supports JSON deserialization for POST, PUT and PATCH requests, using Jackson
 * library. To use it pass the type of the object you want to deserialize as a
 * {@link Class} object when initializing the builder and then pass an object of
 * type {@link T} to the entity method. 
* * Supports multipart requests. To build a multipart {@link Request}, add entity * parts using the multipartEntity method and build the request with the * buildMultipart method. * * @param * the type of the {@link Request} that will be build. If no * {@link Class} object is provided during initialization, T defaults * to type {@link String}. If multipart, the {@link Request} will be * of type {@link MultipartEntity} with this generic type. */ public class RequestBuilder { static final String FAILED_TO_BUILD_REQUEST_OBJECT_MSG = "Failed to build request object. "; static final String FAILED_TO_PARSE_ENTITY_TO_JSON_MSG = "Failed to parse entity [{0}] to json."; static final String FAILED_TO_SET_URI_X_MSG = "Failed to set URI. Provided URI [{0}] is invalid."; static final String ADDING_QUERY_PARAMS_FAILED_MSG = "Adding query parameters failed."; static final String URI_IS_NOT_SET_MSG = "URI is not set."; static final String ENTITY_DISPLAY_NAME = "Entity"; static final String NAME_DISPLAY_NAME = "Name"; private org.apache.http.client.methods.RequestBuilder requestBuilder; private MultipartEntityBuilder multipartEntityBuilder; private EntityBuilder entityBuilder; private List parameters; private ObjectMapper objectMapper; private List> multipartEntities; private T entity; public static RequestBuilder postRequest(Class clazz) { return new RequestBuilder(org.apache.http.client.methods.RequestBuilder.post()); } public static RequestBuilder putRequest(Class clazz) { return new RequestBuilder(org.apache.http.client.methods.RequestBuilder.put()); } public static RequestBuilder patchRequest(Class clazz) { return new RequestBuilder(org.apache.http.client.methods.RequestBuilder.patch()); } public static RequestBuilder patchRequest() { return new RequestBuilder<>(org.apache.http.client.methods.RequestBuilder.patch()); } public static RequestBuilder getRequest() { return new RequestBuilder<>(org.apache.http.client.methods.RequestBuilder.get()); } public static RequestBuilder postRequest() { return new RequestBuilder<>(org.apache.http.client.methods.RequestBuilder.post()); } public static RequestBuilder putRequest() { return new RequestBuilder<>(org.apache.http.client.methods.RequestBuilder.put()); } public static RequestBuilder deleteRequest() { return new RequestBuilder<>(org.apache.http.client.methods.RequestBuilder.delete()); } private RequestBuilder(org.apache.http.client.methods.RequestBuilder requestBuilder) { this.requestBuilder = requestBuilder; this.entityBuilder = EntityBuilder.create().setContentType(ContentType.APPLICATION_JSON); this.multipartEntityBuilder = MultipartEntityBuilder.create(); this.parameters = new ArrayList<>(); this.objectMapper = new ObjectMapper(); this.multipartEntities = new ArrayList<>(); this.entity = null; } public RequestBuilder uri(String uri) { try { requestBuilder.setUri(uri); } catch (IllegalArgumentException e) { throw new RequestBuilderException(format(FAILED_TO_SET_URI_X_MSG, uri), e); } return this; } public RequestBuilder uri(URI uri) { return uri(uri.toString()); } public RequestBuilder addHeader(String name, String value) { requestBuilder.addHeader(name, value); return this; } public RequestBuilder addHeader(Header header) { requestBuilder.addHeader(header); return this; } public RequestBuilder addHeaders(List
headers) { for (Header header : headers) { requestBuilder.addHeader(header); } return this; } public RequestBuilder addHeaders(Header[] headers) { return addHeaders(Arrays.asList(headers)); } public RequestBuilder addParameter(String param, String value) { parameters.add(new BasicNameValuePair(param, value)); return this; } public RequestBuilder addParameters(List nvps) { parameters.addAll(nvps); return this; } /** * Sets an entity as request body. If the entity is not of type * {@link String} it is deserialized using Jackson. * * @param entity the request entity * @return request builder * @throws RequestBuilderException * if Jackson fails to parse the provided entity */ public RequestBuilder entity(T entity) { isNotNull(ENTITY_DISPLAY_NAME, entity); if (entity instanceof String) { entityBuilder.setText((String) entity); this.entity = entity; return this; } try { entityBuilder.setText(objectMapper.writeValueAsString(entity)); this.entity = entity; return this; } catch (JsonProcessingException e) { throw new RequestBuilderException(format(FAILED_TO_PARSE_ENTITY_TO_JSON_MSG, entity), e); } } /** * Adds an entity part to the request builder in case a multipart request is * to be created. The {@link Request} object is to be build with the * buildMultipart() method instead of the normal build() method in order to * use multipart entities that are set. * * @param name the name of the entity part * @param entity an entity representing the part * @throws RequestBuilderException * if Jackson fails to parse the provided entity * @return RequestBuilder instance. */ public RequestBuilder multipartEntity(String name, T entity) { isNotEmptyOrNull(NAME_DISPLAY_NAME, name); isNotNull(ENTITY_DISPLAY_NAME, entity); if (entity instanceof String) { multipartEntityBuilder.addTextBody(name, (String) entity); } else { try { String jsonObj = objectMapper.writeValueAsString(entity); Properties props = objectMapper.readValue(jsonObj, Properties.class); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); props.store(outputStream, null); ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); multipartEntityBuilder.addPart(name, new InputStreamBody(inputStream, name)); } catch (IOException e) { throw new RequestBuilderException(format(FAILED_TO_PARSE_ENTITY_TO_JSON_MSG, entity), e); } } this.multipartEntities.add(new EntityPart<>(name, entity)); return this; } /** * Builds a {@link Request} with generic type {@link T} with the provided * URI and optionally an request entity, any headers and any query * parameters if set. * * @throws RequestBuilderException * in case of a problem while building the request * @return Request instance. */ public Request build() { if (requestBuilder.getUri() == null) { throw new RequestBuilderException(FAILED_TO_BUILD_REQUEST_OBJECT_MSG + URI_IS_NOT_SET_MSG); } if (!parameters.isEmpty()) { this.uri(getUriWithParametersSet()); } if (entity != null) { requestBuilder.setEntity(entityBuilder.build()); } return new Request<>(requestBuilder.build(), entity); } /** * Builds a multipart {@link Request} of type {@link MultipartEntity} with * generic type {@link T} with the provided URI and optionally any request * entity parts, any headers and any query parameters if set. * * @throws RequestBuilderException * in case of a problem while building the request * @return Returns multipart request. */ public Request> buildMultipart() { if (requestBuilder.getUri() == null) { throw new RequestBuilderException(FAILED_TO_BUILD_REQUEST_OBJECT_MSG + URI_IS_NOT_SET_MSG); } if (!parameters.isEmpty()) { this.uri(getUriWithParametersSet()); } if (!multipartEntities.isEmpty()) { requestBuilder.setEntity(multipartEntityBuilder.build()); } return new Request<>(requestBuilder.build(), new MultipartEntity<>(multipartEntities)); } protected String getUriWithParametersSet() { try { URI uri = requestBuilder.getUri(); return URLDecoder.decode(new URIBuilder(uri) .setParameters(parameters) .build().toString(), StandardCharsets.UTF_8.name()); } catch (URISyntaxException | UnsupportedEncodingException e) { throw new RequestBuilderException(FAILED_TO_BUILD_REQUEST_OBJECT_MSG + ADDING_QUERY_PARAMS_FAILED_MSG, e); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy