Problem Statement:
We have created an HTTP Client factory but how to execute requests and handle responses?
Requirement:
Show some examples to build the request and make a request to the external system and handle the response.
Introduction:
HTTP Client factory is an OSGi Service that creates an HTTP connection based on the external system based on the domain and connection configuration.
In order to use this service,
Build URI:
we need to build the key value map using NameValuePair and add these params to URIBuilder. Once the request is created
@Override
public String buildURL(@NotNull String apiEndpointURI, boolean buildExternalLink,
Map < String, String > parameterMap) throws MalformedURLException {
if (MapUtils.isNotEmpty(parameterMap)) {
URIBuilder builder = new URIBuilder();
List < NameValuePair > nvpList = new ArrayList < > (parameterMap.size());
parameterMap.entrySet().stream()
.filter(entry -> StringUtils.isNoneBlank(entry.getKey(), entry.getValue()))
.forEach(entry -> nvpList.add(new BasicNameValuePair(entry.getKey(), entry.getValue())));
return returnApiEndpointURI(apiEndpointURI, buildExternalLink, builder, nvpList);
}
return returnApiEndpointURI(apiEndpointURI, buildExternalLink, null, null);
}
private String returnApiEndpointURI(String apiEndpointURI, boolean buildExternalLink,
URIBuilder builder, List < NameValuePair > nvpList) {
if (buildExternalLink) {
return StringUtils.join(httpClientFactory.getApiStoreLocatorHostName(),
httpClientFactory.getExternalURIType(), apiEndpointURI,
null != builder ? builder.addParameters(nvpList).toString() : StringUtils.EMPTY);
} else {
return StringUtils.join(apiEndpointURI,
null != builder ? builder.addParameters(nvpList).toString() : StringUtils.EMPTY);
}
}
Make a Request:
we can make use of request methods like POST
String responseString = httpClientFactory.getExecutor().execute(httpClientFactory.post(buildURL(apiEndPointURI, false, params)).addHeader("Content-Type", contentType)).handleResponse(HANDLER);
Response Handler:
Get the response and handle the request using StringObjectResponseHandler.
package com.mysite.core.http.impl;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.impl.client.BasicResponseHandler;
/**
* Handling response using Basic response Handler
*/
public class StringObjectResponseHandler implements ResponseHandler < String > {
private BasicResponseHandler handler = new BasicResponseHandler();
@Override
public String handleResponse(HttpResponse httpResponse) throws
ClientProtocolException,
IOException {
String responseString = handler.handleResponse(httpResponse);
HttpClientUtils.closeQuietly(httpResponse);
return responseString;
}
}
Complete file for implementation:
package com.mysite.core.services.impl;
import com.drew.lang.annotations.NotNull;
import com.mysite.core.http.impl.StringObjectResponseHandler;
import com.mysite.core.services.APIInvoker;
import com.mysite.core.services.HttpClientFactory;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.sling.api.servlets.HttpConstants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Component(service = APIInvoker.class)
public class ExampleAPIInvoker implements APIInvoker {
private static final Logger LOGGER = LoggerFactory.getLogger(ExampleAPIInvoker.class);
private static final StringObjectResponseHandler HANDLER = new StringObjectResponseHandler();
@Reference
private HttpClientFactory httpClientFactory;
@Override
public String invokeAPI(String apiEndPointURI, String httpMethod, Map < String, String > params,
String bodyText, String contentType) {
try {
if (StringUtils.isNotEmpty(bodyText)) {
LOGGER.info("API Request Params {}", bodyText);
} else {
LOGGER.info("API Request Params {}", params);
}
if (StringUtils.equalsAnyIgnoreCase(httpMethod, HttpConstants.METHOD_POST) &&
StringUtils.isEmpty(bodyText)) {
String responseString =
httpClientFactory.getExecutor().execute(httpClientFactory.post(buildURL(apiEndPointURI, false, params)).addHeader("Content-Type", contentType)).handleResponse(HANDLER);
return responseString;
}
} catch (MalformedURLException exception) {
LOGGER.debug("MalformedURLException while invoking API, {}", exception.getMessage());
} catch (ClientProtocolException exception) {
LOGGER.debug("ClientProtocolException while invoking API, {}", exception.getMessage());
} catch (IOException exception) {
LOGGER.debug("IOException while invoking API, {}", exception.getMessage());
}
return StringUtils.EMPTY;
}
@Override
public String buildURL(@NotNull String apiEndpointURI, boolean buildExternalLink,
Map < String, String > parameterMap) throws MalformedURLException {
if (MapUtils.isNotEmpty(parameterMap)) {
URIBuilder builder = new URIBuilder();
List < NameValuePair > nvpList = new ArrayList < > (parameterMap.size());
parameterMap.entrySet().stream()
.filter(entry -> StringUtils.isNoneBlank(entry.getKey(), entry.getValue()))
.forEach(entry -> nvpList.add(new BasicNameValuePair(entry.getKey(), entry.getValue())));
return returnApiEndpointURI(apiEndpointURI, buildExternalLink, builder, nvpList);
}
return returnApiEndpointURI(apiEndpointURI, buildExternalLink, null, null);
}
private String returnApiEndpointURI(String apiEndpointURI, boolean buildExternalLink,
URIBuilder builder, List < NameValuePair > nvpList) {
if (buildExternalLink) {
return StringUtils.join(httpClientFactory.getApiStoreLocatorHostName(),
httpClientFactory.getExternalURIType(), apiEndpointURI,
null != builder ? builder.addParameters(nvpList).toString() : StringUtils.EMPTY);
} else {
return StringUtils.join(apiEndpointURI,
null != builder ? builder.addParameters(nvpList).toString() : StringUtils.EMPTY);
}
}
}
Create REST service using HTTP Client factory
Check this out URI