学会tomcat的基本使用以及如何创建IDEA的web项目
第一章 服务器软件tomcat
1.1 web相关概念回顾
- 软件架构
- C/S: 客户端/服务器端
- B/S: 浏览器端/服务器端
- 资源分类
- 静态资源: 所有人看到的一样的部分( html,css )
- 动态资源: 由于用户的id不同,接口返回的数据不同,这些资源就是动态资源,(动态资源首先会转换为静态资源(响应),我们用户才能看得到) (serverlet,php,asp)
- 网络通信三要素
- IP : 网络协议地址
- 端口: 主机上的一个进程和另一个主机上面的一个进程的唯一标识 (0~65536)
- 传输协议: 规定了数据传输的规则 (现在一般都是用TCP/IP协议)
- TCP: 面向连接的协议,要三次握手
- UDP: 无连接, 不安全协议,速度快
1.2 web服务器软件概述
服务器: 就是安装了服务器软件的计算机
服务器软件: 接受用户的请求,处理请求,做出响应
web服务器软件: 用户通过浏览器来发送请求给我们服务器,我们处理请求,做出响应
-
在web服务器软件中,可以部署web项目,让用户通过历览器来访问这些项目
-
可以说他是作为一种web容器,装载动态资源
-
常见的java相关的web服务器软件
- webLogic : oracle公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费 ( JavaEE是企业级开发中使用的技术规范的综合,一共规定了13项大的规范 )
- webSphere : IBM公司, 大型的JavaEE服务器,支持所有的JavaEE规范,收费
- JBOSS : JBOSS公司, 大型的JavaEE服务器,支持所有的JavaEE规范,文档和服务收费
- Tomcat : Apache基金组织开发,中小型的JavaEE服务器,仅仅支持少量的JavaEE规范, 开源免费
1.3 Tomcat的文件配置
我们可以将端口号改为80,因为80端口是http协议的默认端口号 ,用户访问我们的网站的时候就不用输入端口了
现在所有的网站默认端口号都是80
关于我们如何关闭网络服务
- 不推荐直接点击x窗口关闭
- 在startup窗口,点击ctrl+c (推荐)
- 点击
bin/shutdown.bat
文件来关闭
1.4 Tomcat 部署项目的方式
首先看看tomcat的文件目录结构 (了解了解就行了)
部署项目的方式
- 直接将项目放进webapps目录下即可
- 我将register文件夹放进了这个目录下,文件夹里面有我写的网页
http://10.4.235.173:8080/register/denglu.html
- 通过将项目的以war为后缀的压缩文件放进webapps目录下,软件如自动解压
- 同时,我们如果删掉
.war
的文件,解压后的项目文件也会被自动删掉
- 同时,我们如果删掉
- 我将register文件夹放进了这个目录下,文件夹里面有我写的网页
- 在
server.xml
配置文件中部署项目- 我们在里面找到
host
标签 - 在里面加上
<Context docBase ="项目文件夹的位置" path='虚拟路径' />
这是一个自闭合标签- 举例
<Context docBase ="D:\register" path='/hehe' />
那么我们要访问的时候就输入Localhost:8080/hehe/denglu.html
- 举例
- 虚拟路径就是项目不是在那个地方,但我我们在浏览器上想要访问这个项目就要输入虚拟录井而不是真实路径
- 这个方法灵活一些,但是一旦这个软件出现损害,那么部署在这个服务器上面的所有项目都会失败
- 我们在里面找到
- 在
conf\Catalina\localhost
目录下创建一个任意名称的xml文件 (最推荐的一种部署方式,这是一种热部署的方式,同时也不怕丢失了一个文件而导致所有部署的项目都失效)- 在文件中编写
<Context docBase ="项目文件夹的位置" />
, 注意,这里没有虚拟目录 - 虚拟目录在哪? 虚拟目录的路径就是你的xml的文件名
- 在文件中编写
动态项目和静态项目
- 动态目录的目录结构
- 项目的根目录
web-inf
- web.xml : 项目的核心配置文件
- classes目录: 放置字节码文件的目录
- lib目录: 放置依赖的jar包
- 项目的根目录
第二章 Servlet入门
2.1 概述
Servlet(server applet): 运行在服务器上的小应用程序
本质上就是一个接口,定义了一个java类被浏览器访问到(Tomcat识别)的规则
将来我们自定义一个类,实现servlet接口,复写方法
2.2 快速入门
步骤如下
- 创建一个JavaEE项目
- 定义一个类,实现Servlet接口
- 实现接口中的抽象方法
- 配置Servlet
2.3 执行原理
- 当服务器接收到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
- 查找web.xml文件,是否有对应的标签体的内容
- 如果有,则在找到对应的全类名
- tomcat会将字节码文件加载进内存,并且创建其对象
- 调用其方法
2.4 Servlet中的生命周期方法
-
初始化方法: 在Servlet方法被创建的时候执行, 只会执行一次
-
public void init(ServletConfig servletConfig) throws ServletException {}
-
我们可以通过web.xml文件来规定Servlet的创建时机
- 第一次被访问的时候创建:
在<servlet>标签里面添加 <load-on-startup>标签,让其里面的值为负数,不配置的默认值就是-1
- 服务器启动的时候创建: 标签里面的值是0或正数
- 第一次被访问的时候创建:
-
说明servlet在内存中只存在一个对象,servlet是单例的
- 多个用户同时访问这个类时,可能存在线程安全问题,不能加锁,加锁之后效率很低
- 解决: 尽量不要在servlet中定义成员变量, 定义局部变量
-
-
提供服务方法: 每一次Servlet被访问时执行
-
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {}
-
-
销毁方法: 在Servlet正常关闭时执行
-
public void destroy() {}
-
注意,正常关闭时才会执行
-
方法是执行在,销毁之前的
-
2.5 servlet3.0 注解
从servlet3.0 版本之后,支持注解配置,我们可以不需要web.xml了
步骤
-
创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml
-
定义Servlet类,实现Servlet接口
-
复写接口的方法
-
在类上使用注解
@webServlet
-
package example; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import java.io.IOException; //@WebServlet( urlPatterns = "/hehe") //下面是简便写法,里面就是虚拟路径 @WebServlet("/hehe") public class ServletDemo implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("aaa"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
2.6 IDEA与Tomcat的相关配置
- IDEA回味每一个tomcat部署的单独建立一份配置文件
-
运行服务器的时候,我们发现有下面这一行字
Using CATALINA_BASE: "C:\Users\CUMT_CJY\AppData\Local\JetBrains\IntelliJIdea2021.1\tomcat\a7a45e64-9f44-4a4c-b00a-bfe866c6e75b"
-
进入目录,我们就会发现,文件夹中有着和tomcat文件目录很相似的东西
-
-
点进去
conf/Catalina/localhost/JavaWeb_war_exploded.xml
,我们会发现文件里面的内容是<Context path="/JavaWeb_war_exploded" docBase="C:\Users\CUMT_CJY\Desktop\Web\JavaWeb\target\JavaWeb-1.0-SNAPSHOT" />
,我们发现了一个大秘密,tomacat真正访问的不是我们写代码的src的那个目录,而是其他地方(这个地方就是tomcat部署的web项目的地方)
-
- 工作空间项目 和 tomcat部署的web项目
- 如上面的
4
所说, tomcat真正访问的是tomcat部署的web项目
,tomcat部署的web项目
对应着工作空间项目
的webapp目录下的所有资源 - WEB-INF目录下的资源不能被浏览器直接访问
- 断点调试: 使用
小虫子
那个debug的图标
- 如上面的
2.7 Servlet体系结构
在之前,我们每次要写一个Servlet的实例对象,都要重写接口的所有方法,但是有些我们又不用,很麻烦,那么有没有什么方法来解决呢?
我们来看看接口的儿子孙子们
- Servlet --接口
- 他的儿子:
GenericServlet
– 抽象类- 他的孙子:
HttpServlet
– 抽象类
- 他的孙子:
- 他的儿子:
GenericServlet抽象类
该类的定义: Defines a generic, protocol-independent servlet. To write an HTTP servlet for use on the Web, extend HttpServlet instead.
中文翻译: 定义一个通用的、与协议无关的servlet。要编写一个供Web使用的HttpServlet,请改用扩展HttpServlet。
观察他的源码,我们发现除了service方法之外的所有Servlet接口的方法都被重写了(尽管有些只不过是空实现)
因此,我们在继承这个类写Servlet的时候,我们只用重写service方法就行了
package servlet.JavaWeb;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/hehe")
public class ServletDemo2 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("我是你爹!");
}
}
尽管它很方便,但是我们不用他,因为这个类存在的目的不是为了创建适用于http的servlet
HttpServlet抽象类
类的定义: 提供一个要子类化的抽象类,以创建适用于网站的HTTPservlet。
HttpServlet的子类必须重写至少一个方法,通常是以下方法之一:
-
doGet
() ,如果servlet支持HTTP GET请求 -
doPost()
,用于HTTP POST请求 -
doPut()
,用于HTTP PUT请求 -
doDelete()
,用于HTTP删除请求 -
init()和destroy()
,以管理在servlet生命周期内保留的资源 -
getServletInfo()
,servlet使用它来提供关于自身的信息
代码实现
package servlet.JavaWeb;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/haha")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("我是你爹");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("就这?");
}
}
通过浏览器请求,是get的方式
所以我们在访问上面这个页面的时候,输出的是我是你爹
我们可以用表单提交的方式来触发post
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/JavaWeb_war_exploded/haha" method="post">
<input type="text" name = 'username'>
<input type="submit" value="提交">
</form>
</body>
</html>
2.8 Servlet_urlpartten配置
观察@WebServlet
注解,我们发现,下面这两个东西
/**
* The URL patterns of the servlet
*
* @return the URL patterns of the servlet
*/
String[] value() default {};
/**
* The URL patterns of the servlet
*
* @return the URL patterns of the servlet
*/
String[] urlPatterns() default {};
我们会发现,这两个用来写网页访问路径的属性,都是数组的形式,那么就意味着,一个servlet类可以有多个可以访问的路径
@WebServlet( {"/qwq","/qwq1","/qwq2"} )
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("我是一个傻逼!");
}
}
上面这段代码,我们访问下面三个网址,都是有效的
localhost:8080/JavaWeb_war_exploded/qwq
localhost:8080/JavaWeb_war_exploded/qwq1
localhost:8080/JavaWeb_war_exploded/qwq2
路径的定义规则
/xxx
/xx/xx
/xx/*
: * 就是通配符,所有的意思*.do
: 意思就是在所有路径后面加上一个.do
都可以访问到这个Servletlocalhost:8080/JavaWeb_war_exploded/qwq2.do
localhost:8080/JavaWeb_war_exploded.do
注意: 通配符的优先级是最低的,当有其他网址存在的时候,优先显示其他的用的不是通配符的网址
面三个网址,都是有效的
localhost:8080/JavaWeb_war_exploded/qwq
localhost:8080/JavaWeb_war_exploded/qwq1
localhost:8080/JavaWeb_war_exploded/qwq2
路径的定义规则
/xxx
/xx/xx
/xx/*
: * 就是通配符,所有的意思*.do
: 意思就是在所有路径后面加上一个.do
都可以访问到这个Servletlocalhost:8080/JavaWeb_war_exploded/qwq2.do
localhost:8080/JavaWeb_war_exploded.do
注意: 通配符的优先级是最低的,当有其他网址存在的时候,优先显示其他的用的不是通配符的网址