轻量级 HTTP 请求组件

这篇具有很好参考价值的文章主要介绍了轻量级 HTTP 请求组件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Apache HttpClient 是著名的 HTTP 客户端请求工具——现在我们模拟它打造一套简单小巧的请求工具库, 封装 Java 类库里面的 HttpURLConnection 对象来完成日常的 HTTP 请求,诸如 GET、HEAD、POST 等等,并尝试应用 Java 8 函数式风格来制定 API。

<dependency>
    <groupid>com.ajaxjs</groupid>
    <artifactid>ajaxjs-net</artifactid>
    <version>1.0.2</version>
</dependency>

组件源码在:https://gitee.com/sp42_admin/ajaxjs/tree/master/aj-backend/aj-framework/aj-net。

发送 HTTP GET 请求

发送 HTTP GET 请求如下代码所示。

// 请求百度网站,返回网站的 HTML 内容
String html = Get.get("https://www.baidu.com").toString();

框架约定,所有 HTTP 请求返回特定的结果:ResponseEntity,包含了关于请求相关的设置和响应内容。典型地toString()返回响应内容的文本格式。ResponseEntity 是一个 Java Bean,字段如下。

public class ResponseEntity {
    /**
        * 返回响应文本结果
        */
    @Override
    public String toString() {
        return ResponseHandler.stream2Str(this).getResponseText();
    }

    /**
        * 连接对象
        */
    private HttpURLConnection connection;

    /**
        * 请求地址
        */
    private String url;

    /**
        * 请求方法
        */
    private String httpMethod;

    /**
        * 请求参数
        */
    private Map params;

    /**
        * 是否成功(http 200 即表示成功,4xx/500x 表示不成功)
        */
    private boolean isOk;

    /**
        * 程序异常,发生时间比 HTTP 请求靠前,例如非法网址,或者 dns 不存在的 UnknownHostException
        */
    private Exception ex;

    /**
        * HTTP 状态码
        */
    private Integer httpCode;

    /**
        * 响应消息字符串
        */
    private String responseText;

    /**
        * 结果的流
        */
    private InputStream in;
}

有时候我们需要获取响应的 HTTP 状态码,那么读取这个ResponseEntity.getHttpCode()就可以了。有的时候甚至不要读取内容,例如获取重定向地址,例如 HTTP HEAD 请求(下面会讲)。

配置 HTTP 请求

一般情况下,需要在请求发起之前进行诸多的配置,除了 HTTP 方法、URL、参数这些之外,请求框架还应该提供对 HTTP Header 的配置。在 Java 中实际是围绕 HttpURLConnection 对象进行配置。怎么才可以灵活地配置呢?此处我们引入函数接口Consumer<HttpURLConnection>,即可添加头字段。重载的get()方法如下。

/**
* GET 请求,返回文本内容
*
* @param url 请求目标地址
* @param fn  自定义 HTTP 头的时候可设置,可选的
* @return 响应的内容
*/
public static ResponseEntity get(String url, Consumer fn);

// 例子
ResponseEntity result = Get.get("http://abc.com", conn -> {
    conn.setRequestProperty("Content-Type", "application/json");
    conn.setRequestProperty("Authorization", "Bearer " + admin.getAccessToken());
});
框架提供常用的配置的 lambda,如指定 From POST 等等,参见 SetConnection 类。

/**
 * 为初始化 HTTP Connection 所准备的函数。该类不能创建实例
 * 
 * @author Frank Cheung
 *
 */
public abstract class SetConnection {
    /**
     * 设置 POST 方式
     */
    public final static Consumer SET_FORM_POST = conn -> conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

    /**
     * 设置响应 JSON
     */
    public final static Consumer SET_JSON = conn -> conn.setRequestProperty("Content-type", "application/json");

    /**
     * 设置启动 GZip 请求
     */
    public final static Consumer SET_GIZPREQUEST = conn -> conn.addRequestProperty("Accept-Encoding", "gzip, deflate");
    ……
}

为了额外传参数来实施控制,还有其他静态方法返回Consumer<HttpURLConnection>。实际这些是Consumer<HttpURLConnection>的“高阶函数”。例如:

