皮皮网

【cd源码输出】【手机编辑源码】【炫播 源码】httpservlet源码

2024-12-27 15:14:53 来源:k线源码

1.pushlet原理
2.四种方法实现http服务
3.Tomcat处理http请求之源码分析 | 京东云技术团队

httpservlet源码

pushlet原理

       Pushlet的基本使用形式极为简单,通常在多媒体视频、通讯应用中,如QuickTime,实现这一功能。Pushlet基于HTTP流技术,cd源码输出与加载HTTP页面后立即关闭连接的做法不同,它采用HTTP流方式主动推送新变更的数据到客户端,且在此期间HTTP连接始终保持打开状态。实现这种Keep-alive长连接的具体技术细节,请参考Sun提供的《HTTP Persistent Connection》和W3C的《HTTP1.1规范》。下面将通过示例来说明如何使用Pushlet。

       示例1:

       我们可以通过开发一个JSP页面,利用HTTP流技术不断向客户端发送新的HTML内容。该页面在一个定时器循环中实现这一功能:

       <%

       int i = 1

       try { while (true) { out.print(""+(i++)+"")

       out.flush()

       try { Thread.sleep()

       } catch (InterruptedException e) { out.print(""+e+"")

       } } } catch (Exception e) { out.print(""+e+"")

       }%>

       上述示例中,我们利用JSP页面不断向客户端推送内容,但这种做法并不实用,因为新内容被机械地、持续不断地添加到页面中,而不是手机编辑源码服务器端更新的内容。

       示例2:

       现在,让我们深入探讨Pushlet的工作原理。通过运行Pushlet的示例源代码(examples/basics/push-js-stream.html),我们可以看到一个每3秒刷新一次的页面。那么它是如何实现的呢?

       此示例包含了三个文件:push-js-stream.html、push-js-stream-pusher.jsp、push-js-stream-display.html。其中,push-js-stream.html为主框架文件,它以HTML Frame形式包含其他两个页面。

       push-js-stream-pusher.jsp是一个JSP,执行在服务器端,其内容如下:

       <%

       /** Start a line of JavaScript with a function call to parent frame. */

       String jsFunPre = " ";

       int i = 1;

       try {

       // Every three seconds a line of JavaScript is pushed to the client

       while (true) {

       // Push a line of JavaScript to the client

       out.print(jsFunPre+"Page "+(i++)+jsFunPost);

       out.flush();

       // Sleep three secs

       try {

       Thread.sleep();

       } catch (InterruptedException e) {

       // Let client display exception

       out.print(jsFunPre+"InterruptedException: "+e+jsFunPost);

       }

       }

       } catch (Exception e) {

       // Let client display exception

       out.print(jsFunPre+"Exception: "+e+jsFunPost);

       }

       %>

       在示例1和示例2中使用JSP时存在一个问题:一些Servlet引擎在某个客户端离开时会“吃掉”IOException,导致JSP页面永远不会抛出此异常。因此,Pushlet采用Servlet的原因之一是能够捕获到IOException。在示例代码的第行,可以看到在一个定时器循环(3秒/周期)中打印了一些HTML内容并输出到客户端浏览器。请注意,炫播 源码这里推送的并非HTML而是JavaScript!

       下面是JavaScript代码示例:

       push-js-stream.html中的push()函数被名为pushletFrame的JSP Frame调用,将传入的参数值写入到displayFrame(此Frame为push-js-stream-display.html)。这是动态HTML的一个小技巧:使用document对象的writeln方法刷新某个Frame或Window的内容。

       displayFrame成为了用于显示内容的、真正的视图。displayFrame初始化为黑色背景并显示“wait…”直到来自服务器的内容被推送过来:

       WAIT...

       这就是Pushlet的基本做法:从Servlet(或示例中的JSP)将JavaScript代码作为HTTP流推送到浏览器。这些代码被浏览器的JavaScript引擎解释并完成一些有趣的工作。因此,实现了从服务器端的Java到浏览器中的JavaScript的回调。

       上述示例展示了Pushlet原理,但存在一些等待解决的问题和需要增强的特性。因此,建立了一个小型的服务器端Pushlet框架,并添加了一些用于客户端的JavaScript库。由于客户端需要依赖更多的DHTML特性(例如Layers),我们首先简要复习一些DHTML知识。示例代码见examples/dhtml。

       DHTML(动态HTML)提供了在浏览器中维护内容、资源论坛源码进行用户交互的扩展能力。就像Java开发者使用Servlet和JSP那样,DHTML也应该是你的工具箱中的一部分。

       DHTML涉及到HTML、级联样式表(CSS)、JavaScript和DOM。传统的页面只能通过重新加载来自服务器的新页面进行更新。DHTML提供了在页面被加载完毕后对浏览器内的HTML文档的完全控制。你应该见过一些带有“图像翻滚”、弹出内容、可收缩菜单功能的网页,它们便是使用DHTML技术实现的。尽管存在一些标准差异(见下面的“跨浏览器DHTML”),大多数兼容JavaScript1.4版本的浏览器(后面将简称为“版本4的浏览器”)都支持DHTML。

       从开发者角度审视浏览器中的整个文档,如Frame、、表格等,它们都可以表示为具有层次的蜂蜜源码对象模式——DOM。通过使用JavaScript可以维护DOM成员,不仅可以改变文档的内容和外观,还可以捕捉例如鼠标移动、form提交这些用户事件,然后对DOM进行相应修改。例如,鼠标移动到上方可以产生“mouse-over”事件,这时通过显示高亮版本的或弹出解释性文字的方式修改页面外观。这听起来不错吧!我们现在就熟悉一下DHTML标准!但谁定义了DHTML标准?

       这是DHTML初学者首先遇到的问题。首先,你需要一个版本4以上的浏览器。DHTML相关规范的官方标准出自World Wide Web Consortium (W3)。然而,微软和Netscape出品的版本4以上的浏览器都有一些私有的DHTML扩展,这是你必须注意的。

       幸运的是,大多数用户都有版本4以上的浏览器,并且一些开发者(如Dannymen、Dan Steinman和Danny Goodman)建造了跨越浏览器的、可重用的DHTML库。

       作为一名Java开发者,你应该适当地理解基于对象、甚至面向对象的JavaScript编程。在我的DHTML中你将找到一些示例,但了解更多的DHTML资源也是非常值得的。尤其在使用跨越浏览器的DHTML库对付那些顽固的浏览器问题时,一切都变得有趣、而不是枯燥。

       就如Java获得在广阔的服务器端市场、DHTML在客户端领域具有许多强大特性那样,Pushlet以一种直接的方式将这两项伟大的技术捆绑在一起。接下来的章节将详细讨论Pushlet这个服务器端轻量级框架和客户端DHTML库。

