Web 了解和 Servlet 初次见面

五、Tomcat

5.1 什么是 Tomcat

  Tomcat 是一个符合 JavaEE WEB 标准的最小的 WEB 容器,所有的 JSP 程序一定要有 WEB 容器的支持才能运行,而且在给定的 WEB 容器里面都会支持事务处理操作。

  Tomcat 是由 Apache 提供的(www.apache.org),可以用安装版和解压版,安装版可以在服务中出现一 Tomcat 的服务,免安装没有,开发中使用免安装版。 Tomcat 简单的说就是一个运行 Java 的网络服务器,底层是 Socket 的一个程序,它也是 JSP 和 Servlet 的一个容器。Tomcat 是 Apache 软件基金会(Apache Software Foundation)的 Jakarta 项目中的一个核心项目,由 Apache、Sun和其他一些公司及个人共同开发而成。

  由于有了 Sun 的参与和支持,最新的 Servlet 和 JSP 规范总是能在 Tomcat 中得到体现。因为 Tomcat 技术先进、性能稳定,而且免费,因而深受 Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的 Web 应用服务器

  Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试 JSP 程序的首选。 对于一个初学者来说,可以这样认为,当在一台机器上配置好 Apache 服务器,可利用它响应 HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上 Tomcat 部分是 Apache 服务器的扩展,但它是独立运行的,所以当你运行 tomcat 时,它实际上作为一个与 Apache 独立的进程单独运行的。

  当配置正确时,Apache 为 HTML 页面服务,而 Tomcat 实际上是在运行 JSP 页面和 Servlet。另外,Tomcat 和 IIS 等 Web 服务器一样,具有处理 HTML 页面的功能,另外它还是一个 Servlet 和 JSP 容器,独立的 Servlet 容器是 Tomcat 的默认模式。不过,Tomcat 处理静态 HTML 的能力不如 Apache 服务器。目前 Tomcat 最新版本为 9.0。

5.2 安装 Tomcat

  运行 Tomcat 需要 JDK 的支持【Tomcat 会通过 JAVA_HOME 找到所需要的 JDK】。安装就是解压缩过程。启动 Tomcat,能访问则算安装好了

  1、解压

  2、ROOT 目录中查看 index.html 或 index.jsp 文件

  Tomcat8 中自带了页面,而 tomcat7 免安装下没有,如果直接访问会出 404 Tomcat7.XXX 则需要查看 webapps->ROOT 目录中是否有 index.html 或者 index.jsp,如果没有则自己手动添加一个 html 文件或者到其他地方拷贝一份 jsp,此时能访问该页面则是配置成功。

  3、启动 Tomcat (在 tomcat 的安装目录下的 bin 目录 使用命令行启动 tomcat)

  启动后启动窗口不能关闭

