简单介绍 servlet
Servlet
是一种实现动态页面的技术, 是一组Tomcat
提供给程序猿的API
, 帮助程序猿简单高效的开发一个webapp
;
已经知道 Tomcat 为一个web 服务器产品,为什么要学习 servlet 呢
?
原因:
servlet
为我们定义好了统一的编程规范,当使用不同的web
服务器时,所写的web
应用程序还能继续使用的;
servlet
是基于编程的方式提供请求的处理以及响应的内容 (状态码、header、body
),可以完成的功能有:
HTML
是静态的资源文件,如果想返回动态的网页内容,就不行 -----> 但采用servlet
能实现;- 文件下载:把静态的文件放在
Tomcat /webapps
下,访问就能下载 -----> 使用servlet
也能实现此功能; - 用户登陆:客户端浏览器输入账号密码,需要在服务端写程序来校验账号密码 -----> 服务端写程序
servlet
才能实现;
servlet 开发流程
-
使用
IDEA
创建一个maven
项目;如下所示:
然后点击next
,填写项目创建的目录;
-
编写
pom.xml maven
配置文件;
此处需要在
pom.xml
中引入Servlet API
依赖的jar
包,如下步骤所示:
该地址下输入servlet
;
查询结果:
选择版本:要与Tomcat
匹配;
匹配查询链接:
因此这里选择 3.1.0 版本;
将该版本下的xml
复制到项目的pom.xml
中;
修改后的 pom.xml
的文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>servlet-study</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!-- 引入依赖包-->
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
- 创建
web
应用所需要的目录和web.xml
;
- 创建 webapp 目录;
在main
目录下, 和java
目录并列, 创建一个webapp
目录 (注意, 不是webapps
);
- 创建 web.xml 目录;
在webapp
目录内部创建一个WEB-INF
目录, 并创建一个web.xml
文件;
编写 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>
- 编写代码:以上步骤完成后就可以进行
servlet
代码编写了;
- 首先 在
java
目录中创建一个HelloServlet
类 ; - 该类继承自
HttpServlet
; - 在这个类上方加上
@WebServlet("/hello")
注解,表示Tomcat
收到的请求中, 路径为/hello
的请求才会调用HelloServlet
这个类的代码; - 重写
doGet
方法;doGet
的参数有两个, 分别表示收到的HTTP
请求 和要构造的HTTP
响应,该方法会在Tomcat
收到GET
请求时触发;
HttpServletRequest: 表示
HTTP
请求,Tomcat
按照HTTP
请求的格式把 字符串 格式的请求转成了一个HttpServletRequest
对象,后续想获取请求中的信息(方法, url, header, body 等) 都是通过这个对象来获取;
HttpServletResponse:表示HTTP
响应, 代码中把响应对象构造好(构造响应的状态码,header
,body
等)
代码如下:
package org.example;
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;
/**
* Servlet开发是通过Servlet标准的api来处理请求,和返回响应
*
* (1) @WebServlet表示当前类是一个Servlet类,需要处理请求和响应
* (2) 如何知道,某个请求是需要当前这个servlet类来处理?访问路径,定义在@WebServlet中
* 注意:路径是/开头,否则会报错。定义了虚拟的路径(可能这个路径没有对应的文件)
* (3) 继承HttpServlet:处理http协议的
* (4) 重写父类的doXXX方法: XXX就是提供的服务方法(请求的时候,也需要使用相同的方法)
*/
@WebServlet("/hello")
public class helloServlet extends HttpServlet {
//重写父类的 doXXX 方法
/**
* HttpServletRequest: http请求封装的类型,使用这个对象就可以获取http请求报文的内容
* HttpServletResponse: http响应封装的类型,使用这个对象就可以设置http响应报文的内容
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//super.doGet(req, resp); 需要删除掉,否则会报错;
// response.getWriter()是获取响应对象中的输出流,可以把内容设置到响应正文中(body)
resp.getWriter().println("hello");
}
}
- 打包:
通过
maven
面板, 双击package
进行打包;
打包成功如下所示:
此时在 target
目录下, 生成了一个 jar
包;
但 Tomcat
能够识别的是 war
格式的压缩文件,因此,可以通过修改 pom.xml
文件来实现,该文件也可以进行压缩格式名称的修改;
pom.xml 修改后的内容
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>ServletHelloWorld</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 改成 war 包-->
<packaging>war</packaging>
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api
-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 修改 war 包名称为 ServletHello-->
<build>
<finalName>ServletHello</finalName>
</build>
</project>
修改之后,重新打包,则会发现:
war 包和 jar 包的区别:
jar
包是普通的 java 程序打包的结果.,里面会包含一些.class
文件;war
包是java web
的程序, 里面除了会包含.class
文件之外, 还会包含HTML, CSS, JavaScript,
图 片以及其他的jar
包.,打成war
包格式才能被Tomcat
识别;
- 部署程序:
部署 web
到 Tomcat
中:
将打包的
war
格式的压缩文件复制到Tomcat/webapps
下,然后运行Tomcat
,系统会将war
格式的压缩文件解压为相同名称的文件夹;
运行后结果:
页面访问结果如下:
但该种部署方式,当出现 bug 或 访问出错
时不便于修改代码,因此采用另一种方式来进行部署;
方法就是:在 IDEA
中,安装 Smart Tomcat
插件并进行配置;
Smart Tomcat 插件安装步骤:
-
菜单 -> 文件 ->
Settings
;
-
选择
Plugins
, 选择Marketplace
, 搜索 “tomcat
”, 点击 “Install
”;
-
安装完毕之后, 会提示 "重启
IDEA
"
插件配置步骤:
- 点击右上角的 “
Add Configuration
”;
进入如下所示页面:
最后点击 ok
就可以了~,Context Path
默认填写的值是项目名称;
点击 右三角 , IDEA
就会自动进行编译、 部署、启动 Tomcat
;
如下所示:
通过以下方式即可进行访问:
但直接点击访问时,会报 404
状态码,是因为/
默认访问 根目录下的 index.html,
不存在就会报错,因此只需要加上之前定义的虚拟的 /hello
就可以进行访问;
访问出现问题及解决方案
405 状态码
405
:方法不支持,提供的服务方法不包含请求方法;
代码如下:
package org.example;
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("/post")
public class postServlet extends HttpServlet {
// 重写父类 post 方法
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("post");
}
}
当没有重写 doGet
方法时,访问就会出现如下所示:
原因是: 输入URL
访问时,默认为 get
请求;
500 状态码
500
:服务器内部出错;检查异常堆栈信息;
代码如下:
package org.example;
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("/error")
public class errorServlet extends HttpServlet{
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int i = 1;
int j = i/0;
resp.getWriter().println("error");
}
}
访问时,出现如下页面所示
404 状态码
404
:表示访问路径没有对应的服务资源;
当没有写 Context Path(上下文路径)、或者输入的路径不正确
,访问均会出现如下界面所示:
理解 Tomcat 及 servlet 是如何接收请求返回响应的?
其中 servlet-study
对应的是 Context Path
的路径;
hello
对应的是注解中所写的路径;
servlet 生命周期方法
init
:初始化方法,只执行一次;service
:每次HTTP
请求,如果匹配到某个servlet
的路径时,就会调用这个servlet
对象的service
方法,即(一次请求,一次调用);destroy
:销毁方法,只执行一次;
小结
1. 开发简要流程
(1)新建
maven
项目;
(2)编写pom.xml
配置文件;
(3)创建web
应用目录web.xml
;
(4)编写servlet
开发代码;
(5)部署web
应用到Tomcat
并运行;
2. 状态码及解决方案
状态码 | 解决方案 |
---|---|
4xx | 需要检查 URL 是否正确,检查与代码中设定的 Context Path 以及 Servlet Path 是否一致 |
5xx | 需要观察页面提示的内容和 Tomcat 自身的日志是否出现报错 |
空白页面 | 需要使用抓包工具来分析 HTTP 请求响应的具体交互过程 |