使用 IDEA 创建一个 Maven 项目.
Maven
项目创建完毕后, 会自动生成一个 pom.xml
文件.
我们需要在 pom.xml
中引入 Servlet API
依赖的 jar
包.
servlet
”, 一般第一个结果就是.tomcat
版本是8.5.49,对应使用的servlet
版本为 3.1.0 版本。可以在 http://tomcat.apache.org/whichversion.html 查询版本对应关系.xml
复制到项目的 pom.xml
中pom.xml
:<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>org.examplegroupId>
<artifactId>servlet-testartifactId>
<packaging>warpackaging>
<version>1.0-SNAPSHOTversion>
<name>servlet-test Maven Webappname>
<url>http://maven.apache.orgurl>
<dependencies>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.1.0version>
<scope>providedscope>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>3.8.1version>
<scope>testscope>
dependency>
dependencies>
<build>
<finalName>servlet-testfinalName>
build>
project>
当项目创建好了之后, IDEA 会帮我们自动创建出一些目录. 形如
src
表示源代码所在的目录main/resources
表示项目的一些资源文件所在的目录. 此处暂时不关注.main/webapp
webapp
目录就是未来部署到 Tomcat
中的一个重要的目录.当前我们可以往 webapp
中放一些静态资源, 比如 html
, css
等. 在这个目录中还有一个重要的文件 web.xml
. Tomcat
找到这个文件才能正确处理 webapp
中的动态资源.
1) 创建 java 目录
在 main
目录下, 和resources
目录并列, 创建一个 java 目录 .
在 java 目录中创建一个类 HelloServlet
, 代码如下:
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 {
// 获取前端参数
String name = req.getParameter("name");
// 编码设置方式1
// resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html; charset=utf-8");
// 将结果返回给前端
resp.getWriter().println("Jackson,");
// System.out.println("hello");
resp.getWriter().write("hello");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//将请求转发到 doget 方法中
this.doGet(req,resp);
}
}
src/main
下创建Java包,然后在Java包下创建一个类。@WebServlet("/hello")
注解, 表示 Tomcat
收到的请求中,路径为/hello
的请求才会调用 HelloServlet
这个类的代码.(这个路径未包含 Context Path
)doGet
方法. doGet
的参数有两个, 分别表示收到的 HTTP 请求
和要构造的 HTTP 响应
.这个方法会在 Tomcat
收到 GET
请求时触发HttpServletRequest
表示 HTTP 请求
. Tomcat
按照 HTTP
请求的格式把 字符串 格式的请求转成了一个 HttpServletRequest
对象. 后续想获取请求中的信息(方法, url, header, body 等) 都是通过这个对象来获取.HttpServletResponse
表示 HTTP 响应
. 代码中把响应对象构造好(构造响应的状态码, header, body 等)resp.getWriter()
会获取到一个流对象, 通过这个流对象就可以写入一些数据, 写入的数据会被构造成一个 HTTP
响应的 body
部分, Tomcat 会把整个响应转成字符串, 通过 socket 写回给浏览器.注意:
main
方法作为入口了. main
方法已经被包含在 Tomcat
里, 我们写的代码会被 Tomcat
在合适的时机调用起来. 此时我们写的代码并不是一个完整的程序, 而是 Tomcat
这个程序的一小部分逻辑.Tomcat
调用嘛? 满足啥样条件才能被调用呢? 主要满足三个条件:a) 创建的类需要继承自 HttpServlet
b) 这个类需要使用 @WebServlet
注解关联上一个 HTTP
的路径
c) 这个类需要实现 doXXX
方法.
当这三个条件都满足之后, Tomcat
就可以找到这个类, 并且在合适的时机进行调用.
使用 maven
进行打包. 打开 maven 窗口 (一般在 IDEA 右侧就可以看到 Maven 窗口, 如果看不到的话, 可以通过 菜单 -> View -> Tool Window -> Maven 打开)
然后展开 Lifecycle
, 双击 package
即可进行打包.
如果比较顺利的话, 能够看到 SUCCESS 这样的字样:
如果代码/配置/环境存在问题, 可能会提示 BUILD FAILED
, 可以根据具体提示的错误信息具体解决.
把 war 包拷贝到 Tomcat
的 webapps
目录下.
(1)从项目的target
目录下找到.war
包,将这个包复制到Tomcat
的 webapps
目录下.
(1)启动Tomcat
(点击tomcat
的bin
目录下的startup.bat
)Tomcat
就会自动把 war
包解压缩.
看到这个日志说明 Tomcat 已经正确识别了这个 webapp.
(2)此时通过浏览器访问 http://localhost:8080/servlet-test/hello,就可以看到结果了.
手动拷贝 war 包到 Tomcat 的过程比较麻烦. 我们还有更方便的办法.
此处我们使用 IDEA 中的 Smart Tomcat 插件完成这个工作.
如果你的idea是社区版(专业版不用安装,idea已经内置了):
Add Configuration
”Smart Tomcat
”Name
这一栏填写一个名字(可以随便写)Tomcat Server
这一栏选择 Tomcat
所在的目录. 其他的选项不必做出修改.OK
之后, 右上角变成了IDEA
就会自动进行编译, 部署, 启动 Tomcat
的过程.Tomcat
日志就会输出在 IDEA
的控制台中, 可以看到现在就不再乱码了.404 表示用户访问的资源不存在. 大概率是 URL
的路径写的不正确.
错误实例1: 少写了 Context Path
通过 /hello 访问服务器
错误实例2: 少写了 Servlet Path
通过/ServletHelloWorld
访问服务器
错误实例3: Servlet Path
写的和 URL
不匹配
修改 @WebServlet
注解的路径
重启 Tomcat
服务器.
URL
中的路径写作 “/hello
” , 而代码中写作的 Servlet Path
为 “/helloServlet
”, 两者不匹配.
错误实例4: web.xml
写错了
清除 web.xml
中的内容,重启 Tomcat
服务器.
通过浏览器访问 URL
, 可以看到:
405 表示对应的 HTTP
请求方法没有实现.
**错误实例:**没有实现 doGet
方法.
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
}
重启 Tomcat
服务器.
在浏览器中访问, 可以看到:
在浏览器地址栏直接输入 URL
, 会发送一个 HTTP GET
请求.
此时就会根据 /ServletHelloWorld/hello
这个路径找到 HelloServlet
这个类. 并且尝试调用
HelloServlet
的 doGet
方法.
但是如果没有实现 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());
}
}
重启 Tomcat
服务器.
重新访问页面, 可以看到:
在页面上已经有具体的异常调用栈.
异常信息里已经提示了出现异常的代码是 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");
}
}
一般是 Tomcat
启动就失败了.
错误实例: Servlet Path
写错了.
应该写作 “/hello
”, Tomcat
在启动的时候已经提示了相关的错误.
Tomcat 启动的日志里面报错信息可能比较多, 需要耐心观察, 找到关键的提示.
看到的现象:
4xx
的状态码表示路径不存在, 往往需要检查 URL
是否正确, 和代码中设定的 Context Path
以及 Servlet Path
是否一致.5xx
的状态码表示服务器出现错误, 往往需要观察页面提示的内容和 Tomcat
自身的日志, 观察是否存在报错.Tomcat
没有正确启动, 也需要观察 Tomcat
的自身日志是否有错误提示.HTTP
请求响应的具体交互过程.