This tutorial shows how to merge documents to a single file in a Java application using the LEADTOOLS Cloud Services.
Overview | |
---|---|
Summary | This tutorial covers how to make Merge requests and process the results using the LEADTOOLS Cloud Services in a Java application. |
Completion Time | 30 minutes |
Project | Download tutorial project (7 KB) |
Platform | LEADTOOLS Cloud Services API |
IDE | IntelliJ |
Language | Java |
Development License | Download LEADTOOLS |
Be sure to review the following sites for information about LEADTOOLS Cloud Services API.
Create an Account with LEADTOOLS Hosted Cloud Services to obtain both Application ID and Password strings.
LEADTOOLS Service Plan offerings:
Service Plan | Description |
---|---|
Free Trial | Free Evaluation |
Page Packages | Prepaid Page Packs |
Subscriptions | Prepaid Monthly Processed Pages |
To further explore the offerings, refer to the LEADTOOLS Hosted Cloud Services page.
To obtain the necessary Application ID and Application Password, refer to Create an Account and Application with the LEADTOOLS Hosted Cloud Services.
In the IDE, create a new Java project with Maven, and add the following required Maven dependency to the pom.xml
file:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20210307</version>
</dependency>
With the project created and the package added, coding can begin.
In Project Files, open App.java
. Add the following import
statements at the top.
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.File;
import java.io.FileNotFoundException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublisher;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
Add a class level enum named FormatsEnum
and a method named merge()
. The merge()
method utilizes the Merge API to upload 2 files, verify successful upload, and merge them. If successful a unique identifier (GUID) will be returned and then a query using this GUID will be made.
Add the code below to the FormatsEnum
enumeration.
private enum FormatsEnum
{
Png(1),
Jpeg(2),
Tiff(3),
Pdf(4),
Pdfa(5),
PdfImage(6),
PdfImageOverText(7),
PdfaImageOverText(8),
Docx(9),
DocxFramed(10),
Rtf(11),
RtfFramed(12),
Txt(13),
TxtFramed(14);
private final int value;
FormatsEnum(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
Add the code below to the merge()
method.
private static void merge() {
HttpClient client = HttpClient.newHttpClient();
// If using URL to the file
String tiffUrl = "https://demo.leadtools.com/images/cloud_samples/ocr1-4.tif";
String uploadUrl = String.format("UploadFile?fileurl=%s&forMerge=true", tiffUrl);
Results results = postAsync(uploadUrl, null, client);
// If uploading a file as multi-part content:
// File uploadFile = new File("path/to/file");
// String uploadUrl = "UploadFile";
// Results results = postAsync(uploadUrl, uploadFile, client);
if (results.getStatusCode() != 200) {
System.out.println("Request failed with the following response: " + results.getStatusCode());
return;
}
String firstFileId = results.getData();
System.out.println("First File ID returned by the services: " + firstFileId);
if (!checkFileForVerification(firstFileId, client)) {
return;
}
String pdfUrl = "https://demo.leadtools.com/images/pdf/leadtools.pdf";
uploadUrl = String.format("UploadFile?fileurl=%s&forMerge=true", pdfUrl);
results = postAsync(uploadUrl, null, client);
if (results.getStatusCode() != 200) {
System.out.println("Request failed with the following response: " + results.getStatusCode());
return;
}
String secondFileId = results.getData();
System.out.println("Second File ID returned by the services: " + secondFileId);
if (!checkFileForVerification(secondFileId, client)) {
return;
}
if (!mergeFiles(client, firstFileId, secondFileId)) {
System.out.println("Files failed to Merge");
return;
}
query(firstFileId, client);
System.out.println("Done");
}
Create two new methods named mergeFiles(HttpClient client, String firstFileId, String secondFileId)
and checkFileForVerification(String id, HttpClient client)
. Both methods will be called inside the merge()
method, as shown above.
Add the code below to the mergeFiles()
method to instruct the Cloud Services API to merge the two uploaded files into one utilizing the given IDs.
private static boolean mergeFiles(HttpClient client, String firstFileId, String secondFileId) {
ArrayList<MergeArgument> mergeList = new ArrayList<>();
MergeFirstLast newFirstLast = new MergeFirstLast();
newFirstLast.setFileID(firstFileId);
newFirstLast.setFirstPage(1);
newFirstLast.setLastPage(-1);
mergeList.add(newFirstLast);
MergePageArray newPageArray = new MergePageArray();
newPageArray.setFileID(secondFileId);
newPageArray.setPages(new int[]{5,1,2,4,2});
mergeList.add(newPageArray);
// Final output format for the merged file
int outputFormat = FormatsEnum.Pdf.getValue();
String mergeUrl = String.format("Conversion/Merge?format=%s", outputFormat);
JSONArray mergeJSON = new JSONArray(mergeList.toString());
Results result = postAsync(mergeUrl, HttpRequest.BodyPublishers.ofString(mergeJSON.toString(), StandardCharsets.UTF_8), client);
return result.getStatusCode() == 200;
}
Add the below code to the checkFileForVerification()
method to confirm the file passed in was successfully uploaded.
private static boolean checkFileForVerification(String id, HttpClient client) {
String queryUrl = String.format("Query?id=%s", id);
Results results;
JSONObject returnedData;
int fileStatus = 0;
do {
try {
results = postAsync(queryUrl, null, client);
returnedData = new JSONObject(results.getData());
fileStatus = returnedData.getInt("FileStatus");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (fileStatus == 0 || fileStatus == 123);
if (fileStatus != 122) {
System.out.println("File " + id + "failed verification with the File Status: " + fileStatus);
return false;
}
return true;
}
Next, create a new method called query(String id, HttpClient client)
that utilizes the GUID provided by the merge()
method. If successful the response body will contain all the request data in JSON format. Be sure to call the query()
method inside the merge()
method, as shown above. Add the code below to the query()
method.
private static void query(String id, HttpClient client) {
String queryUrl = String.format("Query?id=%s", id);
Results results;
JSONObject returnedData = new JSONObject();
int fileStatus = 0;
do {
try{
results = postAsync(queryUrl, null, client);
returnedData = new JSONObject(results.getData());
fileStatus = returnedData.getInt("FileStatus");
if (fileStatus != 200) Thread.sleep(5000);
} catch (InterruptedException e) {
//e.printStackTrace();
}
} while (fileStatus == 0 || fileStatus == 100 || fileStatus == 123);
System.out.println("File has finished processing with return code: " + fileStatus);
if (fileStatus != 200) {
return;
}
parseJson(returnedData.get("RequestData").toString());
}
Then, create two new methods named parseJson(String json)
and postAsync(String path, File file, HttpClient client)
, which will both be called inside the query()
method, as shown above.
Add the code below to the parseJson()
method to process the returned JSON data.
private static void parseJson(String json) {
JSONArray requestArray = new JSONArray(json);
for (Object requestObject : requestArray) {
if (requestObject instanceof JSONObject) {
JSONObject requestReturn = (JSONObject) requestObject;
System.out.println("Service Type: " + requestReturn.getString("ServiceType"));
System.out.println("Returned Data:");
JSONArray urlArray = new JSONArray(requestReturn.get("urls").toString());
for (Object obj : urlArray) {
System.out.println(obj.toString());
}
}
}
}
Add the code below to the postAsync()
method to create a client connection to request the GUID and JSON data through. Where it states Replace with Application ID
and Replace with Application Password
be sure to place your Application ID and Password accordingly.
private static Results postAsync(String path, Object body, HttpClient client) {
String AppId = "Replace with Application ID";
String Password = "Replace with Application Password";
String authHeader = "Basic " + new String(Base64.getEncoder().encode((AppId + ":" + Password).getBytes(StandardCharsets.UTF_8)));
String hostedServicesUrl = "https://azure.leadtools.com/api/";
BodyPublisher thisBody = HttpRequest.BodyPublishers.ofString("null");
if (body instanceof BodyPublisher) {
thisBody = (BodyPublisher) body;
} else if (body instanceof File) {
try {
thisBody = HttpRequest.BodyPublishers.ofFile(((File) body).toPath());
} catch (FileNotFoundException e) {
//e.printStackTrace();
}
}
HttpRequest request = HttpRequest.newBuilder()
.POST(thisBody)
.uri(URI.create(hostedServicesUrl + path))
.header("Accept", "application/json")
.header("Authorization", authHeader)
.header("Content-Type", "text/plain")
.build();
CompletableFuture<HttpResponse<String>> result = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
Results results = new Results();
results.setData("");
results.setStatusCode(0);
try{
results.setData(result.thenApply(HttpResponse::body).get(5, TimeUnit.SECONDS));
results.setStatusCode(result.thenApply(HttpResponse::statusCode).get(5, TimeUnit.SECONDS));
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}
return results;
}
The application will require a helper class to store the results of the POST
requests. Create a new class called Results
and add the code below to it.
private static class Results {
private String data;
private int statusCode;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public int getStatusCode() {
return statusCode;
}
public void setStatusCode(int statusCode) {
this.statusCode = statusCode;
}
}
Additionally, create the model classes, MergeArgument
, MergeFirstLast : MergeArgument
, and MergePageArray : MergeArgument
; these facilitate the mergeFiles()
method. Add the code below to these classes respectively.
private static class MergeArgument {
private String fileId;
public String getFileID() {
return fileId;
}
public void setFileID(String fileId) {
this.fileId = fileId;
}
public String toString() {
return "\"fileId\":\"" + fileId + "\"}";
}
}
private static class MergeFirstLast extends MergeArgument {
private int firstPage;
private int lastPage;
public int getFirstPage() {
return firstPage;
}
public int getLastPage() {
return lastPage;
}
public void setFirstPage(int firstPage) {
this.firstPage = firstPage;
}
public void setLastPage(int lastPage) {
this.lastPage = lastPage;
}
@Override
public String toString() {
return "{\"firstPage\":" + firstPage + ",\"lastPage\":" + lastPage + "," + super.toString();
}
}
private static class MergePageArray extends MergeArgument {
private int[] pages;
public int[] getPages() {
return pages;
}
public void setPages(int[] pages) {
this.pages = pages;
}
@Override
public String toString() {
return "{\"pages\":" + Arrays.toString(pages) + "," + super.toString();
}
}
In order to test run this code be sure to add merge();
to the static void main
section.
Run the project by pressing Alt + F5, or by selecting Run -> Debug App.
If the steps were followed correctly, the console appears and the application displays the link to the merged file from the returned JSON data.
This tutorial showed how to merge files via the LEADTOOLS Cloud Services in a Java application.