2023-09-13  阅读(0)
原文作者:https://blog.csdn.net/wangwei19871103/category_9681495_2.html 原文地址: https://blog.csdn.net/wangwei19871103/article/details/104565414

HTTP的基本知识

其实这个到处都有,我就讲几点Netty里比较关注的。首先先看下这个协议的格式,这个是请求,响应差不多的:

202309132207366201.png
找个真实的数据看看:
这个是POST方法的:

202309132207380362.png
这个是GET的:

202309132207391623.png
至于区别什么的百度下吧,这里就想说几个点,Netty里会碰到。

POST消息体传输方式

直接发送消息体

最长见的就是直接在POST请求头里设置了Content-Length属性,也就是所谓的定长,只要接收端根据这个去读定长的字节就行,这个方便是方便,但是如果一个比较大的数据,可能要消耗比较大的内存。

块传输

还有一种是Transfer-Encoding: chunked,然后消息体可以分成好几次传,有一定的格式规范,这个其实就可以降低接收端的内存消耗,特别是一些不定长的数据。比如要从数据库里源源不断的读消息传出去,你可能不知道总共有多大,只有读了才知道。

Netty关于HTTP设计的一些类的简单介绍

其实有很多相关的接口,真的很多,所以打算画个结构图,大致了解下他们的用途和之间的关系,虚线框表示是接口,主要netty相同消息行部分消息头都抽离出来了,最后进行一个整合。后面会稍微介绍下,具体还是看源码比较好:

202309132207398844.png

DecoderResult编码结果

要对HTTP数据解码,得有个成功失败的结果吧。这个就是封装了编码的结果,主要有成功失败还未完成

202309132207409315.png

DecoderResultProvider编码结果提供器

用来设置和获取编码结果。

    public interface DecoderResultProvider {
    
        DecoderResult decoderResult();
    
        void setDecoderResult(DecoderResult result);
    }

HttpObject编码结果提供接口

其实是一个Http编码结果提供接口,唯一的方法还被标记弃用了:

202309132207416676.png

ByteBufHolder对HTTP消息体的一些操作

这个主要是针对接受和发送的消息体缓冲区的一些操作和管理。

    public interface ByteBufHolder extends ReferenceCounted {
    
        /**
         * Return the data which is held by this {@link ByteBufHolder}.
         */
        ByteBuf content();
    
        /** 深拷贝一份
         * Creates a deep copy of this {@link ByteBufHolder}.
         */
        ByteBufHolder copy();
    
        /** 浅拷贝副本
         * Duplicates this {@link ByteBufHolder}. Be aware that this will not automatically call {@link #retain()}.
         */
        ByteBufHolder duplicate();
    
        /** 保留的这个副本
         * Duplicates this {@link ByteBufHolder}. This method returns a retained duplicate unlike {@link #duplicate()}.
         *
         * @see ByteBuf#retainedDuplicate()
         */
        ByteBufHolder retainedDuplicate();
    
        /** 创建一个新的
         * Returns a new {@link ByteBufHolder} which contains the specified {@code content}.
         */
        ByteBufHolder replace(ByteBuf content);
    
        @Override
        ByteBufHolder retain();
    
        @Override
        ByteBufHolder retain(int increment);
    
        @Override
        ByteBufHolder touch();
    
        @Override
        ByteBufHolder touch(Object hint);
    }

HttpMessage协议和头信息接口

公共的就是协议版本号和一些头信息

202309132207423597.png

HttpContent消息体接口

202309132207443808.png

LastHttpContent最后一个消息体接口

最后接受的一个消息体,头信息是空的。

202309132207451489.png

2023091322074684110.png

HttpRequest包含请求行和请求头的接口

请求行相关独有接口,无消息体接口。

    public interface HttpRequest extends HttpMessage {
        HttpMethod method();
        HttpRequest setMethod(HttpMethod method);
        String uri();
        HttpRequest setUri(String uri);
        @Override
        HttpRequest setProtocolVersion(HttpVersion version);
    }

HttpResponse包含响应行和响应头的接口

响应行相关独有接口,无消息体接口。

2023091322074748911.png

FullHttpMessage请求和响应的通用HTTP信息接口

2023091322074839512.png
除了请求行的方法和URI和相应行的状态码之外的所有通用HTTP信息,也就是消息头,协议版本,消息体。

FullHttpRequest完整HTTP请求消息接口

2023091322074892713.png

FullHttpResponse完整HTTP响应消息接口

2023091322074944814.png
基本的介绍完了,其他的都整合基本的,自己看下就好了。

Netty有关Http的编解码器

HttpRequestDecoder请求解码器

首先会将请求行和请求头解析出来,根据请求头中是否有Content-Length或者Transfer-Encoding: chunked属性来判断是否还需要进行解码,如果需要,还持续进行解码,直到把消息体全部收完为止,而且期间会解码一次传递一次消息,因此自定义的处理器会不断的收到消息,第一次是消息行和消息头,后面就是消息体,直到收到最后一次消息体才会结束。基本上是按这么解码的,每一块都会被向后传递:

2023091322075005015.png
如果是比较大的包,比如文件,可以直接用这个,块传输,边传输边进行其他操作,比如一遍下载一遍看视频,断点续传啊这类。占用内存少,接受一个处理完可以释放内存,或者复用。

HttpObjectAggregator消息聚合器

在后面加在处理器,这个就是可以解决上面的问题,可以把消息聚合成一个复合缓冲区,一起给后面的处理器,直接封装成AggregatedFullHttpRequest类型传递下去。这样就不需要在处理器中判断是否接受到一半的逻辑了。但是这个有一个指定接受的长度限制,超过长度了直接就丢弃不处理了。主要可以用于接收一些相对较小的消息,不用后面处理器再去判断是否是个完整的包,但是如果包很大可能占用很大内存。

基本的先了解这些,其实里面还有很多,有了这些理解的基础才可以去看,不然看到那么多接口和类真的很晕。后面的内容在讲具体解码流程的时候会有更多的介绍。

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文