一、Web运作原理探析
==Key:理解Web的概念及其运作原理。==
1.1、Web概念与特征
1990年,互联网之父Berners-Lee在自己编写的图形化Web浏览器"WorldWideWeb"上成功的访问了第一个名为"nxoc01.cern.ch"的Web服务器。经过几十年的发展,如今,Web是网络上使用最广泛的分布式应用架构,它旨在共享分布在网络上的各个Web服务器中的所有互相链接的信息。
Web使用HTML超级文本技术链接网络上的信息,采用客户/服务器通信模式,客户与服务器之间用HTTP超文本传输协议通信。==归纳其特征为以下三点==:
- 使用HTML超级文本技术表达信息、建立信息与信息的链接
- 采用统一资源定位符URL精确定位网络资源。URL是专为标识网络上的资源位置而设计的编制格式(编址格式:应用层协议+IP地址/域名+资源路径)
- 服务器与用户代理之间的数据交换遵循HTTP协议
1.2、HTTP协议简介
==Web的核心是HTTP协议,Web的客户端和服务器能够交流的前提是遵循HTTP协议。HTTP协议是应用层协议,建立在TCP/IP基础之上,其规定了Web的基本运作过程,以及用户代理与Web服务器之间的通信细节。==
HTTP协议规定的信息交换过程如下:
当用户输入一个URL地址时,用户代理会生成一个HTTP请求,建立与远程HTTP服务器的TCP连接,然后把HTTP请求发送给远程HTTP服务器,HTTP服务器再返回包含响应网页数据的HTTP响应,用户代理接收到这个响应后进行展示。当用户代理与服务器数据交换完毕,就会断开连接。
==HTTP的请求格式和响应格式==
HTTP协议规定,HTTP的请求由3部分构成,分别是:
- 请求方法、URI和客户端HTTP协议版本
- 请求头,包含许多有关客户端环境和请求正文的有用信息,如声明浏览器的类型,请求正文的类型和长度等
- 请求正文,协议规定请求头与请求正文之间必须以空行分隔,该空行表示请求头部分已结束
HTTP响应也由3部分构成,分别是:
- 服务器端HTTP协议的版本,状态码和描述
- 响应头,同请求头,响应头包含服务器类型,正文类型和长度等有用信息
- 响应正文
二、Tomcat简介
==Key:Tomcat作为Web容器的基本功能==
2.1、Web服务器和Servlet
在介绍Tomcat之前,建议先读这篇文章梳理清楚Web应用,Web服务器和Tomcat的关系,有助于理解Tomcat的由来和所扮演的角色:
原文链接:https://www.cnblogs.com/vipyoumay/archive/2017/08/31/7455431.html
《一文看懂web服务器、应用服务器、web容器、反向代理服务器区别与联系》
==阅读上文可知,随着Web服务器朝着企业级应用方向发展,一些Web程序开发框架横空出世(如Tomcat),它们不解决具体的业务问题,只关注Web开发过程中的通用逻辑,如应用的快速部署、统一配置,通信、安全性和性能问题等。而业务逻辑则由应用软件开发商实现。开发人员只需将应用发布到Web服务器上运行即可。==
可是Web应用和Web服务器作为两个不同的软件系统,它们之间如何进行协作?遵循中介方制定的标准接口是方案的一种。SUN公司作为Java语言的创建者,制定了Web应用和Web服务器进行协作的一系列标准Java接口(统称Java Servlet API),对Web服务器发布及运行Web应用的细节作了规约,它们统称为Servlet规范。
中介方规定:
- Web服务器可以访问任意一个Web应用中实现Servlet接口的类
- Web应用中用于被Web服务器动态调用的程序代码位于Servlet接口的实现类中
Servlet最常见的用途是扩展Web服务器的功能。它完全由Java编写,运行在服务器端,可被服务器动态加载并执行。
==因Web应用发布和运行在Web服务器中,因此我们将遵循Servlet规范的Web服务器又称为Web容器或Servlet容器。== Tomcat就是由Apache开源组织创建的优秀的Servlet容器,想获取更多内容请移步Tomcat官网:http://tomcat.apache.org/
2.2、Tomcat作为Servlet容器的基本功能
==简单来说,Tomcat作为运行Servlet的容器,其基本功能是负责接收和解析来自客户的请求,同时把客户的请求传送给相应的Servlet,并把Servlet的响应结果返回给客户。==
Servlet规范规定的Servlet容器响应客户请求访问特定Servlet的流程如下:
- 用户代理发出要求访问特定Servlet的请求
- Servlet容器接收到客户请求并解析
- Servlet容器创建ServletRequest对象,该对象包含了客户请求信息及其他关于客户的信息
- Servlet容器创建ServletResponse对象
- Servlet容器将步骤3和步骤4创建的ServletRequest对象和ServletResponse对象作为参数传递给客户所请求的Servlet的service()方法
- Servlet从ServletRequest对象中获取客户的请求信息
- Servlet利用ServletResponse对象生成响应结果
- Servlet容器把Servlet生成的响应结果发送给客户
2.3、Tomcat必知必会及机制
Tomcat遵循Servlet规范,其响应客户请求访问特定Serlvet的流程在上一节中已作描述
-
Tomcat目录结构:其目录结构依赖于Tomcat自身实现,与Servlet规范无关。/conf/server.xml用于描述容器组件,常见的"Address already in use:bind"错误可通过修改该文件配置修复;/lib目录中的jar包不仅能被Tomcat访问,还能被所有发布在tomcat中的应用访问。而javaWeb应用中的lib子目录只能被当前JavaWeb应用访问
==Tomcat为JavaWeb应用加载类的加载机制:JavaWeb应用的WEB-INF/classes目录-->WEB-INF\lib目录下的jar包-->Tomcat的lib目录-->tomcat的lib目录中的jar包。在上述所有目录中查找未果,程序会抛出异常。==
开发时大家可能遇到过这种情况,程序中成功引用了某个类的方法,运行时却报classNotFound错误,原因很可能是程序引用的是Tomcat的lib目录中jar的类,但应用的lib下也存在一个同名的jar包,不过版本与前者不同。根据Tomcat的类加载机制,它会成功加载应用下的jar包中的class,因版本不同该class中没有程序中引用的方法那么就会报classNotFound错误
Tomcat既可以运行采用开放式目录结构的Web应用,也可以运行Web应用的war文件。Tomcat服务器启动时,会把webapps目录下所有WAR文件自动展开为开放式的目录结构
Web应用的默认URL入口是Web应用的根目录名
Tomcat的<Context>元素的使用可以帮助我们更灵活的发布web应用
三、创建一个JavaWeb应用
==Key:如何编写一个Demo程序==
3.1、JavaWeb应用的定义
先看一下JavaWeb的定义:
SUN的Servlet规范对JavaWeb应用的定义:JavaWeb应用由一组Servlet/JSP、HTML文件、相关Java类,以及其他可以被绑定的资源构成,它可以在由各种供应商提供的符合Servlet规范的Servlet容器中运行。
3.2、JavaWeb应用的目录结构
为了让Servlet容器能顺利的找到JavaWeb应用中的各个组件,Servlet规范规定,JavaWeb应用必须采用固定的目录结构,每种类型的组件在Web应用中都有固定的存放目录。应用的配置信息必须存放在WEB-INF/web.xml文件中,Servlet容器从该文件中读取配置信息。
因此我们在开发Web应用时,需严格遵循上述规定。JavaWeb应用的目录结构如下面的图表所示:
如今我们在开发应用程序时已经很少亲自去构建应用程序目录,强大的IDE会将这些“杂活”处理妥当。
3.3、照书创建1个JavaWeb应用helloapp
对于helloapp应用的构建,只关注其组件构成和运行逻辑。
helloapp应用包含如下组件:
HTML组件:login.htm,作为登陆页面,该组件包含登录表单,用户提交表单后会触发HTTP请求到服务器,服务器根据web.xml发布描述符中的配置信息,将请求映射到特定Servlet处理
Servlet组件:DispatcherServlet类,被Web容器动态调用,它从ServletRequest对象中获取表单数据并处理,可重定向至特定JSP,这里用到的是服务器端重定向
-
JSP组件:hello.jsp,在此案例中用于展示Servlet类的处理结果,它将作为响应返回到客户端并重新渲染客户端页面
图示是服务器端重定向示意图,原图引自《Head First Servlets and JSP》,了解更多服务器端重定向和客户端重定向知识请移步 https://blog.csdn.net/bluishglc/article/details/7953614 ==服务器端程序编写完成后,需要编辑供web.xml,Servlet容器在加载和启动JavaWeb应用时会读取应用的web.xml文件,从中获得关于当前Web应用的发布信息。web.xml中包含有<servlet>和<servlet-mapping>标签,后者配置了URL所映射的servlet,前者配置了servlet对应的class文件。因此,在上述配置完备的情况下,只需给定一个合法的URL,web容器就能访问到相应的Servlet程序。==
配置Servlet映射有两个好处:简化Servlet的URL,并且可以向客户端隐藏Web应用的实现细节;为一个Servlet对应多个URL提供方便的设置途径
==上述所有组件需按照上一节给出的目录结构部署到应用中!==
3.4、发布JavaWeb应用
按照你所了解的方式发布应用即可。
四、Servlet的生命周期
Servlet是JavaWeb应用的核心组件,熟知其生命周期有助于理解JavaWeb应用的运行机制。Servlet生命周期分为3个阶段:
- 初始化阶段:容器首先加载Servlet类,把.class文件的数据读入内存。接下来容器创建包含初始化参数的ServletConfig对象和Servlet对象,并将ServletConfig对象作为参数传递给Servlet对象的init(ServletConfig config)方法
- 运行时阶段:本阶段中容器接收到客户端请求时,会代劳解析HTTP请求参数并创建针对这个请求的HttpServletRequest对象和HttpServletResponse对象,然后调用相应Servlet对象的service()方法处理请求及生成响应结果。容器返回结果给客户端时,会销毁ServletRequest和ServletResponse对象
- 销毁阶段:web应用被终止时,容器首先调用所有Servlet对象的destroy()方法,然后销毁Servlet对象和关联的ServletConfig对象。
Servlet与JavaWeb应用的生命周期相生相伴:
- 启动阶段:容器在JavaWeb启动时将web.xml的数据加载到内存,为JavaWeb应用创建ServletContext对象,并初始化所有的过滤器和需要在应用启动阶段初始化的Servlet
- 运行时阶段:此阶段所有Servlet处于待命状态随时可以响应客户端请求
- 终止阶段:销毁所有处于运行时的Servlet对象、Filter对象及相关的对象和资源
ServletContext对象与web应用具有同样长的生命周期,且可被应用中的所有Web组件共享,适合存取Web应用范围内的共享数据。
五、JSP技术
现在都流行前后端分离开发部署了,这一章可以先放一放。
六、数据库
6.1、JDBC存在的意义
几乎所有的应用软件都离不开数据的存储和访问,JDBC(Java DataBase Connectivity)作为Java程序和数据库服务器通信的纽带,其实现封装了与各种数据库服务器通信的细节,为我们访问数据库提供了极大的便利。优点列举:
- 为开发人员封装好模板程序,如建立数据库连接,释放资源等操作,简化了访问数据库的程序代码,Java程序直接调用JDBC API即可访问数据库,无须涉及与数据库服务器通信的细节
- 不依赖特定数据库平台,各家数据库厂商均已基于自身产品特点实现了JDBC,应用程序只需引入对应厂商实现的JDBC jar包,即可在多种数据库平台间无缝迁移
6.2、如何进行数据库驱动
JDBC的实现包含3个部分:
- JDBC驱动管理器:主要是java.sql.DriverManager类。负责注册特定JDBC驱动程序
- JDBC驱动程序API:主要接口是java.sql.Driver,各数据库厂商或第三方需实现此接口完成JDBC驱动程序的功能实现
- JDBC驱动程序:JDBC驱动程序API的实现,负责特定数据库的连接、处理通信细节等。
综上,JDBC驱动程序是真正的连接Java应用程序与数据库的纽带。Java应用程序如果希望访问某种数据库,必须先获得相应的JDBC驱动程序类库,然后将其注册到JDBC驱动程序管理器。通过DriverManager提供的getConnection方法建立数据库Connection,通过在数据库连接url中添加前缀来指定要驱动的数据库程序:
String url= "jdbc:mysql://127.0.0.1:3306/mi_user";
Connection con=DriverManager.getConnection(url,userName,pwd);
JDBC驱动程序管理器运用了桥梁设计模式,桥接模式是一种结构型设计模式,它的主要特点是把抽象与行为实现分离开来,分别定义接口,可以保持各部分的独立性以及应对他们的功能扩展。桥梁模式使得应用程序只需和JDBC API打交道,JBC API依赖DriverManager类管理JDBC驱动程序。当应用程序需要向数据库提交任务时,DriverManager类会委派特定的驱动程序来执行任务。
JDBC驱动程序加载过程
6.3、数据源(DataSource)简介
建立数据库连接消耗:
- 为连接分配系统资源
- 数据库服务端校验用户名和密码
- Java程序将代表连接的java.sql.connection对象加载到内存中
可见每次与数据库建立连接的开销很大。而数据源会事先建立多个数据库连接,并保存在连接池中,当应用程序需要访问数据库时,直接从池中取出空闲状态的数据库连接,使用完成后再放回连接池以此提高访问数据库的效率,降低资源开销。
6.4、小结
数据库相关技术使得我们的应用程序与数据库连接是松耦合的,它通过封装了目标源的位置信息,验证信息、建立与关闭连接的操作,为我们屏蔽了底层数据库的差异和繁琐操纵过程。
开发人员只需在配置文件中指定数据源类型,数据库驱动程序和目标源的URL,框架或容器就会帮助我们完成Driver的注册,然后利用数据源实现特定数据库的连接并根据配置信息对连接进行池话。当应用程序想要访问数据库时,只需从数据源中取出连接使用即可,其他的一切过程对开发人员来说都是透明的。当某一天想要使用新的数据库技术来替代时,无需修改代码,替换配置即可。
7、HTTP会话与管理
8、开发Javamail Web应用
9、Web应用的MVC设计模式
MVC和核心设计理念是组件化,解耦合。