Use AI Guardrails SDK for Java to scan images for risky content across multiple moderation scenarios, including pornography, terrorist content, ads, QR codes, undesirable scenes, and logos.
This SDK accepts only image URLs (HTTP or HTTPS, up to 2,048 characters). Local file paths and binary data are not supported directly — use the ClientUploader class from the Extension.Uploader utility to upload local files or binary streams first, then pass the returned URL.Prerequisites
Before you begin, make sure you have:
Java dependencies installed. See Installation for the required Java version. Using a different version causes operation calls to fail.
The Extension.Uploader utility class downloaded and imported into your project, if you plan to moderate local images or binary image streams.
Choose a detection mode
| Mode | How it works | Use when |
|---|---|---|
| Synchronous | Returns results immediately in the response | You need real-time decisions (for example, blocking uploads before they are stored) |
| Asynchronous | Submits a task and returns a task ID; retrieve results by polling or callback | You are processing large volumes or do not need an instant decision |
For parameter details, see Synchronous detection and Asynchronous detection and results.
Synchronous image moderation (recommended)
ImageSyncScanRequest submits a synchronous moderation request and returns results in real time.
Supported regions: cn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1
All three examples below use ImageSyncScanRequest. They differ only in how the image is supplied.
Moderate an online image
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
// Use a RAM user's credentials, not the root account's AccessKey pair.
// Load credentials from environment variables to avoid hardcoding secrets.
// AccessKey ID: System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
// AccessKey secret: System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
// Reuse this client instance across requests for better performance.
IAcsClient client = new DefaultAcsClient(profile);
ImageSyncScanRequest request = new ImageSyncScanRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
JSONObject httpBody = new JSONObject();
// Specify one or more moderation scenarios. Charges apply per scenario per image.
// For example, moderating two images for both "porn" and "terrorism" incurs four charges.
httpBody.put("scenes", Arrays.asList("porn"));
// Create one task per image. Batch requests take longer as total time equals
// the time to process the last image.
JSONObject task = new JSONObject();
task.put("dataId", UUID.randomUUID().toString());
task.put("url", "http://www.aliyundoc.com/xxx.test.jpg"); // URL-encode any special characters
task.put("time", new Date());
httpBody.put("tasks", Arrays.asList(task));
request.setHttpContent(
org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
"UTF-8", FormatType.JSON);
// The server takes up to 10s to process a moderation request.
// Set the read timeout to at least 10s to avoid premature failures.
request.setConnectTimeout(3000);
request.setReadTimeout(10000);
HttpResponse httpResponse = null;
try {
httpResponse = client.doAction(request);
} catch (Exception e) {
e.printStackTrace();
}
if (httpResponse != null && httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(
org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
System.out.println(JSON.toJSONString(scrResponse, true));
int requestCode = scrResponse.getIntValue("code");
JSONArray taskResults = scrResponse.getJSONArray("data");
if (200 == requestCode) {
for (Object taskResult : taskResults) {
int taskCode = ((JSONObject) taskResult).getIntValue("code");
// Each element in "results" contains the outcome for one moderation scenario.
JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
if (200 == taskCode) {
for (Object sceneResult : sceneResults) {
String scene = ((JSONObject) sceneResult).getString("scene");
String suggestion = ((JSONObject) sceneResult).getString("suggestion");
// Act on the suggestion: block, review, or pass the image.
System.out.println("scene = [" + scene + "]");
System.out.println("suggestion = [" + suggestion + "]");
}
} else {
System.out.println("Task failed: " + JSON.toJSONString(taskResult));
}
}
} else {
System.out.println("Request failed: " + JSON.toJSONString(scrResponse));
}
}
}
}Expected output:
scene = [porn]
suggestion = [pass]Moderate a local image file
For local images, use ClientUploader to upload the file and get a temporary URL, then submit that URL for moderation.
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.extension.uploader.ClientUploader;
import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
IAcsClient client = new DefaultAcsClient(profile);
ImageSyncScanRequest request = new ImageSyncScanRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
JSONObject httpBody = new JSONObject();
httpBody.put("scenes", Arrays.asList("porn"));
// Upload the local image to get a temporary URL, then submit the URL for moderation.
String url = null;
ClientUploader clientUploader = ClientUploader.getImageClientUploader(profile, false);
try {
url = clientUploader.uploadFile("d:/test.jpg");
} catch (Exception e) {
e.printStackTrace();
}
JSONObject task = new JSONObject();
task.put("dataId", UUID.randomUUID().toString());
task.put("url", url);
task.put("time", new Date());
httpBody.put("tasks", Arrays.asList(task));
request.setHttpContent(
org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
"UTF-8", FormatType.JSON);
request.setConnectTimeout(3000);
request.setReadTimeout(10000);
HttpResponse httpResponse = null;
try {
httpResponse = client.doAction(request);
} catch (Exception e) {
e.printStackTrace();
}
if (httpResponse != null && httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(
org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
System.out.println(JSON.toJSONString(scrResponse, true));
int requestCode = scrResponse.getIntValue("code");
JSONArray taskResults = scrResponse.getJSONArray("data");
if (200 == requestCode) {
for (Object taskResult : taskResults) {
int taskCode = ((JSONObject) taskResult).getIntValue("code");
JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
if (200 == taskCode) {
for (Object sceneResult : sceneResults) {
String scene = ((JSONObject) sceneResult).getString("scene");
String suggestion = ((JSONObject) sceneResult).getString("suggestion");
System.out.println("scene = [" + scene + "]");
System.out.println("suggestion = [" + suggestion + "]");
}
} else {
System.out.println("Task failed: " + JSON.toJSONString(taskResult));
}
}
} else {
System.out.println("Request failed: " + JSON.toJSONString(scrResponse));
}
}
}
}Moderate a binary image stream
If your application holds an image in memory as a byte array, upload it directly with uploadBytes.
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.extension.uploader.ClientUploader;
import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
IAcsClient client = new DefaultAcsClient(profile);
ImageSyncScanRequest request = new ImageSyncScanRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
JSONObject httpBody = new JSONObject();
httpBody.put("scenes", Arrays.asList("porn"));
// Convert the binary image data to a temporary URL, then submit the URL for moderation.
// In production, pass your in-memory byte array directly instead of reading from disk.
ClientUploader clientUploader = ClientUploader.getImageClientUploader(profile, false);
String url = null;
try {
byte[] imageBytes = FileUtils.readFileToByteArray(new File("/Users/01fb4ab6420b5f34623e13b82b51ef87.jpg"));
url = clientUploader.uploadBytes(imageBytes);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
JSONObject task = new JSONObject();
task.put("dataId", UUID.randomUUID().toString());
task.put("url", url);
task.put("time", new Date());
httpBody.put("tasks", Arrays.asList(task));
request.setHttpContent(
org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
"UTF-8", FormatType.JSON);
request.setConnectTimeout(3000);
request.setReadTimeout(10000);
HttpResponse httpResponse = null;
try {
httpResponse = client.doAction(request);
} catch (Exception e) {
e.printStackTrace();
}
if (httpResponse != null && httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(
org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
System.out.println(JSON.toJSONString(scrResponse, true));
int requestCode = scrResponse.getIntValue("code");
JSONArray taskResults = scrResponse.getJSONArray("data");
if (200 == requestCode) {
for (Object taskResult : taskResults) {
int taskCode = ((JSONObject) taskResult).getIntValue("code");
JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
if (200 == taskCode) {
for (Object sceneResult : sceneResults) {
String scene = ((JSONObject) sceneResult).getString("scene");
String suggestion = ((JSONObject) sceneResult).getString("suggestion");
System.out.println("scene = [" + scene + "]");
System.out.println("suggestion = [" + suggestion + "]");
}
} else {
System.out.println("Task failed: " + JSON.toJSONString(taskResult));
}
}
} else {
System.out.println("Request failed: " + JSON.toJSONString(scrResponse));
}
}
}
}Asynchronous image moderation
ImageAsyncScanRequest submits a moderation task and returns a task ID immediately. Retrieve the result by polling with ImageAsyncScanResultsRequest or by receiving a callback to your server.
Supported regions: cn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1
Submit online image URLs, local image files, or binary image streams — the same image sources supported by synchronous moderation. The example below uses an online image URL.
Submit an asynchronous moderation task
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.model.v20180509.ImageAsyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
public class Main {
public static void main(String[] args) throws Exception {
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
IAcsClient client = new DefaultAcsClient(profile);
ImageAsyncScanRequest request = new ImageAsyncScanRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
JSONObject httpBody = new JSONObject();
httpBody.put("scenes", Arrays.asList("porn"));
// Optional: set a callback URL to receive results when moderation completes.
// The "seed" value is used to verify the callback signature.
httpBody.put("callback", "http://www.aliyundoc.com/xxx.json");
httpBody.put("seed", "yourPersonalSeed");
// A single request can include up to 50 images; create one task per image.
JSONObject task = new JSONObject();
task.put("dataId", UUID.randomUUID().toString());
task.put("url", "http://www.aliyundoc.com/xxx.test.jpg");
task.put("time", new Date());
httpBody.put("tasks", Arrays.asList(task));
request.setHttpContent(
org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
"UTF-8", FormatType.JSON);
request.setConnectTimeout(3000);
request.setReadTimeout(10000);
HttpResponse httpResponse = null;
try {
httpResponse = client.doAction(request);
} catch (Exception e) {
e.printStackTrace();
}
if (httpResponse != null && httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(
org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
System.out.println(JSON.toJSONString(scrResponse, true));
int requestCode = scrResponse.getIntValue("code");
JSONArray taskResults = scrResponse.getJSONArray("data");
if (200 == requestCode) {
for (Object taskResult : taskResults) {
int taskCode = ((JSONObject) taskResult).getIntValue("code");
if (200 == taskCode) {
// Save the task ID to poll for results later.
System.out.println("Task ID: " + ((JSONObject) taskResult).getString("taskId"));
} else {
System.out.println("Task failed: " + JSON.toJSONString(taskResult));
}
}
} else {
System.out.println("Request failed: " + JSON.toJSONString(scrResponse));
}
}
}
}Expected output:
Task ID: img4hDosCHcrFk5jAMR80XWJN-1pZ@0pQuery asynchronous moderation results
ImageAsyncScanResultsRequest retrieves results for one or more previously submitted asynchronous tasks. Pass the task IDs returned when submitting.
Supported regions: cn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.green.model.v20180509.ImageAsyncScanResultsRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
IAcsClient client = new DefaultAcsClient(profile);
ImageAsyncScanResultsRequest request = new ImageAsyncScanResultsRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
// Pass the task IDs returned when you submitted the asynchronous moderation request.
List<String> taskIds = new ArrayList<String>();
taskIds.add("img4hDosCHcrFk5jAMR80XWJN-1pZ@0p");
request.setHttpContent(JSON.toJSONString(taskIds).getBytes("UTF-8"), "UTF-8", FormatType.JSON);
request.setConnectTimeout(3000);
request.setReadTimeout(6000);
try {
HttpResponse httpResponse = client.doAction(request);
if (httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
System.out.println(JSON.toJSONString(scrResponse, true));
if (200 == scrResponse.getInteger("code")) {
JSONArray taskResults = scrResponse.getJSONArray("data");
for (Object taskResult : taskResults) {
if (200 == ((JSONObject) taskResult).getInteger("code")) {
JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
for (Object sceneResult : sceneResults) {
String scene = ((JSONObject) sceneResult).getString("scene");
String suggestion = ((JSONObject) sceneResult).getString("suggestion");
// Act on the suggestion: block, review, or pass the image.
System.out.println("scene = [" + scene + "]");
System.out.println("suggestion = [" + suggestion + "]");
}
} else {
System.out.println("Task failed: " + ((JSONObject) taskResult).getInteger("code"));
}
}
} else {
System.out.println("Request failed. Code: " + scrResponse.getInteger("code"));
}
} else {
System.out.println("HTTP error. Status: " + httpResponse.getStatus());
}
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}Provide feedback on moderation results
If a moderation result is incorrect, use ImageScanFeedbackRequest to correct it. AI Guardrails adds the image to the similar image whitelist or blacklist based on your feedback. When you submit a similar image later, AI Guardrails returns results consistent with your correction.
For parameter details, see /green/image/feedback.
Supported regions: cn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.green.model.v20180509.ImageScanFeedbackRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws Exception {
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
IAcsClient client = new DefaultAcsClient(profile);
ImageScanFeedbackRequest request = new ImageScanFeedbackRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
JSONObject httpBody = new JSONObject();
// suggestion: the correct label for the image.
// "pass" — the image is clean; add to whitelist
// "block" — the image is a violation; add to blacklist
httpBody.put("suggestion", "block");
// scenes: the moderation scenarios this feedback applies to.
httpBody.put("scenes", Arrays.asList("ad", "terrorism"));
httpBody.put("url", "<image-url>");
request.setHttpContent(
org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
"UTF-8", FormatType.JSON);
request.setConnectTimeout(3000);
request.setReadTimeout(10000);
try {
HttpResponse httpResponse = client.doAction(request);
if (httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
System.out.println(JSON.toJSONString(scrResponse, true));
if (200 == scrResponse.getInteger("code")) {
System.out.println("Feedback submitted successfully.");
} else {
System.out.println("Failed. Code: " + scrResponse.getInteger("code"));
}
} else {
System.out.println("HTTP error. Status: " + httpResponse.getStatus());
}
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
}
}Usage notes
Billing: Charges are calculated per image per scenario. Moderating one image across two scenarios incurs two charges.
Batch requests: When submitting multiple images in a single request, total latency equals the processing time of the slowest image. For time-sensitive workloads, keep batches small or use individual requests.
Connection timeout: Set the connection timeout to at least 3,000 ms. For synchronous and asynchronous submit requests, set the read timeout to at least 10,000 ms. For query requests (
ImageAsyncScanResultsRequest), a read timeout of 6,000 ms is sufficient.Client reuse: Instantiate
DefaultAcsClientonce and reuse it across requests. Creating a new client per request degrades performance and increases connection overhead.Credentials: Use a RAM user's AccessKey ID and AccessKey secret instead of the root account's credentials. Store them in environment variables, not in source code.