Bootstrap

Servlet 的初次部署

目录

1. servlet 主要工作

2. 第一个 Servlet 程序

2.1 创建项目

 2.2 引入依赖

 2.3创建目录

2.4  编写代码

2.5 打包程序

 2.6 部署程序

 2.7 验证程序

 2.8 总结

3.更便捷的部署 

3.1 安装 Smart Tomcat 插件

3.2 配置 Smart Tomcat 插件

4.常见出错问题

4.1 出现 404

4.2 出现 405

 4.3 出现 500

 4.4 出现 "空白页面"

 4.5 出现 "无法访问此网站"

 5. 总结


1. servlet 主要工作

       servlet 是一种实现动态页面的技术,是一组Tomcat 提供给程序员的 API,帮组程序员简单高效的开发一个 web app。而不必关注 Socket,HTTP协议格式多线程并发等技术细节,降低了 web app 的开发门槛, 提高了开发效 率。

Servlet 主要做的工作
      允许程序猿注册一个类 ,, Tomcat 收到某个特定的 HTTP 请求的时候 ,, 执行这个类中的一些代码。
      帮助程序猿解析 HTTP 请求 HTTP 请求从一个字符串解析成一个 HttpRequest 对象。
      帮助程序猿构造 HTTP 响应。 程序猿只要给指定的 HttpResponse 对象填写一些属性字段  ,Servlet 就会自动的安装 HTTP 协议的方式构造出一个 HTTP 响应字符串 ,, 并通过 Socket 写回给客户端。

2. 第一个 Servlet 程序

2.1 创建项目

使用 IDEA 创建一个 Maven 项目。
1) 菜单 -> 文件 -> 新建项目 -> Maven

2) 选择项目要存放的目录

 3) 项目创建完毕

 2.2 引入依赖

Maven 项目创建完毕后 , 会自动生成一个 pom.xml 文件。 我们需要在 pom.xml 中引入 Servlet API 依赖的 jar 包。这个API 不是JDK 内置的,而是第三方Tomcat 提供的。Maven中央仓库地址:
https://mvnrepository.com/ ,在里面进行 Servlet API的复制,将下面第五步的代码复制到pom.xml 里面。

<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>

刚复制过来的时候,是标红的状态,那是因为我们的IDEA 还没有下载好 .jar 包。这就需要我们手动点击IDEA的右上方的Maven 的刷新图标,等待下载即可。

 2.3创建目录

当项目创建好了之后 , IDEA 会帮我们自动创建出一些目录 . 形如

但是,这些目录还不够,需要我们手动添加一些必要的目录。

1)webapp

2) 创建 web.xml
然后在 webapp 目录内部创建一个 WEB - INF 目录 , 并创建一个 web.xml 文件
3) 编写 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>

,如果在IDEA中,以下代码出现标红,进行以下操作即可。

2.4  编写代码

java 目录中创建一个类 HelloServlet, 代码如下

import javax.servlet.annotation.WebServlet;
import javax.servlet.ServletException;
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 {
        //这一行代码要注释掉,不能引用父类的 doGet
        //super.doGet(req, resp);

        //这个是让服务器在自己的控制台里打印
        System.out.println("hello world");
        //在页面上也能打印 hello world 字符串,放到 http 响应的 body 中. 浏览器就会把 body 的内容
        //显示到页面上
        //如果不给响应对象中设置任何内容, 这个时候就会出现 空白页面
        resp.getWriter().write("hello world" + System.currentTimeMillis());
    }
}

在上述代码中:

-创建一个类 HelloServlet , 继承自 HttpServlet
- 在这个类上方加上 @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 写回给浏览 器。
注意,要想写的类 能被 Tomcat 调用,就必须满足以下条件
a) 创建的类需要继承自 HttpServlet
b) 这个类需要使用 @WebServlet 注解关联上一个 HTTP 的路径
c) 这个类需要实现 doXXX 方法

2.5 打包程序

当前的代码,是不能单独运行的(没有main方法) 当前的代码,是不能单独运行的(没有Main方法)
需要把当前的代码,打包,然后部署到Tomcat.上, 由Tomcat来进行调用, 需要把当前的代码,打包,然后部署到Tomcat.上,由Tomcat来进行调用。

在打包前,先在 pom.xml 里面增加一个 <packaging>war</packaging> ,因为我们打包的是war 包,如果不写的话,会默认 jar 包。

jar 和 war 都是 java 发布程序用的压缩包格式。war 算是给 Tomcat 专门搞的。这里不光会包含一些 .class,还可以包含配置文件,以及依赖的第3三方的jar ,还有html, Css, js....
添加位置如下

