- 博主简介:想进大厂的打工人
- 博主主页:@xyk:
- 所属专栏: JavaEE初阶
目录
文章目录
一、Tomcat
1.1 Tomcat是什么
1.2 下载安装
1.3 部署项目
二、第一个Servlet程序
2.1 Servlet是什么
2.2 创建Maven项目
2.3 引入依赖
2.4 创建目录
2.5 编写类方法
2.6 打包代码
2.7 部署项目
2.8 验证程序
三、Smart Tomcat部署方式
四、Servlet程序中常见的问题
4.1 404
4.2 出现405
4.3 出现500
4.4 出现空白页面
Tomcat 这个单词很容易让大家想到“汤姆猫”,大家可能会想到小时候看的动画片~~
事实上, Java 世界中的 "汤姆猫" 完全不是一回事, 但是同样大名鼎鼎
Tomcat 是一个 HTTP 服务器.在Java圈子中,最出名的 HTTP 服务器就是Tomcat,是apache社区开源的 http 服务器~~~
下载官网:Apache Tomcat® - Apache Tomcat 8 Software Downloads
最新的版本不一定好用,我推荐下载 Tomcat8 版本的,因为大部分企业都在使用~~
点击即可~
大版本是 8 系列即可,小版本由差别,无所谓~~
目录结构:
bin 表示binary,里面包含了一下可执行的二进制脚本
启动成功是这个界面:乱码没关系的,不影响使用
查看Tomcat的端口号是否绑定成功
打开命令行输入:
netstat -ano | findstr 8080
两个的话,一个是ipv4,一个是ipv6,出现这样的界面就代表绑定成功了~~~
.bat后缀的为 Windows的批处理文件
.sh后缀的为 linux / mac 的shell脚本
如果启动失败怎么办?
最常见的启动失败原因是端口号被占用,Tomcat 启动的时候默认会绑定 8080 和 8005 端口,如果有其他进程已经绑定了这两个端口中的任意一个, 都会导致 Tomcat 不能启动.把对方进程干掉,再重新启动 Tomcat 一般就可以解决问题.
conf 表示config,配置文件
logs表示运行日志
webapps 放webapp,即放我们写的代码压缩包,一个Tomcat上可以同时部署多个网站
我把我写过的项目拷贝到 webapps目录下面:
再次启动Tomcat,就可以看见这个 war包 被自动解压缩了,然后我们进行访问
可以看到,我们访问成功了,证明我们已经成功部署到Tomcat服务器上面~~
但是由于 NAT机制,在外网的设备,还是不能访问我部署的项目,后续我会在云服务器上部署,外网就可以访问了~~
Servlet 是一种实现动态页面的技术. 是一组 Tomcat 提供给程序猿的 API, 帮助程序猿简单高效的开发一个 web app.
Servlet 主要做的工作:
简而言之, Servlet 是一组 Tomcat 提供的 API, 让程序猿自己写的代码能很好的和 Tomcat 配合起来, 从而更简单的实现一个 web app.
而不必关注 Socket, HTTP协议格式, 多线程并发等技术细节, 降低了 web app 的开发门槛, 提高了开发效率.
使用 IDEA 创建一个 Maven 项目
首次使用maven项目,会从互联网上加载很多依赖,所以要保持网络通畅!
在Maven中央仓库中搜索servlet
Maven中央仓库官方网站:Maven Repository: Search/Browse/Explore (mvnrepository.com)
点击3.1.0,选择3.1.0是跟我们的Servlet版本匹配的,不能乱选
复制下来,粘贴进pom.xml
javax.servlet
javax.servlet-api
3.1.0
provided
要跟我一模一样哦!!!
这些目录中:
我们要在main包下面,创建webapp包,webapp包下创建WEB-INF包,WEB-INF包下创建web.xml
web.xml中的内容:
Archetype Created Web Application
在java包下创建HelloServlet
继承HttpServlet,并重写doGet方法,并在类上面写上注解@WebServlet(“....”)表示 Tomcat 收到的请求才会调用 HelloServlet 这个类的代码.
@WebServlet(),括号里面写的路径跟我们后续访问网页有很大关系,所以一定要记住!!!
@WebServlet("/hello")
public class helloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("hello world");
resp.getWriter().write("hello world");
}
}
而我们之前做的TCP回显服务器的基本流程就是:
但是Tomcat已经帮我们把1,3步都做好了,所以我们只需要做好第二步即可~~
为什么不用写main方法??
这是因为Tomcat内部帮我们实现了,它在合适的时机调用了我们重写的代码去计算响应~
伪码:
main { HttpServlet servlet = new HelloServlet();//触发重写 HttpServletRequest req = ...;//获取请求的一系列操作 HttpServletResponse resp = new HttpServletResponse();//空响应 servlet.doGet(req, resp);//调用我们重写的方法,这个响应就被构造好了 }
如果我们不重写doGet方法,那么就会出现405错误:
我们随便写个类都能被 Tomcat 调用嘛? 满足啥样条件才能被调用呢?
主要满足三个条件:
这三个条件都满足之后, Tomcat 就可以找到这个类, 并且在合适的时机进行调用
我们的程序不能独立运行,必须部署(放置)到Tomcat上才能运行,而Tomcat服务器只认识 war包,只能解析 war包!!
- 对于一个规模很大的项目,就会有很多很多的java文件和class文件,所以我们是需要将这些class文件打成一个压缩包,再进行拷贝,是比较科学的~
- java中使用的压缩包,就是jar、war
- jar:普通java程序,打成jar包
- war:部署到Tomcat上的压缩包
我们要在pom.xml里面加下面代码才能打成war包:
war
hello_servlet
接下来打war包:
双击package,就会自动生成war包
可见我们已经生成了war包~~~
把 war 包拷贝到 Tomcat 的 webapps 目录下,启动 Tomcat , Tomcat 就会自动把 war 包解压缩.
看到这个日志说明 Tomcat 已经正确识别了 ServletHelloWorld 这个 webapp.
此时通过浏览器访问 http://127.0.0.1:8080/ServletHelloWorld/hello
就可以看到结果了.
注意: URL 中的 PATH 分成两个部分, 其中 HelloServlet 为 Context Path, hello 为 Servlet Path
Context Path是war包名,Servlet Path 是我们之前在类上面写的路径
我们只需要通过IDEA的插件(plugin)来完成这个工作(一键式完成5和6)
点击下载,我这里已经下载好了,不再下载~~
使用Smart Tomcat插件
首次使用比较麻烦,需要配置:
点击 + 号
这样就运行起来啦!!!
我们加上hello之后,再次访问
可见,访问成功了!!!
Smart Tomcat的运行方式和之前拷贝到webapps是存在区别的~
smart tomcat其实是使用了tomcat的另外一种运行方式,在运行tomcat的时候,通过特定的参数,来指定tomcat加载某个特定目录中的webapp
因此,上述过程既不会打包,也不会拷贝!!!是开发和调试阶段,使用的方式,如果是部署到生产环境,还是得打war包!!!
404 表示用户访问的资源不存在. 大概率是 URL 的路径写的不正确.
错误实例1: 少写了 Context Path
通过 /hello 访问服务器
错误实例2: 少写了 Servlet Path
通过 /ServletHelloWorld 访问服务器
错误实例3: Servlet Path 写的和 URL 不匹配
修改 @WebServlet 注解的路径
错误实例4: web.xml 写错了
清除 web.xml 中的内容
405 表示对应的 HTTP 请求方法没有实现
错误实例: 没有实现 doGet 方法
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
}
在浏览器地址栏直接输入 URL , 会发送一个 HTTP GET 请求.
此时就会根据 /ServletHelloWorld/hello 这个路径找到 HelloServlet 这个类. 并且尝试调用
HelloServlet 的 doGet 方法.
往往是 Servlet 代码中抛出异常导致的.
错误实例:修改代码
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String s = null;
resp.getWriter().write(s.length());
}
}
异常信息里已经提示了出现异常的代码是 HelloServlet.java 的第 13 行
resp.getWriter().write(s.length());
错误实例:修改代码, 去掉 resp.getWritter().write() 操作
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("hello");
}
}
抓包可以看到, 响应 body 中的内容就是 "空数据"