/**
    * 设置超时 (单位:秒)
    */
   public final static Consumer setTimeout(int timeout) {
       return conn -> conn.setConnectTimeout(timeout * 1000);
   }

   /**
    * 请求来源
    */
   public final static Consumer setReferer(String url) {
       return conn -> conn.addRequestProperty("Referer", url); // httpUrl.getHost()?
   }

   /**
    * 设置 cookies
    */
   public final static Consumer setCookies(Map""> map) {
       return conn -> conn.addRequestProperty("Cookie", MapTool.join(map, ";"));
   }

只要都是Consumer<HttpURLConnection>类型则可以链式调用,如SET_FORM_POST.andThen(SET_JSON)

GZip

多数 HTTP 资源允许 GZip 压缩,那样传输效率更高。这时请求头须带上 GZip 打开的标识才可以,也就是说请求头加入了上面的Accept-Encoding字段,一般情况下服务器才会对内容进行 GZip 压缩,否则就不压缩,原文输出。 但有些网站是不管有没有这种请求都一概返回 GZip 的。如果有 GZip,服务器会在响应头中加入Content-Encoding的字段告诉我们的。

处理响应结果

HTTP 是文本协议,于是一般情况下toString()即可返回响应的文本内容。 针对常见 Restful API 返回 JSON,框架提供api()的方法返回 JSON。apiXml()则返回 XML 内容。无论结果 JSON 还是 XML 都使用Map<String, Object>作为容器。

/**
 * GET API,返回 JSON
 *
 * @param url 请求目标地址
 * @param fn  自定义 HTTP 头的时候可设置,可选的
 * @return 响应的 JSON,Map 格式
 */
public static Map<String, Object> api(String url, Consumer fn)public static Map<String, Object> api(String url)public static Map<String, String> apiXML(String url, Consumer fn)public static Map<String, String> apiXML(String url)

如果 API 返回 JSON 数组则返回List<Map<String, String>>,请使用:

public static List<Map<String, Object>> apiList(String url, Consumer fn);
public static List<Map<String, Object>> apiList(String url)

文件下载

HTTP 响应内容在底层处理中被视为输入流 InputStream。文本操作只是转换流的形式之一 我们还可以把流转换为文件,即“远程文件下载到本地磁盘”的功能。ResponseHandler 是这么一个处理 InputStream 的类。

/
* 下载二进制文件
* @param url 请求目标地址
* @param saveDir 保存的目录
* @param newFileName 是否有新的文件名,如无请传 null
* @return 下载文件的完整磁盘路径
*/
public static String download(String url, String saveDir, String newFileName);

// 用法
String url = "https://bbsimage.res.meizu.com/forum/2019/01/23/153122zrz85kuvubbiibbs.jpg";
assertNotNull(Get.download(url, "c:/temp", null));

发送 HTTP HEAD 请求

HEAD 方法也是 HTTP 标准方法之一。像获取资源体积大小、获取 302 重定向调转地址、资源是否 404 那样的请求,着实无须 GET 方法,使用 HEAD 即可。各种 HEAD 请求的用法已封装,参见下面的测试用例。

// 获取资源文件体积大小
long size = Head.getFileSize("http://c.yssmx.com/jifen/images/xunzhang/xunzhang/bokezhuanjiamiddle.png");
assertEquals(size, 4102L);

// 获取 302 重定向跳转地址
System.out.println(Head.get302redirect("https://baidu.com"));

// 请求检测是否 404
assertTrue(!Head.is404("http://c.yssmx.com/jifen/images/xunzhang/xunzhang/bokezhuanjiamiddle.png"));

发送 HTTP POST/PUT 请求

关于 POST 的配置和用法大体和 GET 相似,比较不同的是一般要指定 POST 出去的数据,即 POST 参数,可以为StringMap<String, Object>byte[]类型。

// POST Map 参数
String result = Post.post("http://localhost:8080/post.jsp", new HashMap<>() {
    private static final long serialVersionUID = 1L;
    {
        put("foo", "bar");
    }
});

// POST 字符串参数
result = Post.post("http://localhost:8080/post", "a=1&b=2&c=3");

// api
Post.api(...);
Post.apiXML(...);

PUT 方法为Post.put()/Post.putApi()

发送 DELETE 请求

比较简单,暂且不提。

原理分析

