jquick-curl lets a Java interface method carry a curl command
jquick‑curl: Java library to run raw curl commands, support copy‑paste curl from Postman/Apifox/Browser DevTools, no need to write HTTP client code.
At a glance
- What is it?
- jquick-curl is a Java HTTP client where the request is written as a plain curl command inside an annotation, parsed with ANTLR and executed over a pooled transport, with dynamic proxies, XML configuration and variable substitution on top. The appeal is pasting a request copied from browser dev tools; the trade-off is that the request syntax lives in a string.
- Who is it for?
- jquick-curl suits a Java team that constantly talks to HTTP APIs it does not own, where requests are copied from Postman, Apifox or browser dev tools, and where a probe or one-off integration should not require a hand written HTTP client.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A curl command that is really a method call
jquick-curl is described as a lightweight HTTP client for Java that natively mimics the curl style API: you write a request as a plain curl command and call it as an ordinary Java method. The stated motivation is support for copy-pasting a curl command from Postman, Apifox or browser dev tools, so that no HTTP client code has to be written.
That framing explains the design. Most Java HTTP libraries are typed: you build a request object, set headers, set a body, and the client serialises it. That is the right shape when you own both sides of the contract, because the compiler tells you when a header name changes. It is the wrong shape when you are poking at a third party API you cannot change, because the fastest route to a working request is to copy the one the browser just made.
The library takes the copy-paste route seriously and gives it structure. The feature list runs from a native curl style API through annotation and XML configuration, dynamic proxy clients, variable substitution, conditional rendering, cookie support, the full set of HTTP methods, file transfer, batch execution, timeouts, retries, redirects and connection pooling configured once through JQuickCurlConfig, interceptors, and proxy and SSL handling.
The project is part of the JQuick ecosystem and is maintained by the Dromara open source community, with sibling projects for path handling, Excel, PDF, Java utilities and SQL under the same author, and the artefact is published to Maven Central as io.github.paohaijiao:jquick-curl. The licence is Apache 2.0, the library targets JDK 8 and above, and the repository carries both an English and a Chinese README, a change.log, and separate English and Chinese contribution guides.
ANTLR parses the command, a pooled transport executes it
The mechanism has two halves, and the first one is unusual enough to be worth naming.
Commands are parsed with ANTLR, which is a parser generator, and then executed over a pooled, high performance transport layer. So the curl text in your source is not string-matched and interpreted loosely. It is parsed by a grammar into a command model, which is why the library can support the option surface of curl rather than a hand-picked subset: a request can be described with -X, -H, -d, -b, -c, -F, -o and the rest, and the parser knows what each of them means.
The second half is the transport. Connection pooling, timeouts, retries and redirects are configured once through JQuickCurlConfig rather than per request, which is the difference between a debugging tool and something you would put behind a service boundary. Interceptors exist for the same reason: authentication, logging or request preprocessing can be added globally instead of being repeated in every command.
The request model itself is a small object you pass to the method, JQuickCurlReq, and it is where the runtime values live. Placeholders in the command are resolved at request time, and the library supports two placeholder forms, ${name} and #{name}, so a path segment or a header value can vary per call while the command string stays constant.
Conditional rendering is the other feature that goes beyond curl itself. Headers or options can be rendered only when an XML <if test="..."> expression is true, which means a single declared request can carry several optional headers that appear or disappear based on a condition. That is something you would otherwise have to build in Java, and its presence is a hint that the library is aimed at integration work rather than at being a thin curl emulator.
Declare an interface, create a proxy, call the method
The dependency goes into the project in the usual Maven form:
<dependency>
<groupId>io.github.paohaijiao</groupId>
<artifactId>jquick-curl</artifactId>
<version>2.5.0</version>
</dependency>A request is then declared on an interface method with the @JCurlCommand annotation, and the method returns the response body as a String:
import com.github.paohaijiao.anno.JCurlCommand;
import com.github.paohaijiao.domain.req.JQuickCurlReq;
import com.github.paohaijiao.executor.JCurlInvoker;
public interface UserApi {
// GET request: returns the response body as a String
@JCurlCommand("curl -X GET https://httpbin.org/get")
String list(JQuickCurlReq request);
}The client is a dynamic proxy created from that interface, and calling the method executes the command:
UserApi api = JCurlInvoker.createProxy(UserApi.class);
String body = api.list(new JQuickCurlReq());A POST works the same way, with the method, the header and the JSON body all inside the command string:
public interface OrderApi {
// POST request with a JSON body
@JCurlCommand("curl -X POST https://httpbin.org/post " +
"-H 'Content-Type: application/json' " +
"-d '{\"sku\":\"A-1001\",\"count\":2}'")
String create(JQuickCurlReq request);
}Two details in the code are worth pausing on. First, the method signature takes the request object and returns a String, which means the response is a raw body string with no typed model, and your JSON parsing happens outside the library. Second, the package names are com.github.paohaijiao.* while the Maven groupId is io.github.paohaijiao, a mismatch between the repository the packages were published under and the one the group id names. It is harmless, but it trips up an IDE that tries to resolve the import from the coordinates.
The alternative to annotations is centralised configuration: requests can be declared in an apis.xml file instead, which suits a team that wants the request catalogue in one place, or one that is generating the file.
Cookies, file transfer and running a whole class at once
The cookie support follows native curl, and the behaviour is specified in enough detail to be useful.
The -b and --cookie options send cookies and the -c and --cookie-jar options persist them. Cookies are merged into a single Cookie request header, and every Set-Cookie header can be saved to a Netscape cookie file that acts as a persistent cookie store. Multiple cookies are separated by a semicolon inside one -b option, and both -b and an explicit -H 'Cookie: ...' header end up in the same request header, with repeated names merged rather than overwritten. A single cookie is expressed the same way:
public interface CookieApi {
// Single cookie: -b / --cookie 'name=value'
@JCurlCommand("curl -X GET https://httpbin.org/cookies -b 'sessionId=abc123'")
String withSingleCookie(JQuickCurlReq request);
}The other notable areas are file transfer and batch execution. Multipart upload is done with -F and download with -o or --output, so a request that needs to push a file or pull one does not need a different client. Batch execution means every @JCurlCommand method of a class can be run in a single call, which is the shape you want for a smoke test or a health check suite.
The HTTP method list is the full curl set: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS and TRACE.
Taken together, the feature set is aimed at one workflow: talk to many third party HTTP endpoints, quickly, with the request captured in a form you can paste from a debugging tool. That is also where its limits lie, and the section below is the one to read before you deploy it.
Skipping certificate checks is a supported flag
The feature list includes proxy and SSL handling, with HTTP and SOCKS5 proxy support, and the -k and --insecure options to skip certificate checks.
Supporting -k is reasonable, because curl supports it and people copy commands that contain it. The risk is that the flag is one character away from the request you meant, and unlike a curl command in a terminal, this one ends up in a committed source file, possibly applied to every request that goes through the same configuration or interceptor.
The concrete practice is to keep -k out of the declared requests. If a test environment has a self signed certificate, put the trust anchor in the trust store the JVM uses rather than disabling validation, and if you must use -k, keep it on the single request that needs it rather than in a shared place. A global interceptor that strips verification, or a shared configuration that enables it for convenience, turns every future TLS error into a silent downgrade rather than a visible failure.
The same reasoning applies to the proxy setting. A proxy configured globally is the right choice when all traffic goes through it, and the wrong choice if it was added to reach one host, because it will then apply to every request the client makes.
Interceptors deserve the same scrutiny. Authentication, logging and request preprocessing are applied globally, which is convenient, and global authentication is a place where a mistake is invisible: a request that goes out without the credential is likely to fail loudly at the server, but a request that goes out with the wrong credential, or one that logs a header it should not, is not.
None of this makes the library unsafe by design. It makes the configuration surface worth a review pass, and the shared JQuickCurlConfig is the right place to look.
Apache 2.0, Dromara governance and releases every few weeks
The licence is Apache 2.0, which for a library used inside a proprietary service is the permissive end of the scale: you can use it without publishing anything of your own, and the obligations are the notice and the patent and warranty clauses.
The governance is worth noting because it is different from a single author project. jquick-curl is maintained by the Dromara open source community, and the surrounding JQuick family of libraries is visible in the project header: jquick-path, jquick-excel, jquick-pdf, jquick-java and jquick-sql, plus a separate Javelin artefact link. Being maintained by a community rather than a single author means the roadmap can move with the group's priorities, which is worth weighing for a dependency.
The release record shows an active project with an irregular but quick cadence. The recent tags are v_2.2.0 on 2026-08-25, v_2.3.0 on 2026-08-30 and v_2.6.0 on 2026-09-17, so multiple versions landed within three weeks, and the last push was on 2026-10-15 with the repository not archived. The changelog lives in a change.log file at the root rather than in GitHub releases, so that is where to look for what changed.
One inconsistency to be aware of when you pin a version. The dependency snippet in the documentation shows version 2.5.0, while the published tags have already moved to 2.6.0, so the example is one release behind the latest. That is a documentation lag rather than a real problem, but it is the kind of detail that makes you check the actual artefact in Maven Central instead of trusting the readme, and it is a good habit with a library that releases this often.
The library also advertises JDK 8 and above, which keeps it usable in older enterprise builds, and it appears in the Awesome Java list.
Editorial conclusion
jquick-curl suits a Java team that constantly talks to HTTP APIs it does not own, where requests are copied from Postman, Apifox or browser dev tools, and where a probe or one-off integration should not require a hand written HTTP client. It is the wrong choice if your service calls need a typed, refactorable client, because a curl command in a string is not something a compiler or an IDE can rename or type check, and a poor match where certificate validation must not be optional, since the library supports skipping checks with -k. Before adopting, add the Maven dependency and declare one interface with a single annotated method, then decide in the shared configuration whether proxy, timeout and retry defaults are set centrally through JQuickCurlConfig.
Frequently asked questions
How do I add jquick-curl to a Maven project?
Add the dependency io.github.paohaijiao:jquick-curl to your pom.xml. The quick start in the documentation shows version 2.5.0, while the published tags have reached 2.6.0, so check Maven Central for the version you pin.
How are requests declared in jquick-curl?
Either with the @JCurlCommand annotation on an interface method, or centrally in an apis.xml file. A dynamic proxy created with JCurlInvoker.createProxy turns the interface into a working client, and each method takes a JQuickCurlReq object and returns the response body as a String.
How does jquick-curl handle cookies?
It implements the native curl cookie options, with -b and --cookie for sending and -c and --cookie-jar for persisting. Cookies are merged into a single Cookie request header, and Set-Cookie headers can be saved to a Netscape cookie file used as a persistent cookie store.
What licence is jquick-curl released under?
It is licensed under the Apache 2.0 licence, and the project is maintained by the Dromara open source community as part of the JQuick ecosystem. The library targets JDK 8 and above.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dromara-jquick-curl)Was this useful?