目录
前言
我我们制作一个网站就需要前后端交互,这里HTTP就是前后端交互的桥梁。我们说的前端就是浏览器,后端就是HTTP服务器。HTTP服务器就是基于TCP服务器实现的。让一个TCP服务器按照HTTP协议的约定,解析请求,构造响应,就够成了一个HTTP服务器。但是我们并不需要独立写一个HTTP服务器,本章博客介绍使用一个现成的HTTP服务器Tomcat。
一、Tomcat的下载和安装
Tomcat是Java生态中最流行的HTTP服务器,它是apache社区开源的HTTP服务器。
1️⃣下载Tomacat
直接搜索Tomcat,也可以直接点击这里的连接进入官网https://tomcat.apache.org/,然后再Download下面点击下载Tomcat 8。这个相比于其他的版本能够更稳定一点,因为越新的版本使用的人越少,其中出现问题的概率也就越高。相比于其他Tomcat 8使用的人更多。
2️⃣安装Tomcat
点击下载之后,下载到文件夹中的是一个压缩文件,这个时候你只需要将这个压缩文件进行解压缩并放到一个你可以找到的地方即可。这个时候Tomcat就安装完成了。Tomcat属于绿色软件,不需要其他软件的安装过程,将其放在你电脑的本地硬盘中就可以使用。卸载的时候,只需要把这个文件夹删除即可。但是要想让Tomcat正常工作,必须要保证你的电脑上安装好了JDK。因为Tomcat是基于Java开发的。
3️⃣了解一下Tomcat的文件一些重要的目录
🍃bin目录中放的是Tomcat相关的批处理文件,.bat后缀的文件,表示的是Windows的批处理文件,.sh后缀的文件,表示是Linux/mac的shell脚本。以startup命名的文件不论是什么后缀,表示的就是Tomcat的启动程序。
🍃logs目录主要用来存储Tomcat运行的日志,Tomcat运行的日志都在这里,如果程序出现问题,首先就需要通过这里的运行日志来排查问题。
🍃webapps目录存储webapp。也就是我们经常说的网站,网站就是前端+后端,这个目录命名为webapps,表示一个Tomcat上可以同时部署多个网站。
4️⃣启动Tomcat
进入bin目录,Windows系统的电脑直接双击startup.bat即可。当出现下面的画面表示Tomcat启动成功。
如果没有出现这个画面或者启动的时候一闪而过,这个时候就需要你把startup.bat这个文件拖到cmd中运行,看报啥错。大概率是缺环境变量,缺啥变量配啥就行。
5️⃣查看Tomcat的端口号是否被正确绑定。
打开Tomcat这个服务器之后,就需要查看一下Tomcat绑定的端口是否正常。Tomcat既然是一个服务器,肯定是要绑定一个端口号的,Tomcat默认的端口号是8080。我们使用cmd输入netstat -ano | findstr 8080.来查看8080端口的使用情况,其中netstat -ano这个命令用来查看你系统上所有的网络端口号的使用情况,findstr 8080这是查看8080这个端口的使用情况。
我们通过进程的id就可以在任务管理器中PID这一列中找到,这个运行的程序(进程)。
可以看见他是一个Java的代码。
6️⃣通过浏览器输入一个URL(网址)http://127.0.0.1:8080来访问Tomcat的欢迎页面,这是Tomcat自带的一个webapp.
7️⃣使用tomcat部署前端页面。
将我们之前写的博客系统的前端页面部署到Tomcat上,也就将我们存放前端代码的blog_system文件夹放到webapps目录下即可,然后在bin目录下找到startup.bat文件重新启动Tomcat,最后使用URL(http://127.0.0.1:8080/部署文件的某个页面的相对webapps目录的相对路径)通过浏览器就可查看到我们部署到Tomcat上的页面。
上面的URL相对来说有点抽象,同个这个例子来看,小编是将blog_system文件夹,放在了webapps目录中,所以这个URL是http://127.0.0.1:8080/blog_system/blog_list.html。
其实所谓的部署一个网站到tomcat上,就是把对应的内容拷贝到tomcat的webapps目录中即可。
❓❓但是看到这里,有的老铁就会问,将这个页面部署到Tomcat上和直接在本地文件中打开有什么区别,现实页面效果都是相同。
❗❗这里将页面部署到Tomcat上,其他人就可以通过URL来对你的网页进行访问。而你通过本地的文件打开就只能你自己访问都这个页面。
虽然说通过将编写的前端页面部署到Tomcat上,可以让其他的人访问到,但是有一个前提就是要么让想访问的你页面的电脑和你的电脑在同一个局域网中,要么你的电脑有一个外网IP,这是因为NAT机制,在一个局域网中的电脑只有一个外网IP,处在局域网中的电脑没有外网IP。
这就需要将这个前端页面部署到安装Tomcat的云服务器上,云服务器具有外网IP.
二、写一个简单的Servlet项目
将上面的了解之后,重点就是我们通过Tomcat进行编程,我们要建立一个网站肯定要写一个HTTP服务器,从头开始写一个HTTP服务器比较麻烦,但是Tomcat中已经把根据HTTP协议解析请求报文,根据HTTP协议构造响应报文等等这些步骤都已经完成封装好了,并且Tomcat提供了一系列的API,可以让我们在编程的时候直接调用,所以我们在完成HTTP服务器的时候,只需要关注具体的业务逻辑即可。Tomcat提供的这一组API就叫做Servlet。
创建并写一个Servlet项目需要完成下面的步骤。
1、创建一个Maven项目
Maven是专门用于管理和构建Java项目的"工程管理"工具,有规范的目录结构、管理依赖、构建/编译、打包、测试等功能。下面使用IDEA创建一个Maven项目。
先点击新建项目—>选择Maven—>点击next
这个页面点击完成之后,就是选择目录,并创建一个目录名。
但是第一次创建Maven项目的老铁,可能会因为网络的问题,创建好的页面在控制台上会报资源没有下载好的问题。那么就更换一个网络在重新试一下。
Maven项目创建好之后,出现的页面就是下面的样子
通过上面的图片我们也可以看到,创建的Maven项目自动生成了一组目录,下面我们来了解一下,这些目录的具体作用。
2、引入依赖
由于Servlet是Tomcat提供的api,不是标准库提供的,所以这里就需要额外下载安装,我们下载Tomcat是在程序运行的时候使用的,但是在开发阶段还是需要我们从Maven中央仓库下载一个Servlet的jar包,这里下载的Servlet的jar包需要和之前下载的Tomcat版本对应上。我们下载的是Tomcat8,所以这里下载的因该是Java Servlet API的3.1.0版本。可以直接点击这里的连接https://mvnrepository.com/,进入Maven中央仓库。
进入之后,搜索servlet就可以看到下面的画面。
点击进入选择3.1.0版本的jar包。
这里我们点击之后,出现下面的页面,本来点击jar,直接下载就行,但是我们用一个更简单的方式,在下面的Maven中生成了一段代码,我们只需要将其复制到我们的代码中即可。
在pom.xml页面中添加一个<dependencies></dependencies>标签,将复制的代码粘贴到这个标签中。IDEA就会自动调用maven,从中央仓库下载该jar包。有的老铁首次使用,这里的下载会花费一点时间,刚开始的时候会出现标红,下载完成之后,就正常了。当代码变白就是引入成功了。
这个jar包下载好之后,是被保存在了本地的一个隐藏目录中了 ,当看到了.m2这个目录的时候,我们下载jar包就在这个目录中。
当我们下载完成之后,之后的使用就可以直接使用了。
3、创建目录
虽然Maven已经帮我们自动创建了一些目录,但是还不够,因为此处我们使用Maven开发的是一个Web程序,还需要一些额外的目录。
1️⃣在main目录下创建一个webapp目录,与Java和resources目录并列。点击Directory创建目录。
2️⃣在webapp目录下,在创建一个WEB-INF目录,在WEB-INF中在创建一个文件web.xml。创建文件夹使用Directory,创建文件使用File。
这里的web.xml文件的作用就是,以web.xml为依据Tomcat从webapps目录中加载webapp。这里的web.xml文件是给Tomcat看的,我们之前的pom.xml是给Maven看的,他们的用途是不一样的。
3️⃣给web.xml中写入指定配置,需要注意的是,这里的代码中可能会出现第三行代码爆红的问题,这是因为IDEA只是针对Java代码的识别非常准确,但是对于其他文件的识别并不准确,这里的爆红并不代表是错的。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
</web-app>
4、编写Servlet代码。
1️⃣在main目录下的Java目录中创建一个HelloServlet类,继承HttpServlet类(这个类就是我们在中央仓库下载的Servlet API的jar包中提供的)
2️⃣重写父类的doGet方法,在代码执行的时候,因为多态的原因,执行的就是子类的doGet方法。作用就是根据请求,计算生成的响应。这里doGet方法中存在两个参数HttpServletRequest req(HTTP请求)和 HttpServletResponse resp(HTTP响应)。
🍂重写的doGet方法中的参数解析。
req代表的就是HTTP请求。客户端发送的HTTP请求被Tomcat收到之后,把这个请求按照HTTP协议的格式解析成HTTP servlet req对象,这个对象中的属性就是HTTP中的信息。最后将解析好的HTTP请求传给doGet方法用来计算响应。
resp代表的是HTTP响应,resp是一个输出型参数。这个响应是一个空的对象,需要我们在doGet中,设置响应的一些数据(比如响应的body、header和状态码等),只要把属性设置到这个resp对象中,Tomcat就会自动根据HTTP servlet响应对象,构造一个HTTP响应的字符串,通过socket返回给客户端。
3️⃣在doGet方法中写入业务逻辑代码,构造resp.
4️⃣加上注解(WebServlet)注解表示路径,这个注解的作用是包当前的类和一个HTTP请求的路径关联起来,不同的路径关联的是不同类,可以触发不同的代码(注解是Java中的特殊的类,Java专门定义了一种类来实现注解,作用是针对一个类/方法,进行额外解释说明,赋予额外的含义)。
import javax.jws.WebService;
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("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//在这个服务器的控制台中,打印了字符串(服务器看到了,客户端看不到)。
System.out.println("hello world");
//这里是给resp的body中写入hello world 字符串,这个内容就会被http响应返回给浏览器,显示到浏览器页面上。
resp.getWriter().write("hello world");
}
}
这里的resp.getWriter()会得到一个write对象,这里的write对象是resp对象内部持有的,并且这个write对象是一个字符流对象。所以这里我们可以使用字符流输入方法write(),向这个write对象中写入数据。这里写入的数据放到了HTTP响应的body中。
这里需要注意的就是,在重写doGet方法时,doGet方法中会调用父类的doGet方法,这个方法会被默认执行,这里需要把这个super.doGet(req,resp)删除掉,因为调用的这个方法并没有处理业务逻辑,而是直接报出错误(405和400)。想要执行我们写的业务逻辑就需要将这句代码删除掉。
5、打包程序
将servlet代码编写完成之后,不能直接在IDEA独立上运行,需要将我们的写的代码打包,放到Tomcat上运行。
我们平时见到的压缩包是rar或者zip,但是在Java中,使用的压缩包是jar和war。我们将一个普通的Java程序可以打包成jar,但是部署到Tomcat上的程序需要打包成war包。war包和jar包在本质上没啥区别,都是把一堆 .class 文件打包进去,但是war包是属于Tomcat的专属格式,里面会有一些特定的目录结构和文件,比如web.xml。后续Tomcat就要识别这些内容,来加载webapp.
✨编译器打包的过程中,会做的事情
- 检查代码中是否存在一些依赖,依赖是否下载好了,如果没有下载好,这个时候会尝试下载。
- 把代码进行编译,生成一堆 .class文件
- 把这些.class文件,以及web.xml按照一定的格式进行打包。
根据下图的步骤,就可以完成一个打包的流程,但是看到这里打好的包是一个jar包,并不是上面说的war包,这是因为Mevan默认的打包格式就是jar。
想要打包是war格式,就需要调整pom.xml,描述打包生成的包格式。点击打开pom.xml文件,在project顶级标签的下方,写一个packaging标签,描述打包的类型是war。我们也可以在这里指定一下打好包的名字 ,使用 build标签,并在这个标签内部使用finalName标签描述一个包的名字。这里将这个包的名字设置为hello_servlet。
//设置打包的格式为war
<packaging>war</packaging>
//设置打好包的名字
<build>
<finalName>hello_servlet</finalName>
</build>
可以看见根据我们的设置,打好的包为war包,并且包名也是我们设置的
6、将程序部署到Tomcat上
可以在IDEA上单击右键找到open in然后点击Explorer,自动在文件夹中找到打好的包,也可以在项目所在目录中找到war包,然后将这个包复制到Tomcat的webapps目录上,然后重新启动Tomcat就完成了部署。这里war包是一个压缩文件,但是放在这里之后,并不需要我们对其解压缩,Tomcat可以自动的解压缩。
运行Tomcat之后,自动解压缩。
7、验证程序运行结果
这里我们完成部署之后,并不是重新启动,我们写的doGet方法就可以执行,这个doGet方法是在遇到Get请求之后,才会执行该方法。换句话说doGet方法,是用来处理HTTP GET请求的。当然,也不是随便遇到一个GET请求,就会执行doGet方法,必须是请求的URL路径要匹配。
这就和我们写的代码对应上了。
当然有doGet方法就会有doPost方法、doPut方法,这些方法都是处理相应的请求的。
✨要注意我们在浏览器上访问服务器时,有两级目录。
- 第一级路径为hello_servlet,是Tomcat的webapps目录中的文件,这一级目录也被称为Context Path/Application Path,标识了一个webapp,也就是这个war包名。
- 第二级路径为hello,这一级路径被称为Servlet Path,标识当前请求要调用那个Servlet类的doGet方法。这里的第二级路径是根据代码中的WebServlet注解来写的。
三、在IDEA上安装Smart Tomcat插件
上面介绍的创建一个Mevan项目,需要完成的七步操作,第5步和第6步可以进行简化,因为每次新创建一个Mevan项目或者修改之前项目中的代码,就需要重新打包和部署,这个过程就有点麻烦,所以我们可以在IDEA上装Smart Tomcat插件就可以简化这个两个步骤。
1️⃣点击File,找到设置settings选项。
2️⃣ 选中插件Plugins选项,选中Marketplace之后,在搜索栏中输入Tomcat,点击下载即可。
3️⃣首次使用需要在IDEA中进行配置,点击右上角的Add Configuration。
4️⃣点击+号,然后找到Smart Tomcat选项点击。
5️⃣可以Name中修改名字,需要在Tomcat server中修改路径。
配置好了之后,就可以点击这个三角来运行我们的代码。
这个时候Tomcat的日志,就会在IDEA中显示了,不会在单独弹出cmd,之前运行出现的乱码,也就不会出现了。
选要注意的是,使用Smart Tomcat的运行方式和之前的将war包拷贝到Tomcat的webapps中,是存在本质区别的,Smart Tomcat使用的运行方式是在运行Tomcat的时候,通过特定的参数,来指定Tomcat加载该项目中main目录中的webapp目录。就是让Tomcat加载单个webapp运行,因此这个过程,既没有打包也没有拷贝。
四、Servlet中的一些常见错误
1️⃣常见错误1:404 — 表示浏览器访问的资源,在浏览器上不存在。
- 请求的路径写错了
- 路径写对了,但是war包没有被正确加载
第一种情况,就是你的URL写错了 ,需要检查你的URL,Context path是啥,Servlet Path是啥。
- 如果你使用将jar包拷贝到Tomcat的webapps目录中的方式,那么你的Context path就是你在pom.xml中设置的包名,Servlet Path就是你在代码中写道的WebServlet注解,注解中的参数就是Servlet Path.
- 如果你使用Smart Tomcat方式,那么Context Path就是你在配置Smart Tomcat时设置的,Servlet Path就是代码注解中的参数。
第二种情况,有可能是web.xml中写错了,就会导致war包不能被正确加载;也有可能有两个Servlet的Servlet Path相同,会导致不能正确加载。
2️⃣常见错误2:405
第一种情况:发送的请求的HTTP方法与代码中的不匹配,也就是说代码中没有实现相应的处理这个请求的方法。例如代码中写了一个doPost方法,但是你发送的请求是一个GET请求。
第二种情况:虽然代码中的方法和浏览器请求的HTTP方法对应,但是在写代码的时候没有将doxxx方法中的super.doxxx方法删除掉。就会出现405.
3️⃣常见错误3:500 — 表示服务器代码抛出了异常,需要仔细观察异常调用栈
先在代码中构造一个异常。
4️⃣常见错误4:出现空白页面
将代码中的resp.getWriter().write("hello world"),这就代码删除掉,就会出现这个问题。这句代码的意思是向resp对象的write对象中写入响应的结果,最终将write中的内容会放在HTTP响应的body中。将其删掉就是这个响应中没有body,所以页面就是空白的。
5️⃣常见错误5:无法访问此网站。
将Tomcat关闭之后,就会出现页面无法访问的情况。