Tomcat 服务器

  • Servlet 的JavaEE 中指定了一套标准,目前主要的用途就是写web 应用(web application)。
  • Tomcat是一个免费的开源的 Servlet容器,Tomcat服务器是一个开源的轻量级Web应用服务器,是开发和调试Servlet、JSP 程序的首选。
  • Tomcat处理静态HTML的能力不如Apache服务器。

tomcat的相关配置建议参考文章:https://mp.weixin.qq.com/s/P64rWr80M2wZffj4uT2Kfg

server.xml配置文件详解:https://blog.csdn.net/u_ascend/article/details/80433978#title3-5

tomcat原理:https://blog.csdn.net/u014231646/article/details/79482195

1 Servlet

Servlet(Server Applet)是 Java Servlet 的简称,是使用 Java 语言编写的运行在服务器端的程序。具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。

  • 通常来说,Servlet 是指所有实现了 Servlet 接口的类。
  • Servlet 主要用于处理客户端传来的 HTTP 请求,并返回一个响应,它能够处理的请求有 doGet() 和 doPost() 等。
  • Servlet 由 Servlet 容器 提供,Servlet 容器是指提供了 Servlet 功能的服务器(如 Tomcat)。
  • Servlet 容器会将 Servlet 动态加载到服务器上,然后通过 HTTP 请求和 HTTP 响应与客户端进行交互。

Servlet 应用程序的体系结构:
在这里插入图片描述
在图中,Servlet 的请求首先会被 HTTP 服务器(如 Apache、tomcat) 接收,HTTP 服务器只负责静态 HTML 页面的解析,而 Servlet 的请求会转交给 Servlet 容器,Servlet 容器会根据 web.xml 文件中的映射关系,调用相应的 Servlet,Servlet 再将处理的结果返回给 Servlet 容器,并通过 HTTP 服务器将响应传输给客户端。

(1)Servlet对象的生命周期:

Servlet接口定义了5个方法,其中前三个方法与Servlet生命周期相关:

  • init(ServletConfig config)
  • service(ServletRequest req, ServletResponse resp)
  • destory()
  • getServletInfo()
  • getServletConfig()

Java web应用的生命周期是Servlet容器(tomcat)来控制的,而作为Java web应用的核心组件——Servlet,它的生命周期也是由 Servlet容器 来控制的。其生命周期大致分为三个阶段:初始化阶段运行时阶段销毁阶段
在这里插入图片描述
我们在使用Tomcat时,实例化都是交给Tomcat内部进行处理的,Tomcat内部规定在实例化Servlet对象之后(为了提升效率,Servlet的对象都是单例的),一定会调用一次init()。所以如果我们想要对实例化的对象进行一些操作,可以重写init()方法。同理destroy是对象销毁之前调用的。

1)初始化阶段:

  • Web容器加载Servlet类并创建Servlet对象,Servlet容器会运行该对象的init()方法对该对象进行初始化;

2)运行阶段:

  • 请求到达时,Servlet容器会针对该请求创建ServletRequest对象和ServletResponse对象,然后调用相关Servlet对象的service()方法,service()方法会根据请求调用对应的doGet或doPost等方法;

3)销毁阶段

  • Java web应用被终止时,Servlet容器会调用所有Servlet对象的destroy()方法(释放Servlet对象所占用的资源),

对于每个Servlet对象的init方法和destory方法在其生命周期内只会执行一次,service方法客户端每次请求Servlet都会执行。Servlet中有时会用到一些需要初始化与销毁的资源,因此可以把初始化资源的代码放入init方法中,销毁资源的代码放入destroy方法中,这样就不需要每次处理客户端的请求都要初始化与销毁资源。

(8)Servlet 对象工作在多线程环境下
因为tomcat 内部使用线程处理每个请求,而且每个servlet 对象只会存在一个,所以我们覆写的doGet/doPost方法,是在多线程环境下运行的,需要考虑到线程安全问题。

注意:
多线程的并发的读写Servlet类属性会导致数据不同步。但是如果只是并发地读取属性而不写入,则不存在数据不同步的问题。因此Servlet里的只读属性最好定义为final类型的。

参考博客:https://blog.csdn.net/ThinkWon/article/details/104903925

2 Tomcat 的安装

下载Tomcat完成之后直接解压即可。

解压后的文件夹说明:
bin\ 存放各种启动、停止脚本的。.sh 是以后在linux 上用的,.bat 是在windows 上用的
startup.bat 启动服务,双击即可使用
conf\ 相关的配置文件,目前我们不用关心
lib\ 运行tomcat 需要的类库,我们不关心
logs\ 运行时的日志文件,我们有时需要查看日志,来发现定位一些问题
temp\ 临时文件夹,不关心
webapps\ 存放我们要运行的web application 的文件夹,对于我们最常用的一个文件夹
work\ Tomcat 内部进行预编译的文件夹,我们不关心

双击bin\startup.bat 启动。
请求http://127.0.0.1:8080/时,访问的其实就是webapps\ROOT\ 文件夹下的应用。
1
若出现启动或者访问异常可以参考博客

webapps 下的每个文件夹都对应着一个web 应用,所以可以在浏览器中分别访问

http://127.0.0.1:8080/docs/
http://127.0.0.1:8080/examples/
http://127.0.0.1:8080/host-manager/
http://127.0.0.1:8080/manager/
3 静态资源和动态资源访问

在tomcat 的webapps 下新建一个myworld文件夹,并且按照如下分级建好各级文件夹(classes与web.xml同级),黑色字体都是固定名称,不可随意更改。
1

index.html的内容:

<html>
	<head>
		<meta charset="utf-8">
	</head>
	<body>
		<h1> hello world </h1>
	</body>
</html>

web.xml的内容:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1">

    <servlet>
      <servlet-name>Hello</servlet-name>
      <servlet-class>HelloServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>Hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

HelloServlet.java 的内容:
在编写HelloServlet.java时需要在idea中导入tomcat 文件夹下lib 中的servlet-api.jar 包,导包参考博客

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

// 显示的内容,是在运行期间决定的
public class HelloServlet extends HttpServlet {
    // 当 GET 请求时的处理逻辑
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name"); 
        if (name == null) {
            name = "world";
        }
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().println("<h1>GET</h1>");
        resp.getWriter().println("<p>hello" + name + "</p>");
    }
    // 当 POST 请求时的处理逻辑
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf-8");
        resp.getWriter().println("<h1>POST</h1>");
        resp.getWriter().println("<p>hello world</p>");
    }
}

接下来,我们把HelloServlet.java 编译成HelloServlet.class,并将其放入classes目录下,之后,可以通过http://127.0.0.1:8080/myworld/ 访问我们的静态资源index.html。通过http://127.0.0.1:8080/myworld/hello 访问我们写好的动态资源HelloServlet 类。

注意:

  • 静态访问,就是单纯的html等文件的直接访问。而动态访问是让url和程序连接起来,进而达到一个动态访问资源的效果。
  • 在public class HelloServlet extends HttpServlet {}中可以加入一个注解@WebServlet("/hello"),这样就可以替代web.xml中的内容,让tomcat根据/hello可以直接找到HelloServlet. 但是web.xml中不能存在metadata-complete="true"这一句。
@WebServlet("/hello"public class HelloServlet extends HttpServlet {}
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