Tomcat 服务器介绍和使用
服务器的概念和作用:
问题:
学习了 java 编程之后,java 代码的一个很重要的作用就是进行数据的处理,但是目前来说我们运行编写的代码,只有一次性,也就是运行完毕后,如果需要再次运行则需要再次手动启动代码的执行。但是我们无法提前用户会何时发送请求,也就无法决定我们编写的 java 代码应该什么时候启动运行。而且手动运行也变得不现实。
解决:
那么根据 java 的网络编内容,我们是不是可以使用代码编写一个容器
(对象) 呢?,该容器可以根据用户的请求来启动并运行我们编写的数据逻辑代码。答案是可以的。
实现:
服务器
流程:客户端请求 ---> tomcat服务器 -->java程序 --->返回相对应的html
解释:
所谓服务器其实就是代码编写的一个可以根据用户请求实时的调用执行对应的逻辑代码的一个容器。在普通用户看来就是一个安装程序。我们只需要将服务器在操作系统上进行安装,并将我们事先编写好的逻辑处理代码根据规则放到服务器的指定位置,启动服务器,那么服务器就自动的会根据接收到请求调用并执行对象的逻辑代码进行处理。
Tomcat 服务的下载和安装:
下载地址:
https://tomcat.apache.org/download-70.cgi
下载选项
安装:
下载成功后会为压缩包文件,解压即可
使用注意:尽量不要解压在中文目录中
目录结构介绍:
Backup 运行时候会备份基础的配置
in 存放启动和关闭 Tomcat 的可执行文件
conf 存放Tomcat 的配置文件
lib 存放库文件
logs 存放日志文件
emp 存放临时文件
webapps 存放web 应用,默认在这里读项目。
work 存放JSP 转换后的Servlet 文件
校验安装:
打开 bin 目录,然后双击执行 startup.bat 文件,打开浏览器在地址栏中输入 localhost:8080/ 如果出现 tomcat 广告页安装成功
常见问题:
1、tomcat 的运行依赖 JDK,必须配置 JDK 环境。配置方式参照: https://jingyan.baidu.com/article/6dad5075d1dc4
0a123e36ea3.html
2、闪退,启动闪退问题一般是因为 JDK 的环境变量配置有问题, 参照 1 进行重新进行配置,如果还是闪退,使用:
在 binstartup.bat 文件中的第一行前面加入: SET JAVA_HOME=JDK 目录
SET CATALINA_HOME=解压后 Tomcat 的目录
这样,运行 startup.bat 就可以正常启动 tomcat 服务器,如果想点击 shutdown.bat 关闭服务器,同样在 shutdown.bat 文件中加入上面的两行即可
在学习了服务器并成功安装后,我们知道当浏览器发送请求给服务器后,服务器会调用并执行对应的逻辑代码进行请求处理。逻辑代码是由程序员自己编写然后放进服务器进行运行,其实就是 Servlet程序。
第一个 Web 程序:
开发工具:
Myeclipse
Myeclipse 安装:
双击执行安装软件,然后一路 next(位数根据电脑的操作系统位数自行选择)。
Myeclipse 的破解:
根据破解文档自行破解。
第一个Web 项目:
1、 打开 Myeclipse 并创建工作空间
2、 点击 file 选择—>new—>web project—>输入项目名,点击finish
3、 在 src 下创建包com.bjsxt.servlet.
4、 在包下创建一个普通 java 类 MyServlet,并继承 HttpServlet
5、 在 MyServlet 类中覆写 service 方法。
6、 在 webRoot 下的 WEB-INF 下找到 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"> <!--配置Servlet --> <!--配置servlet类路径 --> <servlet> <servlet-name>my</servlet-name> <servlet-class>com.bjsxt.servlet.MyServlet</servlet-class> </servlet> <!--配置访问方式 --> <servlet-mapping> <servlet-name>my</servlet-name> <url-pattern>/my</url-pattern> </servlet-mapping> </web-app> |
7、 打开 tomcat 的安装目录,在 webapps 目录下新建文件夹,文件夹名为 project,并将项目源码 webRoot 下的内容全部复制到该文件夹下。
8、 启动 tomcat 服务器,并在地址栏中输入:localhost:8080/project/my
总结:
MyEclipse 是开发工具,通过此工具便于程序员的代码编写。真正运行的代码不是MyEclipse 中编写的代码,而是 tomcat 服务器中部署好的代码。Tomcat 会根据请求自动调用对应的代码进行请求处理。
Eclipse配置Tomcat
1、选择window,设置preferences
2、设置server,选择runtime Environments,点击add
3、选择 tomcat v7.0,点击next
4、选择tomcat 7.0目录地址,设置jdk1.8
Servlet 介绍
问题:
服务器在接收到浏览器的请求后,会自动调用对应的逻辑代码进行请求处理。但是逻辑代码是由程序员编写并放到服务器中,那么服务器怎么知道该怎么调用并调用哪个类和哪个方法来进行请求处理。
解决:
程序员在编写代码的时候如果能够按照服务器能够识别的规则进行编写, 浏览器按照指定的规则进行发送请求,那么服务器就可以调用并执行响应的逻辑代码进行请求处理了。
实现:
Servlet 技术
概念:
狭义的 Servlet 是指 Java 语言实现的一个接口,广义的 Servlet 是指任何实现了这个 Servlet 接口的类,一般情况下,人们将 Servlet 理解为后者。Servlet 运行于支持 Java 的应用服务器中。从原理上讲,Servlet 可以响应任何类型的请求,但绝大多数情况下 Servlet 只用来扩展基于 HTTP 协议的 Web 服务器
请求 ---> Tomcat ---> Servlet(封装的类)--响应输出txt/html/json
特点:
运行在支持 java 的应用服务器上
Servlet 的实现遵循了服务器能够识别的规则,也就是服务器会自动的根据请求调用对应的 servlet 进行请求处理。
简单方便,可移植性强
使用:
1、创建普通的 java 类并继承 HttpServlet
2、覆写 service 方法
3、在 service 方法中书写逻辑代码即可
运行流程
URL组成:
服务器地址:端口号/虚拟项目名 /servlet注解的路径(配置的路径)
URI:虚拟项目名 /servlet 的别名
浏览器发送请求到服务器,服务器根据请求 URL 地址中的 URI 信息在 webapps 目录下找到对应的项目文件夹,然后在 web.xml 中检索对应的 servlet,找到后调用并执行 Servlet。
DoGet方法用于GET请求
DoPost方法用于POST请求
通过对 Servlet 的调用流程学习,我们知道 web.xml 文件的配置是为了保护servlet。其实服务器应该调用哪个 servlet 进行请求的处理, 在浏览器的请求地址中写的很清楚。
注解配置:
1.精确匹配,一般作用于站点独特的几个路径,首页、登录、注册等等
@WebServlet("/hello") |
2、路径匹配,一般用于产品页,新闻页面,百科页面一般用于大量相类似的页面
@WebServlet("/product/*") |
3、扩展名匹配
@WebServlet("*.json") |
匹配多个路径:
@WebServlet(urlPatterns= {"/morepath","*.do","/more/*"}) |
Servlet的web.xml 配置:
Web.xml 配置的作用:保护Servlet。
配置方式一:精确匹配
<!-- 配置方式一 --> <servlet> <servlet-name>my3</servlet-name> <servlet-class>com.bjsxt.servlet.MyServlet3</servlet-class> </servlet> <servlet-mapping> <servlet-name>my3</servlet-name> <url-pattern>/my3</url-pattern> </servlet-mapping> |
配置方式二:路径匹配
<servlet> <servlet-name>my3</servlet-name> <servlet- class>com.bjsxt.servlet.MyServlet3</servlet-class> </servlet> <servlet-mapping> <servlet-name>my3</servlet-name> <url-pattern>/news/*</url-pattern> </servlet-mapping> |
配置方式三:扩展名匹配
<servlet> <servlet-name>my3</servlet-name> <servlet- class>com.bjsxt.servlet.MyServlet3</servlet-class> </servlet> <servlet-mapping> <servlet-name>my3</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> |
加载时机:
服务器启动的时候会将 webapps 中部署好的项目统一进行加载,并完成对每个项目的 web.xml 文件的加载。
注意:
一个 Servlet 可有拥有多个 url-pattern 配置,但是一个url-pattern 配置只能对应一个Servlet
路径和扩展名匹配无法同时设置,比如下面的三个<url-pattern>都是非法的,如果设置,启动tomcat服务器会报错。
<url-pattern>/kata/*.jsp</url-pattern>
<url-pattern>/*.jsp</url-pattern>
<url-pattern>he*.jsp</url-pattern>
另外注意:<url-pattern>/aa/*/bb</url-pattern>
这个是精确匹配,url必须是 /aa/*/bb,这里的*不是通配的含义
优先顺序
当一个url与多个servlet的匹配规则可以匹配时,则按照 “ 精确路径 > 最长路径>扩展名”这样的优先级匹配到对应的servlet。举例如下:
例1: servletA 的url-pattern为 /test, servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test ,这个时候容器就会先进行精确路径匹配,发现/test正好被servletA精确匹配,那么就去调用servletA,不会去管servletB。 例2: servletA的url-pattern为/test/*, servletB的url-pattern为/test/a/*,此时访问http://localhost/test/a时,容器会选择路径最长的servlet来匹配,也就是这里的servletB。 例3: 比如 servletA的url-pattern:*.action , servletB的url-pattern为 /* ,这个时候,如果我访问的url为http://localhost/test.action,这个时候容器就会优先进行路径匹配,而不是去匹配扩展名,这样就去调用servletB。 |
Servlet 生命周期
Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:
Servlet 通过调用 init () 方法进行初始化。 Servlet 调用 service() 方法来处理客户端的请求。 Servlet 通过调用 destroy() 方法终止(结束) |
最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
现在让我们详细讨论生命周期的方法。
init() 方法
init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。
Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。
当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。
init 方法的定义如下:
public void init() throws ServletException { // 初始化代码... } |
service() 方法
service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。
下面是该方法的特征:
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException{ } |
service() 方法由容器调用,service 方法在适当的时候调用 doGet、doPost、doPut、doDelete 等方法。所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可。
doGet() 和 doPost() 方法是每次服务请求中最常用的方法。下面是这两种方法的特征。
doGet() 方法
GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Servlet 代码 } |
doPost() 方法
POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Servlet 代码 } |
destroy() 方法
destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。destroy 方法定义如下所示:
public void destroy() { // 终止化代码... } |
架构图
下图显示了一个典型的 Servlet 生命周期方案。
第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。
Servlet 容器在调用 service() 方法之前加载 Servlet。
然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。