[外链图片转存失败(img-n02rtymk-1562919807933)(https://raw.githubusercontent.com/Cushier/picture/master/20190308110402.png)]

  4、打开浏览器输入 http://localhost:8080/ 访问

[外链图片转存失败(img-6tipbMbg-1562919807935)(https://raw.githubusercontent.com/Cushier/picture/master/20190308110903.png)]

  OK,Tomcat 安装成功。

  5、关闭 Tomcat (在 tomcat 的安装目录下的 bin 目录 使用命令行关闭 tomcat)

5.3 Tomcat 目录结构

  1. bin:启动和关闭 tomcat 的 bat 文件
  2. conf:配置文件server.xml 该文件用于配置 server 相关的信息,比如 tomcat 启动的端口号,配置主机(Host) web.xml 文件配置与 web 应用(web 应用相当于一个 web 站点)tomcat-user.xml 配置用户名密码和相关权限.
  3. lib:该目录放置运行 tomcat 运行需要的 jar 包
  4. logs:存放日志,当我们需要查看日志的时候,可以查询信息
  5. webapps:放置我们的 web 应用
  6. work 工作目录:该目录用于存放 jsp 被访问后生成对应的 server 文件和 .class 文件

5.4 Eclipse 关联 Tomcat

Window→preferences→Server→Runtime Environment→add→apache-tomcat-8.0.23

[外链图片转存失败(img-4IHxBN6z-1562919807946)(https://raw.githubusercontent.com/Cushier/picture/master/20190308115009.png)]

六、HTTP 协议

  HTTP 协议(Hypertext Transfer Protocol,超文本传输协议),是一个客户端请求和回应的标准协议,这个协议详细规定了浏览器和万维网服务器之间互相通信的规则。用户输入地址和端口号之后就可以从服务器上取得所需要的网页信息。

  通信规则规定了客户端发送给服务器的内容格式,也规定了服务器发送给客户端的内容格式。客户端发送给服务器的格式叫“请求协议”;服务器发送给客户端的格式叫“响应协议”。

6.1 浏览器中的书写格式

  在 B/S 体系架构中,客户端都统一成了浏览器,要请求服务器端资源需要通过浏览器进行,此时由浏览器将我们给出的请求解析为满足 HTTP 协议的格式并发出。则我们发出的请求格式需要按照浏览器规定的格式来书写,在浏览器中书写格式如下:

[外链图片转存失败(img-U51VJf51-1562919807947)(https://raw.githubusercontent.com/Cushier/picture/master/20190308163251.png)]

  当浏览器获取到信息以后,按照特定格式解析并发送即可。接收到服务器端给出的响应时,也按照 HTTP 协议进行解析获取到各个数据,最后按照特定格式展示给用户。

6.2 HTTP 协议的主要特点

  1.)支持 客户 / 服务器 模式。

  2.)简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有 GET、POST。每种方法规定了客户与服务器联系的类型不同。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。

  3.)灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记。

  4.)HTTP1.1 支持持续连接。通过这种连接,就有可能在建立一个 TCP 连接后,发送请求并得到回应,然后发送更多的请求并得到更多的回应。通过把建立和释放 TCP 连接的开销分摊到多个请求上,则对于每个请求而言,由于 TCP 而造成的相对开销被大大地降低了。而且, 还可以发送流水线请求,也就是说在发送请求 1 之后的回应到来之前就可以发送请求 2,也可以认为,一次连接发送多个请求,由客户机确认是否关闭连接,而服务器会认为这些请求分别来自不同的客户端。

  5.)无状态:HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

6.3 HTTP之URL

  http(超文本传输协议)是一个基于请求与响应模式的、应用层的协议,常基于 TCP 的连接方式,绝大多数的 Web 开发,都是构建在 HTTP 协议之上的 Web 应用。

  HTTP URL (URL 是一种特殊类型的 URI,包含了用于查找某个资源的足够的信息)的格式 如下:

  http://host[":"port][abs_path]

  http 表示要通过 HTTP 协议来定位网络资源;host 表示合法的 Internet 主机域名或者 IP 地址;port 指定一个端口号,为空则使用缺省端口 80;abs_path 指定请求资源的 URI;如果 URL 中没有给出 abs_path,那么当它作为请求 URI 时,必须以“/”的形式给出,通常这个工作浏览器自动帮我们完成。

6.4 HTTP 请求

  http 请求由三部分组成,分别是:请求行请求头请求正文

  通过chrome浏览器,F12→Network 查看

  get(没有请求体)

[外链图片转存失败(img-1CvrOWi9-1562919807953)(https://raw.githubusercontent.com/Cushier/picture-java/master/middle/Servlet/20190704180141.png)]

  post

[外链图片转存失败(img-xEifNOEP-1562919807954)(https://raw.githubusercontent.com/Cushier/picture-java/master/middle/Servlet/20190704180253.png)]

  格式

  请求首行(请求行)

  请求头信息(请求头)1

  请求头信息2

  …

  请求空行

  请求体

  请求行以一个方法符号开头,以空格分开,后面跟着请求的 URI 和协议的版本,格式如下:Method Request-URI HTTP-Version CRLF 其中 Method 表示请求方法;Request-URI 是一个统一资源标识符;HTTP-Version 表示请求的 HTTP 协议版本;CRLF 表示回车和换行

6.5 HTTP 响应

  在接收和解释请求消息后,服务器返回一个 HTTP 响应消息。HTTP 响应也是由三个部分组成,分别是:状态行、消息报头、响应正文

  格式

  状态行

  响应头1

  响应头2

  …

  响应空行

  响应体

6.6 消息头

  HTTP 消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行),消息报头(可选),空行(只有 CRLF 的行),消息正文(可选)组成。

  每一个报头域都是由名字+“:”+空格+值组成,消息报头域的名字是大小写无关的。

请求头

  请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。

  Refere:该请求头指明请求从哪里来

  如果是地址栏中输入地址访问的都没有该请求头地址栏输入地址,通过请求可以看到,此时多了一个 Referer 的请求头,并且后面的值为该请求从哪里发出。百度竞价,只能从百度来的才有效果,否则不算;通常用来做统计工作、防盗链

响应头

  响应报头允许服务器传递不能放在状态行中的附加响应信息,以及关于服务器的信息和 对 Request-URI 所标识的资源进行下一步访问的信息。

  Location:Location响应报头域用于重定向接受者到一个新的位置。Location响应报头域,常用在更换域名的时候。response.sendRedirect(“http://www.pxcoder.com”);

  Refresh:自动跳转(单位是秒),可以在页面通过meta标签实现,也可在后台实现。

<meta http-equiv=”refresh” content=”3;url=http://www.pxcoder.com”>

七、第一个 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 等等。

7.1 实现

1)创建动态 web 项目

2)新建类

package com.xxx.web;

public class HelloWeb {

}

3)实现 Servlet 规范

实现 Servlet 规范,即继承 HttpServlet 类,并导入相应的包,该类中已经完成了通信的规则,我们只需要进行业务的实现即可。

package com.xxx.web;

import javax.servlet.http.HttpServlet;

public class HelloWeb extends HttpServlet {

}

4)重写 service 方法

满足 Servlet 规范只是让我们的类能够满足接收请求的要求,接收到请求后需要对请求进行分析,以及进行业务逻辑处理,计算出结果,则需要添加代码,在规范中有一个叫做 service 的方法,专门用来做请求处理的操作,业务代码则可以写在该方法中。

package com.xxx.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloWeb extends HttpServlet {

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("I received a request");
		resp.getWriter().write("<h1>Hello World!</h1>");
	}

}

5)配置 web.xml

在完成好了一切代码的编写后,还需要向服务器说明,特定请求对应特定资源,此时通过一个名叫 web.xml 的配置文件完成。

<!-- 配置servlet -->
<servlet>
  <servlet-name>helloweb</servlet-name><!-- 给服务器看的 -->
  <servlet-class>com.xxx.web.HelloWeb</servlet-class><!-- servlet对应的资源路径 -->
</servlet>
<servlet-mapping>
  <servlet-name>helloweb</servlet-name><!-- 给服务器看的 -->
  <url-pattern>/helloweb</url-pattern><!-- 给浏览器看的,对外访问路径 -->
</servlet-mapping>

[外链图片转存失败(img-p7ui1gCl-1562919807962)(https://raw.githubusercontent.com/Cushier/picture-java/master/middle/20190709160334.png)]

6)发布项目

到此,需要编写和配置的地方已经完成,项目已经完整了,但是如果需要外界能够访问, 还需要将项目发布到服务器上并运行服务器。

[外链图片转存失败(img-UDgilIhj-1562919807963)(https://raw.githubusercontent.com/Cushier/picture/master/middle/20190311144945.png)]

[外链图片转存失败(img-J7GNZsFu-1562919807965)(https://raw.githubusercontent.com/Cushier/picture/master/middle/20190311145027.png)]

7)启动项目

看到类似一长串信息表示启动成功,接下来就可以访问项目了

8)访问并查看结果

在项目正确发布到服务器上之后,用户即可通过浏览器访问该项目中的资源。注意 url 的格式正确,tomcat 的端口为 8080。http://localhost:8080/hw/helloweb,页面结果

后台结果

到这里我们的第一个 Servlet 就实现了!

7.2 工作原理

执行过程

客户端发出请求根据 web.xml 文件的配置,找到对应的 url-pattern 读取其中的值,找到对应的 servlet-name,找到指定的 class 并加载执行该 class,返回结果由 Web 服务器将结果响应给客户端

[外链图片转存失败(img-QPIHov38-1562919807980)(https://raw.githubusercontent.com/Cushier/picture/master/middle/20190311152246.png)]

7.3 Servlet 的生命周期

  Servlet 没有 main() 方法,不能独立运行,它的运行完全由 Servlet 引擎来控制和调度。所谓生命周期,指的是 servlet 容器何时创建 servlet 实例、何时调用其方法进行请求的处理、并何时销毁其实例的整个过程。(此处讨论默认的生命周期)

  • 实例和初始化时机

当请求到达容器时,容器查找该 servlet 对象是否存在,如果不存在,则会创建实例并进行初始化。

  • 就绪/调用/服务阶段

有请求到达容器,容器调用 servlet 对象的 service() 方法,处理请求的方法在整个生命周期中可以被多次调用;

HttpServlet 的 service() 方法,会依据请求方式来调用 doGet() 或者 doPost() 方法。但是,这两个 do 方法默认情况下,会抛出异常,需要子类去 override。

  • 销毁时机

当容器关闭时(应用程序停止时),会将程序中的 Servlet 实例进行销毁。

上述的生命周期可以通过 Servlet 中的生命周期方法来观察。在 Servlet 中有三个生命周期方法,不由用户手动调用,而是在特定的时机由容器自动调用,观察这三个生命周期方法即可观察到 Servlet 的生命周期。

init 方法,在 Servlet 实例创建之后执行(证明该 Servlet 有实例创建了)

    public void init(ServletConfig config) throws ServletException {
        System.out.println("有实例创建了");
    }

service 方法,每次有请求到达某个 Servlet 方法时执行,用来处理请求(证明该 Servlet 进行服务了)

	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("服务调用了");
	}

destroy 方法,Servlet 实例销毁时执行(证明该 Servlet 的实例被销毁了)

	public void destroy() {
		System.out.println("有实例被销毁了");
	}

Servlet 的生命周期,简单的概括就分为四步:servlet 类加载→实例化→服务→销毁。下面我们描述一下 Tomcat 与 Servlet 是如何工作的,看看下面的时序图:

1、Web Client 向 Servlet 容器(Tomcat)发出 Http 请求

2、Servlet 容器接收 Web Client 的请求

3、Servlet 容器创建一个 HttpRequest 对象,将 Web Client 请求的信息封装到这个对象中

4、Servlet 容器创建一个 HttpResponse 对象

5、Servlet 容器调用 HttpServlet 对象的 service 方法,把 HttpRequest 对象与 HttpResponse 对象作为参数,传给 HttpServlet 对象

6、HttpServlet 调用 HttpRequest 对象的有关方法,获取 Http 请求信息

7、HttpServlet 调用 HttpResponse 对象的有关方法,生成响应数据

8、Servlet 容器把 HttpServlet 的响应结果传给 Web Client

7.4 Servlet 的配置

Servlet 除了配置基本的访问信息,还可以配置初始化参数,自启动等,并且一个 Servlet 可以配置多个访问路径,还可以使用通配符“*****”。

基本配置

  <servlet>
    <servlet-name>helloweb</servlet-name><!-- 给服务器看的 -->
    <servlet-class>com.xxx.web.HelloWeb</servlet-class><!-- servlet对应的资源路径 -->
  </servlet>
  <servlet-mapping>
    <servlet-name>helloweb</servlet-name><!-- 给服务器看的 -->
    <url-pattern>/helloweb</url-pattern><!-- 给浏览器看的,对外访问路径 -->
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

初始化参数

  <servlet>
    <servlet-name>helloweb</servlet-name><!-- 给服务器看的 -->
    <servlet-class>com.xxx.web.HelloWeb</servlet-class><!-- servlet对应的资源路径 -->
    <!-- 初始化参数 -->
	<init-param>
		<param-name>param1</param-name>
		<param-value>1</param-value>
	</init-param>
	<init-param>
		<param-name>param2</param-name>
		<param-value>2</param-value>
	</init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>helloweb</servlet-name><!-- 给服务器看的 -->
    <url-pattern>/helloweb</url-pattern><!-- 给浏览器看的,对外访问路径 -->
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

自启动

  <servlet>
    <servlet-name>helloweb</servlet-name><!-- 给服务器看的 -->
    <servlet-class>com.xxx.web.HelloWeb</servlet-class><!-- servlet对应的资源路径 -->
    <!-- 初始化参数 -->
	<init-param>
		<param-name>param1</param-name>
		<param-value>1</param-value>
	</init-param>
	<init-param>
		<param-name>param2</param-name>
		<param-value>2</param-value>
	</init-param>
	<!-- 自启动 -->
	<load-on-startup>2</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>helloweb</servlet-name><!-- 给服务器看的 -->
    <url-pattern>/helloweb</url-pattern><!-- 给浏览器看的,对外访问路径 -->
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

servlet-name:Servlet 对象的名称

servlet-class:创建 Servlet 对象所要调用的类

param-name:参数名称

param-value:参数值

load-on-startup:Servlet 容器启动时加载 Servlet 对象的顺序

servlet-mapping/servlet-name:要与 servlet 中的 servlet-name 配置的内容对应

url-pattern:客户访问的 Servlet 的相对 URL 路径

说明:url-pattern 可以配多个(一个 servlet 可以通过多个 url-pattern 访问)当多个 servlet 配置成了同一个 url-pattern,报错 java.lang.reflect.InvocationTargetExceptionion;通配符“*****”只能放在最前面或最后面,不能放中间且不能单独存在(以/分割的,不能和单词组成整体)。越精确越优先。常规配置即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值