使用 maven 进行打包 . 打开 maven 窗口 ( 一般在 IDEA 右侧就可以看到 Maven 窗口 , 如果看不到的话 , 可以通过 菜单 -> View -> Tool Window -> Maven 打开
然后展开 Lifecycle , 双击 package 即可进行打包。

 当控制台出现 BUILD SUCCESS,并且目录列表出现servlet_hello.war 就表明打包成功

 2.6 部署程序

 打开之后 war 包拷贝到 Tomcat webapps 目录下。然后启动 Tomcat , Tomcat 就会自动把 war 包解压缩。

 2.7 验证程序

通过浏览器输入直接部署的网址,就可以得到响应 http://127.0.0.1:8080/servlet_hello/hello,如下

 注意: URL 中的 PATH 分成两个部分, 其中 servlet_hello  Context Path, hello Servlet Path

 2.8 总结

上述这七个步骤,这是针对一个新的项目,项目创建好之后,后续修改代码,前三个步骤就不必重复了.直接从4—7进行操作即可。

3.更便捷的部署 

手动拷贝 war 包到 Tomcat 的过程比较麻烦 . 我们还有更方便的办法。 此处我们使用 IDEA 中的 Smart Tomcat 插件完成这个工作。

3.1 安装 Smart Tomcat 插件

菜单 -> 文件 -> Settings ->选择 Plugins, 选择 Marketplace, 搜索 "tomcat", 点击 "Install".
安装完毕之后 , 会提示 " 重启 IDEA"

3.2 配置 Smart Tomcat 插件

1) 点击右上角的 "Add Configuration。 2) 点击+号,3) 选择左侧的 "Smart Tomcat"
4) 在Name这一栏填写一个名字 ( 可以随便写)。5)选择 Tomcat的安装路径

 点击绿色的三角号, IDEA就会自动进行编译,部署

启动Tomcat的过程,其中字体就是红色的,不是出错才显红色。

使用 Smart Tomcat 部署的时候 , 我们发现 Tomcat webapps 内部并没有被拷贝一个 war ,
也没有看到解压缩的内容。Smart Tomcat 相当于是在 Tomcat 启动的时候直接引用了项目中的 webapp target 目录。

4.常见出错问题

4.1 出现 404

404 表示用户访问的资源不存在 . 大概率是 URL 的路径写的不正确。
在当前,正确的是 http://127.0.0.1:8080/servlet_hello/hello
 1) 少写了 Context Path 即servlet_hello

 2)少写了 Servlet Path 即 hello

 3)Servlet Path 写的和 URL 不匹

修改 @WebServlet 注解的路径,此处正确的如下

 错误如下

 4)web.xml 写错了

4.2 出现 405

405 表示对应的 HTTP 请求方法没有实现。
1) 没有实现 doGet 方法 .
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
//被注释掉,所以没有实现doGet 方法
  //@Override
    //protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { }
}

 4.3 出现 500

往是 Servlet 代码中抛出异常导致的。
错误实例 : 修改代码
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServlet Requestreq, HttpServlet Responseresp) throws Servlet Exception, IOException {
        String s = null;
        resp.getWriter().write(s.length());
    }
}

 4.4 出现 "空白页面"

错误实例 : 修改代码, 注释掉  resp.getWritter().write() 操作.

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //这一行代码要注释掉,不能引用父类的 doGet
        //super.doGet(req, resp);

        //这个是让服务器在自己的控制台里打印
        System.out.println("hello world");
        //在页面上也能打印 hello world 字符串,放到 http 响应的 body 中. 浏览器就会把 body 的内容
        //显示到页面上
        //如果不给响应对象中设置任何内容, 这个时候就会出现 空白页面
        //resp.getWriter().write("hello world" + System.currentTimeMillis());
    }
}

 4.5 出现 "无法访问此网站"

一般是 Tomcat 启动就失败了 .
 
错误实例 : Servlet Path 写错了。
//把
@WebServlet("/hello")
//写成了,就是少了个 /
@WebServlet("hello")

 5. 总结

初学 Servlet, 遇到的这类问题会非常多 . 我们不光要学习 Servlet 代码的基本写法 , 也要学习 排查错误的
4xx 的状态码表示路径不存在 , 往往需要检查 URL 是否正确 , 和代码中设定的 Context Path 以及
Servlet Path 是否一致。
5xx 的状态码表示服务器出现错误 , 往往需要观察页面提示的内容和 Tomcat 自身的日志 , 观察是否
存在报错。
出现连接失败往往意味着 Tomcat 没有正确启动 , 也需要观察 Tomcat 的自身日志是否有错误提示 .
空白页面这种情况则需要我们使用抓包工具来分析 HTTP 请求响应的具体交互过程。
;