美文网首页
为什么Java需要servlet?

为什么Java需要servlet?

作者: 程序媛小白 | 来源:发表于2021-11-30 17:42 被阅读0次

            servlet翻译过来就叫服务程序,你可以理解为一个http服务器,rpc服务器,或者别的啥服务器都行。

            反正服务程序的核心功能就是接受客户端请求,处理再返回!

            说白了 servlet 就是 web 服务共通部分(TCP socket 监听、TLS 加解密、HTTP 协议的解析、路由机制的实现、并发处理等)和特殊部分(你的业务逻辑)之间的一层胶水。有了 servlet 这套规约,web 服务器(比如 tomcat)可以专注地做它的共通部分而不用管你的特殊部分,而你则可以专注写你的业务逻辑而不用关心共通部分。其他语言的web框架当然也有这种,只不过不叫 servlet 而已,比如 Ruby 语言的生态里有 Puma (相当于 tomcat)和 Rack(相当于 servlet API),Elixir 生态里有 cowboy 和 Plug 等。

    推荐大家2套课程吧,也是我身边很多人都在看的☟☟☟

    【Java300集】全新的Java300集来啦!java零基础小白自学Java必备优质教程

    花2万多买的Java教程全套,现在分享给大家,入门到精通!Java300集_Java程序开发就业教程

            下面先来说说 HTTP 是什么?其实最常见的 HTTP 请求(文件上传不算)就是一段文本,大概长成下面这样:

    POST http://www.example.com/foo/bar?baz=1&qux=haha HTTP/1.0

    Content-Type: application/x-www-form-urlencoded;charset=utf-8

    Content-Length: 11

    Cookie: foo=bar;httpOnly&baz=qux

    Origin: https://www.example.com

    Referer: https://www.example.com/foo.html

    x=1&y=2&z=0

            你在这段文本里会看到 method(开头的那个 POST)、URL、协议及版本号、请求头(从第二行开始一直到第一个空行为止)、以及请求体(第一个空行之后的文本)。

        而最常见的HTTP响应其实也是一段文本,大概长成下面这样

    HTTP/1.0 302 Found

    Content-Type: text/html; charset=utf-8

    Content-Length: 56

    Set-Cookie: sessionid=1acb45fb;httpOnly

    <html><body><h1>You've been redirected.</h1></body></html>

            你在这段文本里能看到协议及版本号、响应状态码(302)、响应状态文本(Found)、响应头(从第二行开始到第一个空行为止),以及响应体(第一个空行之后的内容)。

            你可以想象 Tomcat 干了些啥(默认端口号,不考虑 https 的情况):

            Tomcat 启动后就创建线程池,并开始监听 TCP 端口 8080 (注意是 TCP,不是 HTTP 哦!)

            当有客户端尝试创建 TCP 连接时,接受这个连接,并从线程池里捞一个线程出来,把这个连接扔给那个线程。

            那个线程开始读取从 TCP 连接里发送过来的文本,并按照 HTTP 协议的格式解析这段文本(你可以想象成无非就是搞个 reader 来 readLine 一下啦,然后string.split一下啦,当然实际情况比这复杂一点)。解析结果装进一个 HttpServletRequest 对象。同时,这个线程会 new 一个 HttpServletResponse 对象,用来收集之后你的业务逻辑装进去的响应信息。

            那个线程根据请求路径,找到 web.xml 里配置的 servlet 对象。这个过程就是路由。

            那个线程根据请求的 method 找到那个 servlet 里的 doXxx 方法(比如 doPost),把之前准备好的 request 和 response 对象作为参数来调用那个方法。这时才走进你的业务逻辑!

            当你的对应那个请求的业务逻辑走完后,那个线程回收 request 和 response 对象,并用 response 对象里的数据按照 HTTP 协议的格式要求拼装出 HTTP 响应的文本

            那个线程把拼装出来的文本往那个 TCP 连接里写,写完后正常切断连接,然后把自己扔回线程池。

            可以看到,你的业务逻辑部分只接触到了第5步的后半和第6步的前面一点点,剩下来的部分全都是 web 服务器在替你操心。为什么可以这么做?因为 servlet API 帮你把边界画好了,你就在那条边界里面折腾,别管外面的,而 web服务器就在边界外面折腾,不管里面的。实际情况当然比上面写的7步复杂得多,比如响应并不是全部拼完才写回去,而是拼一点写一点;在请求解析之前,还会有 TLS 解密,读完请求头后还会有请求体解压等。

    相关文章

      网友评论

          本文标题:为什么Java需要servlet?

          本文链接:https://www.haomeiwen.com/subject/lqbdxrtx.html