目录
前言
基于tomcat进行网站后端开发,肯定是需要针对http协议进行一系列操作的,tomcat把底层操作封装好,直接调用api即可,这里的api就叫做Servlet。(虽然企业中几乎不会使用了,但这是我们未来学习框架的基础~)
一、Servlet是什么?
Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序猿的 API, 让我们用户不必关注Socket,HTTP协议格式等细节,降低了web开发的门槛,提高开发效率,帮助程序猿简单高效的开发一个 web app
网页可以分为两类:
1.静态页面:网页内容始终固定的页面,单纯的html
2.动态页面:用户不同/时间不同/输入参数不同时页面的内容会发生变化,html+数据
Servlet主要进行的工作:
- 允许我们程序员创建一个类,tomcat收到某个特定路径的HTTP请求时,执行该类中的某个方法
- 对HTTP请求进行解析,并将HTTP请求从一个字符串解析成一个HttpRequest对象
- 程序员只需要给指定的HttpResponse对象的一些属性字段填写,Servlet就会自动的按照HTTP协议的方式构造出一个HTTP响应的字符串,然后通过Socket写回客户端
二、第一个Servlet程序
编写第一个Servlet程序,写一个helloworld程序,部署到tomcat上,然后通过浏览器去访问,在网页上得到hello world字符串,一共需要一下7个步骤:
1、创建项目
2、引入依赖
3、创建目录
4、编写代码
5、打包程序
6、部署程序
7、验证
2.1 创建项目
打开idea,新建一个maven项目:
什么是maven?
maven是Java中非常知名的一个远程管理工具/构建工具
核心功能是将:管理依赖;构建/编译;打包;这一系列操作串起来,都由maven负责!
依赖:可以理解为A想买一个手抓饼,但是A没钱,A需要向他的妈妈B要5块钱,那么B就是A的依赖;简单从字面意思理解即可;在咱们以后写代码过程中,经常会依赖一些标准库,这个依赖的关系可能是很复杂的,比如A->B->C->D;如果手动来管理这些依赖的话那么是不是非常麻烦,为了解决这个问题,maven就可以自动的进行管理;
构建/编译:即调用jdk;
打包:即把Java代码给构造成jar/war包;
2.2 引入依赖
中央仓库地址:仓库地址!
2.3 创建目录
虽然maven已经帮我们自动创建了一些目录,但远远不够,不足以支撑咱们写一个servlet项目;因为此处我们使用maven开发的是一个web程序,还需要一个额外的目录,需要咱们手动创建一些目录和文件;
1.在main目录下,创建一个目录
解释下这里的目录:
当前写的servlet程序和以往写的代码有很大区别——没有main方法
main方法什么——相当于一辆车的发动机,能把程序拉跑起来~
这里没有main方法,程序可以跑起来吗?——可以,一辆车没有发动机,但只要有车头拉着,也能跑起来~(参照地铁)
tomcat是车头,sevlet是车厢,把servlet程序扔到webapps目录下,相当于把车厢挂到车头上
,这样servlet也就可以跑起来了~
tomcat如何识别webapps目录下哪些是需要拉着跑的车厢呢?哪些是不需要拉着跑的目录呢?——就靠这个WEB-INF/web.xml文件,这个文件相当于servlet给tomcat的一张投名状,表示下次运行要把我带上~
因为tomcat可以同时加载多个webapp,所以tomcat的目录是带s的,咱们写的就是一个webapp,就没有s;
2.给web.xml写入指定配置
<!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>
这里的代码是红色的,但并不代表是错的
2.4 编写servlet代码
doGet的父类是直接写回一个错误,所以这里需要将自己重写doGet方法
这里doGet方法不需要我们手动调用,而是交给tomcat,当tomcat收到get请求,就会触发doGet方法,tomcat会构造好两个参数,req和resp。
- req 是TCP socket中读出来的字符串,按照HTTP协议解析得到的对象
- resp是一个空的对象(不是null,只是里面的各个属性没有赋值)
程序员需要在doGet方法中,根据请求req,结合自己的业务逻辑,构造出一个resp对象来(可见resq参数本质上是一个输出型参数,doGet方法做的工作就是根据请求返回响应)
需要在类上面加一个注解,注解是java中特殊的类,java中定义一种特殊的’语法糖"来实现注解,注解的作用,是针对一个类/方法,进行额外的解释说明,赋予该类/方法额外的功能/含义。
此处@WebServlet 注解的作用是把 当前类和一个HTTP请求路径关联起来,doGet是tomcat收到GET请求的时候调用,具体要不要调用,还得看当前GET请求的路径是啥,不同的路径可以触发不同的代码(这里注释把类和HTTP请求路径关联起来,到时候根据不同路径找到对应的类,实现GET请求)
小知识点:一个Servlet程序中,可以有很多Servlet类,每个Servlet类都可以关联到不同的路径(对应到不同的资源),因此此处的多个Servlet就实现了不同的功能,一个路径也不能对应多个Servlet,路径和Servlet类之间是一对一的关系
resp.getWriter()会得到一个Writer对象,此处的writer对象是属于resp对象的,此处的write操作其实是往resp的body部分进行写入,等resp对象整个构造好了,tomcat会统一转成HTTP相应的格式,写入socket
2.5 打包程序
这里需要将程序打成war包,jar只是一个普通的java程序(jar是.class构成的压缩包),war则是tomcat专属用来描述webapp的程序,一个war就是一个webapp
但是maven默认是打成jar包,需要在pom.xml文件中配置一下
点击package进行打包
如果大家打包后没有出现target,大家需要刷新(reload)一下项目。
2.6 部署
将刚才打包好的war拷贝到tomcat的webappas目录下,无论tomcat是在同一个电脑还是在不同电脑上,都是这样拷贝,然后启动tomcat,需要注意如果tomcat正在运行时,直接拷贝,tomcat虽然能识别,但是在windows上可能会出现Bug
2.7 验证
启动Tomcat,在浏览器地址栏输入对应url
刚刚在浏览器地址输入url之后,浏览器就构造了一个GET HTTP 请求,发给了tomcat,tomcat会根据一级目录,确定具体的webapp,根据第二级路径,确定了是调用哪个类,再通过GET/POST方法确定调用HelloServlet的那个方法。
上述是我们servelt最朴素的步骤,我们也可以通过一些操作来简化上述操作
三、IDEA部署Servlet程序
smart tomcat
我们可以通过一些第三方的工具来简化打包和部署这两步的操作;IDEA上有一个插件叫做smart tomcat就可以自动完成打包部署的操作;
下载步骤;
step1、打开idea,file->settings->plugin;在搜索栏搜索smart tomcat;
step2、第一次使用需要配置一下;首先点击右上角红色箭头指向的地方;
step3、点击+号,找到smart tomcat;name可以随便取;选择一下对应的版本、目录;注意这个content path路径要和URL的第一级路径保持一致;
step4、点击右上角的这个绿色的三角,便可自动的进行打包部署;
step5、点击三角箭头,打包部署;
!这怎么一堆红色的代码,报错了?不是。这里的内容本身就是红色的,异常调用栈才是错误;
注意,打包部署的时候记得先把tomcat命令行给关了,然后再去点击绿色三角按钮,不然会占用端口号;导致错误;不要去点击这里的地址,我们需要在地址栏手动输入url
smart tomcat的工作原理,不是说把war包拷贝(webapps里不变),而是tomcat启动的时候显式指定了一个webapp目录,相当于加载单个webapp运行,ided直接调用tomcat,让tomcat加载当前项目中的目录,这个过程没有打war包,没有拷贝,也没用解压缩的过程
大家需要注意:如果我们直接拷贝war包的方式部分,context path就是war包名,如果是smart tomcat方式部署,这里是可以配置的,默认是项目名
四、常见错误
4.1 404
路径写错了,如果大家出现了404将自己地址栏输入的url与Context path
和servlet path对应看是否一致
webapp没有正确被部署: web.xml 写错了
4.2 405
405 表示对应的 HTTP 请求方法没有实现,比如我们在浏览器发了个GET请求,但是代码里没写doGet,此时就会出现405,因为我们父类的doGET里的代码就是返回405
4.3 500
本质上就是我们的代码抛异常了,500的时候日志里会明确告诉我们异常调用栈,告诉我们是哪一行代码出的异常
4.4 出现空白页面
我们的方法中没有写resp.getWriter().write()方法
4.5 出现"无法访问此网站"
原因可能是tomcat没有启动好,我们需要检查我们的tomcat是否启动好了