๐ก Capture Your Mobile Applicationโs Network Logs from Automation โ Part 2
How to Use MITM Proxy and Java for Network Log Interception

๐ Recap: What We Did in Part 1?
In Part 1, we successfully set up MITM Proxy to intercept network requests from a mobile app running on an Android/iOS device. We learned how to:
โ
Install MITM Proxy and start a proxy server.
โ
Configure proxy settings on a real device/emulator.
โ
Intercept HTTP & HTTPS requests using a MITM CA Certificate.
๐ That was fun, but now letโs take it to the next level!
๐ฅ Whatโs Next?
We donโt just want to view network logsโwe want to capture them programmatically in our automation framework.
And for that, weโll use MITM Proxyโs Java Client!
๐ค What is the MITM Proxy Java Client?
The MITM Proxy Java Client (mitmproxy-java) acts as a bridge between MITM Proxy and your Java-based automation framework.
๐ก Hereโs how it works:
โ
MITM Proxy starts a WebSocket server.
โ
A Python plugin inside MITM Proxy sends network traffic to the Java client.
โ
The Java client captures and stores network requests for analysis.
With this setup, we can:
๐ Capture API calls made by the mobile app.
๐ Save network logs for debugging.
๐ Attach logs to test reports.
โ๏ธ Step 1: Install the Required Dependencies
๐ Prerequisites
Before setting up the Java client, make sure you have:
1๏ธโฃ MITM Proxy v9+ installed and working.
2๏ธโฃ Python 3.6+ (MITM Proxy uses async WebSockets).
3๏ธโฃ WebSockets module installed:
pip3 install websockets
๐ Add MITM Proxy Java Dependency to Your Project
If youโre using Maven, add this dependency to your pom.xml:
<dependency>
<groupId>io.appium</groupId>
<artifactId>mitmproxy-java</artifactId>
<version>2.0.2</version>
</dependency>
๐จ Note: The latest version is not yet available in the official repository, so you may need to clone the source code and build your own JAR.
๐ Step 2: Integrate MITM Proxy Java Client in Your Framework
๐ Step 2.1: Create a Class to Store Intercepted Messages
To store network logs with timestamps, create InterceptedMessages.java:
import io.appium.mitmproxy.InterceptedMessage;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* Stores intercepted message along with timestamp.
*/
public class InterceptedMessages {
@Accessors(chain = true)
@Getter@Setter
private Date timestamp;
@Accessors(chain = true)
@Getter@Setter
private InterceptedMessage interceptedMessage;
}
๐ Now every intercepted request will be saved with a timestamp!
๐ Step 2.2: Add a Handler to Start & Stop MITM Proxy
Now, letโs create MITMProxy.java to:
โ
Start the proxy listener.
โ
Capture network traffic.
โ
Stop the proxy when needed.
import io.appium.mitmproxy.InterceptedMessage;
import io.appium.mitmproxy.MitmproxyJava;
import lombok.Getter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeoutException;
/**
* MITM Proxy Utility for Capturing Network Logs in Automation Framework.
*/
public class MITMProxy {
@Getter
private final List<InterceptedMessages> networkCalls = new ArrayList<>();
private static MITMProxy proxyInstance = null;
private MitmproxyJava proxy;
// Singleton Pattern to Ensure Single Instance
private MITMProxy() {
startProxyListener();
}
public static MITMProxy getProxy() {
if (proxyInstance == null)
proxyInstance = new MITMProxy();
return proxyInstance;
}
/**
* Starts MITM Proxy and Listens for Network Traffic
*/
private void startProxyListener() {
System.out.println("๐ Starting MITM Proxy Listener...");
List<String> extraMitmproxyParams = Arrays.asList("--showhost", "<domain-name-filter>");
int mitmproxyPort = 8090;
this.proxy = new MitmproxyJava(getMitmDumpPath(), (InterceptedMessage message) -> {
InterceptedMessages interceptedMessage = new InterceptedMessages()
.setTimestamp(new Date())
.setInterceptedMessage(message);
networkCalls.add(interceptedMessage);
// Log each intercepted message
System.out.println("๐ Captured Network Request at: " + interceptedMessage.getTimestamp());
System.out.println("๐ก Request Details: " + message);
return message;
}, mitmproxyPort, extraMitmproxyParams);
try {
// Kill existing process on the same port if running
String processId = ProcessExecutor.executeCommandSync("lsof -t -i:" + mitmproxyPort + " -sTCP:LISTEN").trim();
if (!processId.isEmpty())
ProcessExecutor.executeCommandSync("kill -9 " + processId);
this.proxy.start();
} catch (IOException | TimeoutException e) {
throw new RuntimeException("โ Failed to Start Proxy: " + e.getMessage());
}
System.out.println("โ
Proxy Listener Started Successfully!");
}
/**
* Retrieves MITM Dump Path
*/
private String getMitmDumpPath() {
String result = ProcessExecutor.executeCommandSync("whereis mitmdump");
return result.split("mitmdump: ")[1].split(" ")[0].trim();
}
/**
* Stops MITM Proxy
*/
public void stopProxyListener() {
System.out.println("๐ Stopping MITM Proxy Listener...");
try {
this.proxy.stop();
} catch (InterruptedException e) {
throw new RuntimeException("โ Failed to Stop Proxy: " + e.getMessage());
}
System.out.println("โ
Proxy Listener Stopped Successfully!");
}
/**
* Prints All Captured Network Logs
*/
public void printCapturedLogs() {
System.out.println("๐ Printing Captured Network Logs...");
if (networkCalls.isEmpty()) {
System.out.println("โ ๏ธ No network requests were intercepted.");
return;
}
for (InterceptedMessages msg : networkCalls) {
System.out.println("โณ Captured Request at: " + msg.getTimestamp());
System.out.println("๐ก Request Details: " + msg.getInterceptedMessage());
System.out.println("--------------------------------------------------");
}
}
}
๐ฅ What Does This Class Do?
โ
Automatically starts MITM Proxy when called.
โ
Captures every intercepted request and stores it with a timestamp.
โ
Prevents port conflicts by killing any existing process on the same port.
๐ Step 3: Start Capturing Network Logs
๐ฌ Start the Proxy
MITMProxy.getProxy();
๐ This starts the MITM Proxy and begins capturing network requests.
๐ Fetch Intercepted Logs
networkLogMessage = MITMProxy.getProxy().getNetworkCalls();
๐ This retrieves all captured network logs, which can be saved or attached to reports.
๐ Stop the Proxy
MITMProxy.getProxy().stopProxyListener();
๐ This stops the proxy when tests are complete.
๐ Verifying Captured Logs
Once your tests have run, print the captured logs to verify that requests are being intercepted:
for (InterceptedMessages msg : MITMProxy.getProxy().getNetworkCalls()) {
System.out.println("Captured Request at: " + msg.getTimestamp());
System.out.println("Request Details: " + msg.getInterceptedMessage());
}
๐ Now you can capture and analyze every network request in your tests!
๐ฏ Whatโs Next?
โ We can now intercept API calls from our mobile automation framework! ๐ฏ
But what if we need to store these logs for later analysis? ๐ค
๐ In Part 3, weโll:
โ
Save network logs to files for debugging.
โ
Attach logs to automation test reports.
โ
Filter out unwanted noise from logs.
Stay tuned for Part 3! ๐๐ฅ
๐ฌ Questions? Drop a comment below!


