web 相信大家都不陌生,平常我们浏览网页用的都是web服务。互联网起初的web就是非常简单的页面,但是随着客户需求越来越复杂,需要的功能越来越多,我们的服务器端需要处理的请求越来越多,需要区分不同的请求,还需要按照不同请求进行请求数据的提取以及资源的分配和运算还有逻辑的处理,最后还需要响应给客户端,这就使得服务器端 代码越来越复杂,实现越来越困难。根据以往的经验,双方进行通信只需要遵循一定的规则就可以很明确地知道各部分数据的含义,于是出现了网络更上层的应用协议(后面讲的 HTTP 协议),规定 服务器 端和客户端通信的规则。客户端请求 服务器端和服务器端响应客户端,都按照固定的规则,那么接收请求和相应数据这部分操作就可以固定下来,交给特定的一段代码来执行,从而减少 服务器端的代码量,于是出现了各种web框架;如果大家想了解更加深入的话,就去了解web的发展历程吧,其中有不少有趣的小故事啊,这里就不详细赘述了。
一,socket通信
说起web,肯定离不开tcp协议和http协议(https协议较为复杂,暂时不在本章讨论范围之内)。http协议在后面,那什么是tcp协议,cp协议就是网络的传输层面的东西,就是用来传输数据的,tcp协议相对安全可靠,主要连接过程如下图,客户端先发送一个SYN请求,包含一个随机数seq,假设这个随机数的值等于i。服务器就会发送一个ACK请求,并且对这个随机数加1,同时发给客户端,客户端收到服务端的ack之后也会向服务端发送一个ack(这里只是大概描述了一下tcp三次握手,如果想详细了解的话可以去看tcp/ip协议卷)
http是应用层的协议,它的传输层是tcp协议。可以说sock通信是web服务的底层通信,没有socket也就没有http协议,跟谈不上web服务了
二,体系架构
主要有c/s 架构和b/s架构,c/s 主要由一般需要在客户端安装的应用程序和远程服务器组成的。它的优点是通信双方的通信量较少,因为大部分信息存储在本地,缺点是客户端的维护和升级较为麻烦,一般适用于大型的系统。
b/s架构是由浏览器和服务器组成的,优点是方便,随时可以上网,缺点是通信量较大,相对于c/s不是特别的稳定;
c/s 架构
b/s架构
三,web应用程序的工作原理
web应用程序大致上分为两种,即动态网站和静态网站。静态网站就是用HTML写的静态页面,动态网站是根据用户不同的请求动态的生成动态的不同的页面发送给客户端,通常使用HTML语言和动态脚本语言(ASP,PHP,JSP)等语言编写。下面的图片来源于网络
在开发 Web 应用程序时,通常需要应用客户端和服务器端两方面的技术。其中,客户端应用的技术主要用于展现信息内容,而服务器端应用的技术,则主要用于进行业务逻辑的处理和与数据库的交互等。
四,HTTP协议
为了使互联网的web服务茁壮的发展,让客户端和服务端共同的遵守一些协议,http就出现了。http协议可以说是最伟大的协议之一,主要有1.0版本,1.1版本和2.0版本。在浏览器中的书写格式是http://127.0.0.1:80/mysite/index,主要由 http协议://ip地址:端口 / 资源地址 组成的,这也是常说的URL,URL也是URI的一种形式,有兴趣的可以查一下URL和URI有什么区别;
http的请求报文
请求格式:
请求行
请求头1
请求头2
.........
请求空行
请求正文
请求行由请求方式(get和post),请求资源地址,协议(http/1.1) 组成
请求头由报头域组成 每一个报头域都是由名字+“:”+空格+值组成,消息报头域的名字是大小写无关的。
请求正文(也有的叫请求体):只有post有请求正文,get是没有的
注意:请求头和请求正文之间必须有一个空白行的。
请求头
http的响应报文
响应格式:
状态行
响应头1
响应头2
..........
响应空行
响应正文
状态行由协议(http/1.1 状态码 状态码的描述)
响应头由报头域组成 每一个报头域都是由名字+“:”+空格+值组成,消息报头域的名字是大小写无关的。
响应正文 一般由HTML组成
注意:响应头与响应正文之间必须有一个空白行
响应头
响应正文
五,第一servlet的实现
Servlet 是 Server 与 Applet 的缩写,是服务端小程序的意思。使用 Java 语言编写的服务 器端程序,可以像生成动态的 WEB 页,Servlet 主要运行在服务器端,并由服务器调用执行, 是一种按照 Servlet 标准来开发的类。 是 SUN 公司提供的一门用于开发动态 Web 资源的技 术。 (言外之意:要实现 web 开发,需要实现 Servlet 标准)Servlet 本质上也是 Java 类,但要遵循 Servlet 规范进行编写,没有 main()方法,它的创 建、使用、销毁都由 Servlet 容器进行管理(如 Tomcat)。(言外之意:写自己的类,不用写 main 方法,别人自动调用)Servlet 是和 HTTP 协议是紧密联系的,其可以处理 HTTP 协议相关的所有内容。这也是 Servlet 应用广泛的原因之一。提供了 Servlet 功能的服务器,叫做 Servlet 容器,其常见容器有很多,如Tomcat, Jetty, WebLogic Server, WebSphere, JBoss 等。
创建servlet的三种方式:
第一种,继承HttpServlet
1 package test; 2 3 import java.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class Servlet01 extends HttpServlet { 10 11 @Override 12 public void init() throws ServletException { 13 System.out.println("我servlet01诞生了"); 14 15 } 16 17 @Override 18 protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { 19 System.out.println("hello world"); 20 } 21 22 @Override 23 public void destroy() { 24 System.out.println("我servlet01要圆寂了"); 25 } 26 27 28 }
第二方式 ,继承GenericServlet
1 package test; 2 3 import java.io.IOException; 4 5 import javax.servlet.GenericServlet; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletResponse; 11 12 public class Servlet02 extends GenericServlet{ 13 @Override 14 public void init() throws ServletException { 15 System.out.println("我servlet02诞生了"); 16 } 17 18 @Override 19 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { 20 System.out.println("service...servlet02...."); 21 HttpServletResponse hsr=(HttpServletResponse)res; 22 hsr.getWriter().write("hello world"); 23 24 } 25 26 @Override 27 public void destroy() { 28 System.out.println("我servlet02要走向死神的怀抱了"); 29 } 30 31 32 }
第三种方式,实现Servlet接口
1 package test; 2 3 import java.io.IOException; 4 import javax.servlet.Servlet; 5 import javax.servlet.ServletConfig; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 10 public class Servlet03 implements Servlet{ 11 12 @Override 13 public void init(ServletConfig config) throws ServletException { 14 System.out.println("servlet03的初试化"); 15 16 } 17 18 @Override 19 public ServletConfig getServletConfig() { 20 // TODO Auto-generated method stub 21 return null; 22 } 23 24 @Override 25 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { 26 // TODO Auto-generated method stub 27 System.out.println("servlet03。。。。。"); 28 } 29 30 @Override 31 public String getServletInfo() { 32 // TODO Auto-generated method stub 33 return null; 34 } 35 36 @Override 37 public void destroy() { 38 // TODO Auto-generated method stub 39 System.out.println("servlet03的销毁。。。。。。。"); 40 } 41 42 }
servlet的工作原理
执行过程客户端发出请求 根据 web.xml 文件的配置,找到对应的读取中的值 找到对应的 找到该 class 并加载执行该 class,返回结果 由 Web 服务器将结果响应给客户端
web.xml的配置如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>test</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>Servlet01</servlet-name> <servlet-class>test.Servlet01</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet01</servlet-name> <url-pattern>/s01</url-pattern> </servlet-mapping> <servlet> <servlet-name>Servlet02</servlet-name> <servlet-class>test.Servlet02</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet02</servlet-name> <url-pattern>/s02</url-pattern> </servlet-mapping> <servlet> <servlet-name>Servlet03</servlet-name> <servlet-class>test.Servlet03</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet03</servlet-name> <url-pattern>/s03</url-pattern> </servlet-mapping> </web-app>
servlet的生命周期
Servlet 没有 main()方法,不能独立运行,它的运行完全由 Servlet 引擎来控制和调度。 所谓生命周期,指的是 servlet 容器何时创建 servlet 实例、何时调用其方法进行请求的处理、 何时并销毁其实例的整个过程。(此处讨论默认的生命周期)实例和初始化时机当请求到达容器时,容器查找该 servlet 对象是否存在,如果不存在,则会
创建实例并 进行初始化。就绪/调用/服务阶段有请求到达容器,容器调用 servlet 对象的 service()方法,处理请求的方法在整个声明周 期中可以被多次调用;HttpServlet 的 service()方法,会依据请求方式来调用 doGet()或者 doPost()方法。但是, 这两个 do 方法默认情况下,会抛出异常,需要子类去 override。
销毁时机当容器关闭时(应用程序停止时),会将程序中的 Servlet 实例进行销毁。上述的生命周期可以通过 Servlet 中的生命周期方法来观察。在 Servlet 中有三个生命周 期方法,不由用户手动调用,而是在特定的时机有容器自动调用,观察这三个生命周期方法 即可观察到 Servlet 的生命周期。init 方法,在 Servlet 实例创建之后执行(证明该 Servlet 有实例创建了)。
servlet的配置
Servlet 除了配置基本的访问信息,还可以配置初始化参数,自启动等,并且一个 Servlet 可以配置多个访问路径(),还可以使用通配符“ * ”
xml配置初试化参数
<servlet> <servlet-name>Servlet03</servlet-name> <servlet-class>test.Servlet03</servlet-class> <init-param> <param-name>name</param-name> <param-value>liu</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Servlet03</servlet-name> <url-pattern>/s03</url-pattern> </servlet-mapping>
servlet的init方法中打印初始化参数信息
@Override public void init(ServletConfig config) throws ServletException { System.out.println("servlet03的初试化"); String name=config.getInitParameter("name"); System.out.println(name); }
<load-on-startup>2</load-on-startup>表示容器启动时就要创建servlet的对象,2表示启动的等级,数字1等级最高,即容器启动时,先创建1等级的servlet对象,当1等级的创建完成之后再创建2等级的servlet对象;