有关原理的分析,请移步至博客文章:https://blog.csdn.net/zhangxin09/article/details/86668854、https://blog.csdn.net/zhangxin09/article/details/51836563。文章来源地址https://www.toymoban.com/news/detail-789456.html

到了这里,关于轻量级 HTTP 请求组件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • QtWebApp介绍、下载和搭建http轻量级服务器Demo

    QtWepApp是一个C++中的HTTP服务器库,其灵感来自Java Servlet。适用于Linux、Windows、Mac OS和Qt Framework支持的许多其他操作系统。   QtWebApp包含以下组件: • HTTP(S)1.0和1.1服务器 • 模板引擎 • 缓冲记录器   这些组件可以相互独立地使用。一个非常小的用法示例: 官方: http:

    2024年02月12日
    浏览(68)
  • 扔掉okhttp、httpClient,这款轻量级 HTTP 神器好用到爆

    前言 功能特性 快速使用 HTTP请求相关注解 配置项说明 高级功能 全局拦截器 调用适配器和数据转码器 总结 在 SpringBoot 项目直接使用 okhttp 、 httpClient 或者 RestTemplate 发起 HTTP 请求,既繁琐又不方便统一管理。因此,在这里推荐一个适用于 SpringBoot 项目的轻量级HTTP客户端框架

    2024年02月07日
    浏览(48)
  • C++轻量级Web服务器TinyWebServer源码分析之http篇

    http类这篇个人觉得是最难同时也是最繁琐的一篇,本篇在基础知识方面,包括epoll、HTTP报文格式、状态码和有限状态机,不做赘述,所有源码分析的篇章基础知识会做单开一篇或者读者可以看 小白一文看懂社长服务器 来补基础知识。真的佩服那个叫社长的男人,我读代码且

    2024年02月10日
    浏览(34)
  • Mainflux IoT:Go语言轻量级开源物联网平台,支持HTTP、MQTT、WebSocket、CoAP协议

    Mainflux是一个由法国的创业公司开发并维护的 安全、可扩展 的开源物联网平台,使用 Go语言开发、采用微服务的框架。Mainflux支持多种接入设备,包括设备、用户、APP;支持多种协议,包括HTTP、MQTT、WebSocket、CoAP,并支持他们之间的协议互转。 Mainflux的南向接口连接设备,北

    2024年02月01日
    浏览(90)
  • Qt+QtWebApp开发笔记(一):QtWebApp介绍、下载和搭建基础封装http轻量级服务器Demo

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130631547 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中… 上一篇:没有了 下一篇:《Qt+Q

    2024年02月05日
    浏览(32)
  • cpp-httplib: 轻量级、高性能的C++ HTTP/HTTPS客户端和服务器库

    cpp-httplib 是一个轻量级且高效的 C++ HTTP/HTTPS 客户端和服务器库。它由 Hideaki Sone(yhirose)开发,并在 MIT 许可下发布。该项目的主要目标是提供一种简单易用的方式,在 C++ 应用程序中实现 HTTP 和 HTTPS 功能。 项目仓库地址:https://gitcode.com/yhirose/cpp-httplib cpp-httplib 可用于以下场

    2024年04月09日
    浏览(55)
  • Python实现轻量级WEB服务器接收HTTP提交的RFID刷卡信息并回应驱动读卡器显示播报语音

     本示例使用的设备:RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com)

    2024年02月12日
    浏览(25)
  • PHP实现轻量级WEB服务器接收HTTP提交的RFID刷卡信息并回应驱动读卡器显示播报语音

     本示例使用的读卡器:RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com)

    2024年02月12日
    浏览(27)
  • 界面组件DevExpress WPF v23.2 - 更轻量级的主题支持

    DevExpress WPF Subscription拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 DevExpress WPF控件日前正式发布了近

    2024年02月02日
    浏览(45)
  • Ip-Limit: 轻量级注解式IP限流组件(一)

    基于JVM缓存的轻量级、注解式IP限流组件,方便项目快速引用,满足多线程场景。 默认为滑动窗口限流器,内置令牌桶限流器,可通过注解的属性配置修改 项目Github地址: https://github.com/DDAaTao/ip-limiter 项目Gitee地址:https://gitee.com/fanwentaomayun/ip-limiter 使用样例 包含较为详细的

    2024年02月16日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包