四种方法实现http服务

       当面临非Springboot项目中实现HTTP服务的需求时,有四种方法可供选择:基于Tomcat、Jetty、JdkHttp和Netty。这些内嵌web容器各有特色,适合不同的场景和性能需求。

       Tomcat作为常见的选择,可通过添加Maven坐标并实现初始化代码来实现,如JdkSimpleDispatchServlet所示。它内置了Servlet支持,适用于基础需求。

       Jetty与Tomcat类似,通过启动方法启动,其依赖相对简单。它的服务初始化代码简洁,对于Web支持同样较为全面。

       Netty以其高性能脱颖而出,尤其适合高吞吐量应用。其pom依赖和启动方式都体现了其内置http编解码和协议支持的便利性。

       最后,对于不依赖第三方的选项,JDK8内置的HttpServer提供了一种简单直接的方法。需下载rt包源码并在项目中配置,初始化服务的过程相对直接。

       总的来说,选择哪种方法取决于具体项目的需求,如对Servlet规范的支持、性能要求以及对第三方依赖的考虑。每个选项都有其独特的优势,值得开发者根据实际情况灵活运用。

Tomcat处理http请求之源码分析 | 京东云技术团队

       本文将从请求获取与包装处理、请求传递给 Container、Container 处理请求流程,这 3 部分来讲述一次 http 穿梭之旅。

       在 tomcat 组件 Connector 启动时,会监听端口。以 JIoEndpoint 为例,在 Acceptor 类中,socket = serverSocketFactory.acceptSocket (serverSocket); 与客户端建立连接,将连接的 socket 交给 processSocket (socket) 来处理。在 processSocket 中,对 socket 进行包装,交给线程池处理。

       线程池中的 SocketProcessor 任务,将 socket 交给 handler 处理,此 handler 为 HttpConnectionHandler 的实例。在 HttpConnectionHandler 的父类 process 方法中,根据请求的状态,创建 HttpProcessor 进行相应的处理,然后切到 HttpProcessor 的父类 AbstractHttpProccessor 中。

       在 SocketProcessor 中,从 socket 获取请求数据,进行 keep-alive 处理,数据包装等操作,最终将处理后的请求信息交给了 CoyoteAdapter 的 service 方法。

       CoyoteAdapter 的 service 方法中有两个主要任务:一是将 org.apache.coyote.Request 和 org.apache.coyote.Response 转换为继承自 HttpServletRequest 的 org.apache.catalina.connector.Request 和 org.apache.catalina.connector.Response,同时定位到 Context 和 Wrapper。二是将请求交给 StandardEngineValve 处理。

       在 postParseRequest 方法中,request 通过 URI 的信息找到属于自己的 Context 和 Wrapper。Mapper 保存了所有的容器信息,初始化时将所有容器添加到了 mapper 中。容器信息的变化由 MapperListener 监听,一旦容器发生变化,MapperListener 将其作为监听者进行处理。

       找到请求对应的 Context 和 Wrapper 后,CoyoteAdapter 将包装好的请求交给 Container 处理。从下面的代码片段,我们很容易追踪整个 Container 的调用链,形成时间线图。

       最终,StandardWrapperValve 将请求交给 Servlet 处理完成,至此一次 http 请求处理完毕。