Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

Adobe Summit 2023 [19th to 23rd March, Las Vegas and Virtual] | Complete AEM Session & Lab list

How to Unit testing for doPost Servlet which contains HTTP Request


Level 2

Hi Guys, Can anyone help me in creating Junit test cases for my servlet. I am new to AEM development and not aware of Junit thing. I create below servlet which will retrive rates from an external API in JSON format.

so plz help for unit testing. i need unit testing script for this code, this my code.

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.jcr.RepositoryException;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@component(service = Servlet.class, property = {Constants.SERVICE_DESCRIPTION + "=Rates Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_POST, "sling.servlet.paths=" + "/services/rates/"
@Designate(ocd = RatesServlet.ServiceConfig.class)
public class RatesServlet extends SlingAllMethodsServlet {
protected final Logger log = LoggerFactory.getLogger(RatesServlet.class);
private String apiURL;
private String tokenApiURL;
private String secret;
private String appID;
private static final UUID uuid = UUID.randomUUID();
private static final String correlationID=uuid.toString();
private static final String scope = "/**/communications::POST";
private String token;
protected void doPost(final SlingHttpServletRequest req, final SlingHttpServletResponse resp)
throws ServletException, IOException {
try {
} catch (NoSuchAlgorithmException e) {
} catch (InvalidKeyException e) {
String market = req.getParameter("market");
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); // Quoted "Z" to indicate UTC, no timezone offset
String nowAsISO = df.format(new Date());
CloseableHttpClient client = HttpClients.createDefault();
HttpPost method = new HttpPost(this.apiURL);
JsonObject json = new JsonObject();
json.addProperty("market", market);
json.addProperty("rateVarianceTimestamp", nowAsISO);
StringEntity entity = new StringEntity(json.toString(), ContentType.APPLICATION_JSON);
String authorizationHeader="claims app_authorization="+String.valueOf(this.token);
method.setHeader("Content-Type", "application/json");
method.setHeader("app-id", this.appID);
method.setHeader("Authorization", authorizationHeader);
try {
CloseableHttpResponse response = client.execute(method);
String ratesVarianceResponse = EntityUtils.toString(response.getEntity());
} catch (Exception e) {
log.error("Exception in servlet while executing :", e.getMessage());
} finally {
protected void generateToken(SlingHttpServletRequest req) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
Mac mac = Mac.getInstance("HmacSHA256");
byte[] hmacKeyBytes = Base64.decodeBase64(this.secretOneData.getBytes());
SecretKey secretKey = new SecretKeySpec(hmacKeyBytes, mac.getAlgorithm());
long timestamp = System.currentTimeMillis();
String input = String.format("%s-%s-%s", this.clientIdOneData, "2", timestamp);
byte[] rawHmac = mac.doFinal(input.getBytes());
String signature = Base64.encodeBase64URLSafeString(rawHmac);
CloseableHttpClient client = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(this.tokenApiURL);
String json = "{\n"
+ " \"scope\": [\n"
+ " \"" + scope + "\"\n"
+ " ]\n"
+ "}";
StringEntity entity = new StringEntity(json);
httpPost.setHeader("X-Auth-AppID", this.appID);
httpPost.setHeader("X-Auth-Version", "2");
httpPost.setHeader("X-Auth-Signature", signature);
httpPost.setHeader("Content-Type", "application/json");
httpPost.setHeader("X-Auth-Timestamp", String.valueOf(timestamp));
try {
CloseableHttpResponse response = client.execute(httpPost);
HttpEntity httpentity = response.getEntity();
String signatureToken = EntityUtils.toString(httpentity);
JsonParser parser = new JsonParser();
Object resultObject = parser.parse(signatureToken);
Object keyvalue = null;
if (resultObject instanceof JsonArray) {
JsonArray array=(JsonArray)resultObject;
for (Object object : array) {
JsonObject obj =(JsonObject)object;
keyvalue = obj.get("authorization_token").getAsString();
}else if (resultObject instanceof JsonObject) {
JsonObject obj =(JsonObject)resultObject;
keyvalue = obj.get("authorization_token").getAsString();
} catch (Exception e) {
log.error("Exception in servlet while executing :", e.getMessage());
} finally {
protected void activate(ServiceConfig serviceConfig) throws RepositoryException {
apiURL = PropertiesUtil.toString(serviceConfig.apiURL(), StringUtils.EMPTY);
tokenApiURL = PropertiesUtil.toString(serviceConfig.tokenApiURL(), StringUtils.EMPTY);
secretData = PropertiesUtil.toString(serviceConfig.secretOneData(), StringUtils.EMPTY);
appID = PropertiesUtil.toString(serviceConfig.clientIdOneData(), StringUtils.EMPTY);
@ObjectClassDefinition(name = "Rates Servlet", description = "This service makes an API call and retrieves the rates values")
public @interface ServiceConfig {
@AttributeDefinition(name = "API Url", description = "Please provide the API URL", type= AttributeType.STRING)
String apiURL();
@AttributeDefinition(name = "Token API URL", description = "Please provide the A2A Token generation API URL", type= AttributeType.STRING)
String tokenApiURL();
@AttributeDefinition(name = "Secret Data", description = "Please Provide domain specific secret of Consuming API", type= AttributeType.STRING)
String secretData();
@AttributeDefinition(name = "App ID", description = "Please provide application ID", type= AttributeType.STRING)
String appID();

6 Replies


Level 2

Hi @Mayank_Tiwari , Thanks for sharing these, found some similar requirement in, but here OSGI configuration variables are predefined in Test class, in my case i do not want to define them either in my main servlet or test class. Could you help, how we can do that? 


Community Advisor


OSGi config values created as Map object is the way we mock OSGi config in the Test class. The same is then used while registering the service (with its config) to the AemContext. -


Outside this, if you would like to test HttpClient, you can refer -



Level 2

Hi @Vijayalakshmi_S ,

You mean to say, we must use OSGi config values in Test class? is there any way we can get the values from config manager like we are getting in main class?


Thanks for sharing the info about HttpClient test..



Level 2

Hi @BrianKasingli , 

Thank you for sharing this, it doesn't have any Http request details. My request contains an external API and also with OSGi configurations defined in console.
This is some helpful solution, but OSGI configuration variables are predefined in Test class, in my case i do not want to define them in my main servlet or test class. Could you help me how we can do that?