Labels

Java (10) Spring (10) Spring MVC (6) Web Services (5) Rest (4) Javascript (3) Nodejs (3) Spring Batch (3) Angular (2) Angular2 (2) Angular6 (2) Expressjs (2) Passportjs (2) SOAP (2) SOAPUI (2) Spring Boot (2) AJAX (1) H2 (1) JQuery (1) JUnit (1) Npm (1) Puppeteer (1) Python (1) RaspberryPi (1) Raspbian (1) SQL (1) SQLite (1) Scripts (1) html (1)

Sunday, July 16, 2017

How to invoke a POST method in a RESTFul Web service with basic authentication

As an example of how to do this I will invoke the restful web service that we built here.

If you want to call a web service from a Java Spring application, the best way to go around the problem is (in my opinion) by creating:


  •  A POJO for the request and a POJO for the response. You could avoid these by working directly with JSON strings but I think this could go wild.
  • A bean that invokes the web service, with the password and user as attributes. This bean will use the previous POJO's to build the invocation to the ws.




Request and Response POJO's


In my example I have a web service that takes an object with the webcam parameters (number of seconds to wait until the webcam detects movement), and a response object with the images obtained by the server.

This will be my request:

\src\main\java\com\hjbello\restfulws\RequestCapture.java

package com.hjbello.restfulws;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class RequestCapture {

 private int seconds;

 public RequestCapture(int seconds) {
  super();
  this.seconds = seconds;
 }

 public int getSeconds() {
  return seconds;
 }

 public void setSeconds(int seconds) {
  this.seconds = seconds;
 }

 public RequestCapture() {
  super();
  }
 
}

And this the response:

\src\main\java\com\hjbello\restfulws\CapturedMovement.java

package com.hjbello.restfulws;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import java.util.ArrayList;
import java.util.Date;

@JsonIgnoreProperties(ignoreUnknown = true)

public class CapturedMovement {

 private String dateOfCapture;

 private ArrayList<String> imagesPath;

 private ArrayList<byte[]> imagesBase64;

 public String getDateOfCapture() {
  return dateOfCapture;
 }

 public void setDateOfCapture(String dateOfCapture) {
  this.dateOfCapture = dateOfCapture;
 }

 public ArrayList<byte[]> getImagesBase64() {
  return imagesBase64;
 }

 public void setImagesBase64(ArrayList<byte[]> imagesBase64) {
  this.imagesBase64 = imagesBase64;
 }

 public CapturedMovement(String dateOfCapture, ArrayList<byte[]> imagesBase64) {
  super();
  this.dateOfCapture = dateOfCapture;
  this.imagesBase64 = imagesBase64;
 }

 public CapturedMovement() {
  super();
 }

 public ArrayList<String> getImagesPath() {
  return imagesPath;
 }

 public void setImagesPath(ArrayList<String> imagesPath) {
  this.imagesPath = imagesPath;
 }
 
}


Invoker


Now we create the bean that we will autowire every time we need to invoke the restful web service in our application


\src\main\java\com\hjbello\restfulws\WebcamRestWS.java


package com.hjbello.restfulws;

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@Component
public class WebcamRestWS {

 private String url = "http://localhost:8080/capture/";
 private String user = "user";
 private String password = "1234";

 
 public CapturedMovement invokeWecamRestWS ( RequestCapture requestCapture) throws JsonProcessingException{
  //First we prepare the authentification
  DefaultHttpClient httpClient = new DefaultHttpClient();
  BasicCredentialsProvider credentialsProvider =  new BasicCredentialsProvider();
  credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, password));
  httpClient.setCredentialsProvider(credentialsProvider);
  ClientHttpRequestFactory rf = new HttpComponentsClientHttpRequestFactory(httpClient);

  //Here we convert the request to json, and then to httpEntity
  ObjectMapper mapper = new ObjectMapper();
  String requestCaptureJson = mapper.writeValueAsString(requestCapture);
  HttpHeaders headers = new HttpHeaders();
  headers.setContentType(MediaType.APPLICATION_JSON);
  HttpEntity request= new HttpEntity(requestCaptureJson, headers);

  //We invoke the web service
  RestTemplate restTemplate = new RestTemplate(rf);
  CapturedMovement response = restTemplate.postForObject(url,request, CapturedMovement.class);
  return response;
 }

}


Be aware that you will need the following dependencies in your pom.xml file:



  <!-- Restful web services -->
  <dependency>
   <groupId>org.codehaus.jackson</groupId>
   <artifactId>jackson-jaxrs</artifactId>
   <version>1.9.13</version>
  </dependency>
  <dependency>
   <groupId>com.sun.jersey</groupId>
   <artifactId>jersey-client</artifactId>
   <version>1.19</version>
  </dependency>
  <dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   </dependency>

If you want to invoke a GET method, instead of restTemplate.postForObject you will need something like


CapturedMovement response = restTemplate.getForObject(url, CapturedMovement.class);

in the Getting Started Spring tutorial you have a complete example regarding GET methods.


Tests with JUnit4



Now that we have our invoker class (or client), we can test it with JUnit4. For that purpose create a src/main/test folder in your classpath and click on New -> JUnit Test Case



And add the following code to the newly created class




\src\main\tests\com\hjbello\tests\TestWebcamRestWS.java


package com.hjbello.tests;

import static org.junit.Assert.*;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.hjbello.restfulws.RequestCapture;
import com.hjbello.restfulws.WebcamRestWS;



public class TestWebcamRestWS {

 @Test
 public void test() throws JsonProcessingException {
  WebcamRestWS wr = new WebcamRestWS();
  RequestCapture request = new RequestCapture(1);
  System.out.println("testing web service client");
  System.out.println(wr.invokeWecamRestWS(request));
  assertNotNull("Asserting that return class is not null", wr.invokeWecamRestWS(request));
 }

}


To run it we will click on Run As -> JUnit Test





Or alternatively in Run Configurations:




We will see that it Runs OK and it gives us JSON response down in the console:



here you have more info regarding JUnit4.

No comments:

Post a Comment