Deep‑Copying HttpRequestBase in Java: A Custom FunRequest Wrapper
This article explains why a separate HttpRequestBase object is needed for each concurrent request in a performance testing framework, and provides a complete Java implementation of a FunRequest class that offers deep‑copy, cloning, and fluent configuration of GET/POST HTTP requests.
Problem
When building a performance‑testing framework a single HttpRequestBase instance was reused across many threads. Because concrete subclasses such as HttpGet and HttpPost do not implement Serializable, deep‑copy via serialization is unavailable, which can cause hidden bugs due to shared mutable state.
Solution – FunRequest
FunRequestis a wrapper that extends FanLibrary and implements Serializable and Cloneable. It encapsulates request metadata (type, host, API name, URI) and payload collections (headers, query arguments, form parameters, JSON body). The class provides a fluent API for building GET or POST requests and a static cloneRequest method that rebuilds an equivalent HttpRequestBase from an existing one.
Key fields
RequestType requestType– GET or POST HttpRequestBase request – underlying Apache HttpClient request object String host, String apiName, String uri – address components List<Header> headers – request headers JSONObject args – GET query parameters JSONObject params – POST form parameters JSONObject json – POST JSON body
Fluent builder methods
static FunRequest isGet()/ static FunRequest isPost() – create a request of the desired type
FunRequest setHost(String host) FunRequest setApiName(String apiName) FunRequest setUri(String uri) FunRequest addArgs(Object key, Object value)– add a GET query argument FunRequest addParam(Object key, Object value) – add a POST form parameter FunRequest addJson(Object key, Object value) – add a JSON field FunRequest addHeader(Object key, Object value) – add a header FunRequest addHeader(Header header) – add a header object FunRequest addHeader(List<Header> header) – bulk add headers FunRequest addCookies(JSONObject cookies) – add cookies as a header FunRequest setHeaders(List<Header> headers) – replace the whole header list FunRequest setArgs(JSONObject args), setParams(JSONObject params), setJson(JSONObject json) – bulk replace payload objects JSONObject getResponse() – execute the request and return the response as a
JSONObjectRequest creation
The getRequest() method builds the underlying HttpRequestBase based on requestType. If uri is empty it concatenates host and apiName. For GET it calls FanLibrary.getHttpGet(uri, args). For POST it chooses the appropriate overload of FanLibrary.getHttpPost depending on whether params or json is populated. All configured headers are added to the request before it is returned.
Cloning
The clone() method creates a new FunRequest and copies the original request via cloneRequest(HttpRequestBase base). The static cloneRequest extracts the HTTP method, URI, and all headers from the original request. For GET it simply creates a new FunRequest with the same URI and headers. For POST it reads the entity, determines the content‑type, and reconstructs the request with the same JSON, form data, or raw text payload.
Usage example
FunRequest req = FunRequest.isPost()
.setHost("https://api.example.com")
.setApiName("/login")
.addJson("user", "alice")
.addJson("pwd", "secret")
.addHeader("Content-Type", "application/json");
JSONObject resp = req.getResponse(); // executes the request
FunRequest copy = req.clone(); // independent copy for another threadBy providing a serializable, cloneable wrapper and a custom deep‑copy routine, FunRequest enables safe concurrent creation and reuse of HTTP request objects, eliminating side‑effects caused by sharing a mutable HttpRequestBase instance.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
