{"id":21915739,"url":"https://github.com/admin4j/common-http","last_synced_at":"2025-04-04T23:09:34.988Z","repository":{"id":57732257,"uuid":"490997293","full_name":"admin4j/common-http","owner":"admin4j","description":"HTTP request library packaged specifically for JAVA  ","archived":false,"fork":false,"pushed_at":"2025-03-17T12:15:02.000Z","size":173,"stargazers_count":92,"open_issues_count":1,"forks_count":28,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T22:14:37.199Z","etag":null,"topics":["httputils","java","okhttp"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/admin4j.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-11T07:12:35.000Z","updated_at":"2025-03-17T12:15:06.000Z","dependencies_parsed_at":"2023-11-08T10:42:01.999Z","dependency_job_id":"f6175a9a-d3e2-4fbd-a641-77b62591ea0b","html_url":"https://github.com/admin4j/common-http","commit_stats":{"total_commits":34,"total_committers":2,"mean_commits":17.0,"dds":"0.11764705882352944","last_synced_commit":"6656fedbb6a053b5b91f5bd7d444e730fa8d5c56"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/admin4j%2Fcommon-http","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/admin4j%2Fcommon-http/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/admin4j%2Fcommon-http/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/admin4j%2Fcommon-http/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/admin4j","download_url":"https://codeload.github.com/admin4j/common-http/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247261612,"owners_count":20910108,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["httputils","java","okhttp"],"created_at":"2024-11-28T19:13:57.946Z","updated_at":"2025-04-04T23:09:34.947Z","avatar_url":"https://github.com/admin4j.png","language":"Java","readme":"# OKHttpUtil\n\n在Java的世界中，Http客户端之前一直是Apache家的HttpClient占据主导，但是由于此包较为庞大，API又比较难用，因此并不使用很多场景。而新兴的OkHttp、Jodd-http固然好用，但是面对一些场景时，学习成本还是有一些的。很多时候，我们想追求轻量级的Http客户端，并且追求简单易用。而OKHttp\n是一套处理 HTTP 网络请求的依赖库，由 Square 公司设计研发并开源，目前可以在 Java 和 Kotlin 中使用。对于 Android App\n来说，OkHttp 现在几乎已经占据了所有的网络请求操作，对于服务器端请求外部接口也是必备的选择 。针对OKHttp\nOkHttpUtil做了一层封装，使Http请求变得无比简单。\n\n# OKHttpUtil 功能\n\n- 根据URL自动判断是请求HTTP还是HTTPS，不需要单独写多余的代码。\n- 默认情况下Cookie自动记录，比如可以实现模拟登录，即第一次访问登录URL后后续请求就是登录状态。\n- 自动识别304跳转并二次请求\n- 支持代理配置\n- 支持referer配置\n- 支持User-Agent配置\n- 自动识别并解压Gzip格式返回内容\n- 支持springboot 配置文件\n- 极简的封装调用\n\n# OKHttpUtil使用\n\nmaven引入\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.admin4j\u003c/groupId\u003e\n    \u003cartifactId\u003ehttp\u003c/artifactId\u003e\n    \u003cversion\u003e0.9.5\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n最新版查询 [https://central.sonatype.com/artifact/io.github.admin4j/http](https://central.sonatype.com/artifact/io.github.admin4j/http)\n\n## GET\n\n最简单的使用莫过于用HttpUtil工具类快速请求某个接口：\n\n``` \nResponse response = HttpUtil.get(\"https://github.com/search\", Pair.of(\"q\", \"okhttp\"));\nSystem.out.println(\"response = \" + response);\n```\n\n## POST\n\n一行代码即可搞定，当然Post请求也很简单：\n\n```\n        # JSON 格式的body\n        Response post = HttpUtil.post(\"https://oapi.dingtalk.com/robot/send?access_token=27f5954ab60ea8b2e431ae9101b1289c138e85aa6eb6e3940c35ee13ff8b6335\", \"{\\\"msgtype\\\": \\\"text\\\",\\\"text\\\": {\\\"content\\\":\\\"【反馈提醒】我就是我, 是不一样的烟火\\\"}}\");\n        System.out.println(\"post = \" + post);\n        \n        # form 请求\n        Map\u003cString, Object\u003e formParams = new HashMap\u003c\u003e(16);\n        formParams.put(\"username\", \"admin\");\n        formParams.put(\"password\", \"admin123\");\n        Response response = HttpUtil.postForm(\"http://192.168.1.13:9100/auth/login\",\n                        formParams\n        );\n        System.out.println(\"response = \" + response);\n```\n\n返回格式为JSON的 可以使用 HttpJsonUtil 自动返回JsonObject\n\n```java\n        Map\u003cString, Object\u003e  object=HttpJsonUtil.get(\"https://github.com/search\",\n        Pair.of(\"q\",\"http\"),\n        Pair.of(\"username\",\"agonie201218\"));\n        System.out.println(\"object = \"+object);\n```\n\n## 文件上传\n\n```java\n        File file=new File(\"C:\\\\Users\\\\andanyang\\\\Downloads\\\\Sql.txt\");\n        Map\u003cString, Object\u003e formParams=new HashMap\u003c\u003e();\n        formParams.put(\"key\",\"test\");\n        formParams.put(\"file\",file);\n        formParams.put(\"token\",\"WXyUseb-D4sCum-EvTIDYL-mEehwDtrSBg-Zca7t:qgOcR2gUoKmxt-VnsNb657Oatzo=:eyJzY29wZSI6InpoYW56aGkiLCJkZWFkbGluZSI6MTY2NTMwNzUxNH0=\");\n        Response response=HttpUtil.upload(\"https://upload.qiniup.com/\",formParams);\n        System.out.println(response);\n```\n\n## 下载文件\n\n```java\n   HttpUtil.down(\"https://gitee.com/admin4j/common-http\",\"path/\");\n```\n\n## HttpRequest 链式请求\n\n```java\n\n# get\n        Response response=HttpRequest.get(\"https://search.gitee.com/?skin=rec\u0026type=repository\")\n        .queryMap(\"q\",\"admin4j\")\n        .header(HttpHeaderKey.USER_AGENT,\"admin4j\")\n        .execute();\n        System.out.println(\"response = \"+response);\n\n        # post form\n        Response response=HttpRequest.get(\"http://192.168.1.13:9100/auth/login\")\n        .queryMap(\"q\",\"admin4j\")\n        .header(HttpHeaderKey.USER_AGENT,\"admin4j\")\n        .form(\"username\",\"admin\")\n        .form(\"password\",\"admin123\")\n        .execute();\n        System.out.println(\"response = \"+response);\n```\n\n### 开启日志\n\n```yaml\nlogging:\n  level:\n    io.github.admin4j.http.core: debug\n```\n\npost form 日志\n\n```\n16:49:14.092[main]DEBUG io.github.admin4j.http.core.HttpLogger- --\u003eGET http://192.168.1.13:9100/auth/login?q=admin4j http/1.1\n16:49:14.094[main]DEBUG io.github.admin4j.http.core.HttpLogger-User-Agent:admin4j\n16:49:14.094[main]DEBUG io.github.admin4j.http.core.HttpLogger-Host:192.168.1.13:9100\n16:49:14.094[main]DEBUG io.github.admin4j.http.core.HttpLogger-Connection:Keep-Alive\n16:49:14.094[main]DEBUG io.github.admin4j.http.core.HttpLogger-Accept-Encoding:gzip\n16:49:14.094[main]DEBUG io.github.admin4j.http.core.HttpLogger- --\u003eEND GET\n16:49:14.670[main]DEBUG io.github.admin4j.http.core.HttpLogger-\u003c--200OK http://192.168.1.13:9100/auth/login?q=admin4j (575ms)\n16:49:14.670[main]DEBUG io.github.admin4j.http.core.HttpLogger-transfer-encoding:chunked\n16:49:14.670[main]DEBUG io.github.admin4j.http.core.HttpLogger-Vary:Origin\n16:49:14.670[main]DEBUG io.github.admin4j.http.core.HttpLogger-Vary:Access-Control-Request-Method\n16:49:14.670[main]DEBUG io.github.admin4j.http.core.HttpLogger-Vary:Access-Control-Request-Headers\n16:49:14.670[main]DEBUG io.github.admin4j.http.core.HttpLogger-Vary:Origin\n16:49:14.670[main]DEBUG io.github.admin4j.http.core.HttpLogger-Vary:Access-Control-Request-Method\n16:49:14.670[main]DEBUG io.github.admin4j.http.core.HttpLogger-Vary:Access-Control-Request-Headers\n16:49:14.671[main]DEBUG io.github.admin4j.http.core.HttpLogger-Content-Type:application/json;charset=utf-8\n16:49:14.671[main]DEBUG io.github.admin4j.http.core.HttpLogger-Date:Tue,08Nov 2022 08:49:14GMT\n16:49:14.671[main]DEBUG io.github.admin4j.http.core.HttpLogger-\n16:49:14.671[main]DEBUG io.github.admin4j.http.core.HttpLogger-{\"code\":406,\"msg\":\"Full authentication is required to access this resource\"}\n16:49:14.671[main]DEBUG io.github.admin4j.http.core.HttpLogger-\u003c--END HTTP(76-byte body)\nresponse=Response{protocol=http/1.1,code=200,message=OK,url=http://192.168.1.13:9100/auth/login?q=admin4j}\n```\n\n# 在 Springboot 中使用\n\nmaven引入\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.admin4j\u003c/groupId\u003e\n    \u003cartifactId\u003ecommon-http-starter\u003c/artifactId\u003e\n    \u003cversion\u003e0.9.5\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n最新版查询 [io.github.admin4j:common-http-starter](https://search.maven.org/artifact/io.github.admin4j/common-http-starter)\n\nspring 版可以对 OkHttp进行个性化配置\n配置详见\n\n```java\npublic class HttpConfig {\n\n\n    /**\n     * 日志等级\n     */\n    private HttpLoggingInterceptor.Level loggLevel = HttpLoggingInterceptor.Level.BODY;\n\n    /**\n     * 读取超时时间，秒\n     */\n    private long readTimeout = 30;\n    /**\n     * 链接超时时间\n     */\n    private long connectTimeout = 30;\n\n    private boolean followRedirects = false;\n\n    /**\n     * 最大的连接数\n     */\n    private int maxIdleConnections = 5;\n\n    /**\n     * 最大的kepAlive 时间 秒\n     */\n    private long keepAliveDuration = 5;\n\n    private String userAgent = \"OKHTTP\";\n    /**\n     * 是否支持cookie\n     */\n    private boolean cookie = false;\n    private ProxyConfig proxy;\n\n\n    @Data\n    public static class ProxyConfig {\n\n        private Proxy.Type type = Proxy.Type.HTTP;\n        private String host;\n        private Integer port = 80;\n        private String userName;\n        private String password;\n    }\n}\n\n```\n\n# 如何快速封装外部接口\n\n以实体项目为例，封装 ebay接口\n\n```java\npublic class EbayClient extends ApiJsonClient {\n\n    /**\n     * 店铺配置\n     *\n     * @param storeId\n     */\n    public EbayClient(Long storeId) {\n\n        //TODO 获取店铺相关配置\n        Map\u003cString, String\u003e config = new HashMap\u003c\u003e();\n\n        basePath = \"https://api.ebay.com\";\n        defaultHeaderMap.put(\"Authorization\", \"Bearer \" + config.get(\"accessToken\"));\n        defaultHeaderMap.put(\"X-EBAY-C-MARKETPLACE-ID\", config.get(\"marketplaceId\"));\n    }\n}\n```\n\nEbayClient 封装ebay api请求 基础类\n\n```java\npublic class EbayInventoryClient extends EbayClient {\n\n    /**\n     * 店铺配置\n     *\n     * @param storeId\n     */\n    public EbayInventoryClient(Long storeId) {\n        super(storeId);\n    }\n\n    /**\n     * 库存列表\n     *\n     * @param limit\n     * @param offset\n     * @return\n     * @throws IOException\n     */\n    public Map\u003cString, Object\u003e inventoryItem(Integer limit, Integer offset) throws IOException {\n\n        Map\u003cString, Object\u003e queryMap = new HashMap(2);\n        queryMap.put(\"limit\", limit);\n        queryMap.put(\"offset\", offset);\n        return get(\"/sell/inventory/v1/inventory_item\", queryMap);\n    }\n}\n```\n\nEbayInventoryClient 封装ebay 库存 api请求  \n使用\n\n```java\n        EbayInventoryClient ebayInventoryClient=new EbayInventoryClient(1L);\n        Map\u003cString, Object\u003e jsonObject=ebayInventoryClient.inventoryItem(0,10);\n```\n\n```java\n/**\n * 订单相关api\n *\n * @author andanyang\n * @since 2022/11/8 17:34\n */\npublic class EbayOrderClient extends EbayClient {\n\n\n    /**\n     * 店铺配置\n     *\n     * @param storeId\n     */\n    public EbayOrderClient(Long storeId) {\n        super(storeId);\n    }\n\n    /**\n     * 订单列表\n     *\n     * @param beginTime\n     * @param endTime\n     * @param limit\n     * @param offset\n     * @return\n     */\n    public Map\u003cString, Object\u003e orders(String beginTime, String endTime, int limit, int offset) {\n\n        final String path = \"/sell/fulfillment/v1/order\";\n\n        String filter = MessageFormat.format(\"lastmodifieddate:[{0}..{1}]\", beginTime, endTime);\n\n        //\n        Map\u003cString, Object\u003e queryMap = new HashMap\u003c\u003e(8);\n        queryMap.put(\"filter\", filter);\n        queryMap.put(\"limit\", limit);\n        queryMap.put(\"offset\", offset);\n\n        return get(\"/sell/inventory/v1/inventory_item\", queryMap);\n    }\n}\n```\n\n库存相关的使用`EbayInventoryClient`,订单相关的使用`EbayOrderClient`,是不是很清晰\n\n# JSON 适配器\n\n项目默认使用 fastjson 解析json，如果想用其他json框架.排除`admin4j-json-fastjson`,重新导入其他包参考如下\n\n```\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.admin4j\u003c/groupId\u003e\n    \u003cartifactId\u003ehttp\u003c/artifactId\u003e\n    \u003cversion\u003e0.9.5\u003c/version\u003e\n    \u003cexclusions\u003e\n        \u003cexclusion\u003e\n            \u003cgroupId\u003ecom.admin4j.json\u003c/groupId\u003e\n            \u003cartifactId\u003eadmin4j-json-fastjson\u003c/artifactId\u003e\n        \u003c/exclusion\u003e\n    \u003c/exclusions\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.admin4j.json\u003c/groupId\u003e\n    \u003cartifactId\u003eadmin4j-json-jackson\u003c/artifactId\u003e\n    \u003cversion\u003e0.6.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nJSON 适配工具类参考 [https://github.com/admin4j/admin4j-json](https://github.com/admin4j/admin4j-json)\n\n# Error 报错踩坑\n\n```\n\njava.lang.NoClassDefFoundError: okio.Buffer\n\n\tat okhttp3.ResponseBody$Companion.create(ResponseBody.kt:248)\n\tat okhttp3.ResponseBody$Companion.create$default(ResponseBody.kt:247)\n\tat okhttp3.internal.Util.\u003cclinit\u003e(Util.kt:65)\n\tat okhttp3.HttpUrl$Builder.parse$okhttp(HttpUrl.kt:1239)\n\tat okhttp3.HttpUrl$Companion.get(HttpUrl.kt:1634)\n\tat okhttp3.Request$Builder.url(Request.kt:184)\n\tat io.github.admin4j.http.core.AbstractHttpBuildCall.buildRequest(AbstractHttpBuildCall.java:182)\n\tat io.github.admin4j.http.core.AbstractHttpBuildCall.buildPost(AbstractHttpBuildCall.java:410)\n\tat io.github.admin4j.http.core.AbstractHttpRequest.post(AbstractHttpRequest.java:59)\n```\n\n由于 okio 版本号问题\n具体参考 [记录Maven 依赖包版本号奇奇怪怪的问题 - okhttp3、okio 版本指定无效](https://blog.csdn.net/agonie201218/article/details/131552134)\n\n# 鸣谢\n![IntelliJ IDEA logo](https://resources.jetbrains.com/storage/products/company/brand/logos/IntelliJ_IDEA.png)\n","funding_links":[],"categories":["网络编程"],"sub_categories":["Spring Cloud框架"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadmin4j%2Fcommon-http","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadmin4j%2Fcommon-http","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadmin4j%2Fcommon-http/lists"}