Download the image file via Rest API

Hello All,

I have an API with response as image text.
How to get download the file in local as image file?

Here the script I’ve used

Sample API Response

Thanks!
NU

1 Like

With Katalon Studio’s WS-features, you can not download and save a binary content into file appropriately.

You can read the source of com.kms.katalon.core.testobject.ResponseObject at

If you read the code, you would easily find that ResponseObject naively assumes that all HTTP response is a text. It does not work properly when the HTTP response contains any binary.


I would show you an evidence.

Here is a sample target URL of an image

I can open this in a browser manually, and save the image into disk. I checked the file length:

$ ls -la | grep apple
-rw-r--r--@   1 kazuakiurayama  staff       60428  2 23 09:21 a-bite-in-the-apple.png

The apple image has the size of 60K bytes. This is correct.

Now I wrote a Test Case in Katalon Studio, tried to save the image into file.

import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject

import com.kms.katalon.core.testobject.ResponseObject
import com.kms.katalon.core.testobject.HttpBodyContent
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS

import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths

/**
 * This Test Case tries to download a image of Apple, save it into a local file.
 * The image is accessible at
 *     https://kazurayam.github.io/myApple/a-bite-in-the-apple.png
 * This script uses the build-in keywords of Katalon Studio for WebService testing.
 */

ResponseObject res = WS.sendRequest(findTestObject('Object Repository/AppleImage'))

assert res.getStatusCode() == 200

HttpBodyContent bodyContent = res.getBodyContent()
println "${bodyContent.getContentLength()} bytes"
println "${bodyContent.getContentType()}"
println "${bodyContent.getContentEncoding()}"   // returns null.
Path file = Paths.get("./apple.png")
Files.createDirectories(file.getParent())
OutputStream ostream = new FileOutputStream(file.toFile())

bodyContent.writeTo(ostream)

assert Files.exists(file)
assert file.toFile().length() > 0

The script wrote the file apple.png. I checked the file size:

$ ls -la | grep apple
-rw-r--r--@   1 kazurayam  staff  107545  2 23 09:15 apple.png

The apple.png has 107K bytes of size. This is wrong.

Why the different file size?

I tried to open the apple.png by the image viewer software on Mac OS, it told me the PNG file is broken.

Clearly, Katalon Studio has a bug. No, I should rather say, KS has a design fault.

@Elly_Tran

@nithizunnikumaran21

I believe that the WS features of Katalon Studio never work for any type of binary content. You should not use KS for testing the URLs that respond binary content. You should look for other tools such as Postman.

If you are asked to find a way in KS, you could write test cases that drive the famous Apache HttpClient v4.15 of which jar is bundled in Katalon Studio. You can find some tutorials how to use the Apache HttpClient, like

I will show an example Test Case that uses it:

import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths

import org.apache.http.client.methods.CloseableHttpResponse
import org.apache.http.client.methods.HttpGet
import org.apache.http.entity.ContentType
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.util.EntityUtils

/**
 * This Test Case downloads the Google logo image and save it into a local file.
 * 
 * This script uses the Apache HttpClient library. In the `.classpath` file of this project, I found a line:
 *     /Applications/Katalon Studio.app/Contents/Eclipse/plugins/org.apache.httpcomponents.httpclient_4.5.14.v20221207-1049.jar"/>
 *
 * This means that Katalon Studio bundles the Apache HttpComponet/HttpClient 4.5,
 * so I can use it in this project without any setup
 * 
 * I wrote this code referring to a Baeldung article:
 *     [Apache HttpClient Cookbook](https://www.baeldung.com/apache-httpclient-cookbook)
 */

String url = "https://www.google.co.jp/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"

CloseableHttpClient client = HttpClientBuilder.create().build();
CloseableHttpResponse response = client.execute(new HttpGet(url));
assert response.getStatusLine().getStatusCode() == 200

String contentMimeType = ContentType.getOrDefault(response.getEntity()).getMimeType()
assert contentMimeType == ContentType.IMAGE_PNG.toString()

byte[] contentByteArray = EntityUtils.toByteArray(response.getEntity())
InputStream istream = new ByteArrayInputStream(contentByteArray)

Path logoFile = Paths.get("./google_logo.png")
Files.createDirectories(logoFile.getParent());

Files.copy(istream, logoFile)
assert Files.exists(logoFile)

Katalon Studio internally calls the Apache HttpClient API. So you are to re-invent the WS features for yourself. It is not so difficult if you are skilled enough for Java programming.

It is a fun for me to play on the Apache’s library, which is thoroughly tested, proved to be high quality.

Thanks @kazurayam

I have faced the similar issue as file downloaded but couldnt be supportable.

But, is there any possibility to get the file as image from an API?
Not only by groovy, will it works by java supported by katalon??

Why am asking is!
I’ve to scan the QR/Barcode dynamically for image injection
After that I’d like to scan the image on testCloud getting through API.

Anyway thanks for you support :handshake:

I showed a running sample code above. Use the Apache HttpClient API. Do not use the WS keywords of Katalon.

Groovy or Java? — principally it is not significant. The Groovy compiler can compile any Java code.

You can place a Java code under the Include/scripts/groovy folder. There any *.java will be compiled by the Groovy compiler. So, for example, you can create

Include/scripts/groovy/my/Greeter.java

package my;

public class Greeter {
    public static String greet(String name) {
        return "Hello, " + name;
    }
 
    public static void main(String name) {
        String msg = greet(name);
        System.out.println(msg);
    }
}

Then in a Test Case in Groovy, you use it

import my.Greeter

println Greeter.greet("nithizunnikumaran21")