运行一个servlet项目

运行一个servlet项目

1. 创建项目

使用 IDEA 创建一个 Maven 项目.

  1. 菜单 -> 文件 -> 新建项目 -> Maven
    运行一个servlet项目_第1张图片

创建好后的项目:
运行一个servlet项目_第2张图片

2. 引入依赖

Maven 项目创建完毕后, 会自动生成一个 pom.xml 文件.
我们需要在 pom.xml 中引入 Servlet API 依赖的 jar 包.

  1. 在中央仓库 https://mvnrepository.com/ 中搜索 “servlet”, 一般第一个结果就是.
    运行一个servlet项目_第3张图片
  2. 选择版本(点击版本号). 我的tomcat版本是8.5.49,对应使用的servlet版本为 3.1.0 版本。可以在 http://tomcat.apache.org/whichversion.html 查询版本对应关系.
  3. 把中央仓库中提供的 xml 复制到项目的 pom.xml
    运行一个servlet项目_第4张图片
    修改后的 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>

这个时候点击右上角的image.png,如果没有:
运行一个servlet项目_第5张图片

3. 创建目录

当项目创建好了之后, IDEA 会帮我们自动创建出一些目录. 形如
运行一个servlet项目_第6张图片

  • src 表示源代码所在的目录
  • main/resources 表示项目的一些资源文件所在的目录. 此处暂时不关注.
  • main/webapp webapp 目录就是未来部署到 Tomcat 中的一个重要的目录.

当前我们可以往 webapp 中放一些静态资源, 比如 html , css 等. 在这个目录中还有一个重要的文件 web.xml. Tomcat 找到这个文件才能正确处理 webapp 中的动态资源.
1) 创建 java 目录
main 目录下, 和resources目录并列, 创建一个 java 目录 .
运行一个servlet项目_第7张图片

结果如下:
运行一个servlet项目_第8张图片

4. 编写代码

在 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 写回给浏览器.

注意:

    1. 我们的代码不是通过 main 方法作为入口了. main 方法已经被包含在 Tomcat 里, 我们写的代码会被 Tomcat 在合适的时机调用起来. 此时我们写的代码并不是一个完整的程序, 而是 Tomcat 这个程序的一小部分逻辑.
    1. 我们随便写个类都能被 Tomcat 调用嘛? 满足啥样条件才能被调用呢? 主要满足三个条件:

a) 创建的类需要继承自 HttpServlet
b) 这个类需要使用 @WebServlet 注解关联上一个 HTTP 的路径
c) 这个类需要实现 doXXX 方法.
当这三个条件都满足之后, Tomcat 就可以找到这个类, 并且在合适的时机进行调用.

5. 打包程序

使用 maven 进行打包. 打开 maven 窗口 (一般在 IDEA 右侧就可以看到 Maven 窗口, 如果看不到的话, 可以通过 菜单 -> View -> Tool Window -> Maven 打开)
然后展开 Lifecycle , 双击 package 即可进行打包.
运行一个servlet项目_第9张图片
如果比较顺利的话, 能够看到 SUCCESS 这样的字样:
运行一个servlet项目_第10张图片

如果代码/配置/环境存在问题, 可能会提示 BUILD FAILED, 可以根据具体提示的错误信息具体解决.

6. 部署程序

把 war 包拷贝到 Tomcatwebapps 目录下.
(1)从项目的target目录下找到.war包,将这个包复制到Tomcatwebapps 目录下.

运行一个servlet项目_第11张图片

7. 验证程序

(1)启动Tomcat(点击tomcatbin目录下的startup.batTomcat 就会自动把 war 包解压缩.
运行一个servlet项目_第12张图片
看到这个日志说明 Tomcat 已经正确识别了这个 webapp.
(2)此时通过浏览器访问 http://localhost:8080/servlet-test/hello,就可以看到结果了.
运行一个servlet项目_第13张图片

更方便的部署方式

手动拷贝 war 包到 Tomcat 的过程比较麻烦. 我们还有更方便的办法.
此处我们使用 IDEA 中的 Smart Tomcat 插件完成这个工作.
如果你的idea是社区版(专业版不用安装,idea已经内置了):

安装 Smart Tomcat 插件

  1. 菜单 -> 文件 -> Settings
  2. 选择 Plugins, 选择 Marketplace, 搜索 “tomcat”, 点击 “Install”. (注意: 安装过程必须要联网. )
    运行一个servlet项目_第14张图片

配置 Smart Tomcat 插件

  1. 点击右上角的 “Add Configuration
    image.png
  2. 选择左侧的 “Smart Tomcat
    运行一个servlet项目_第15张图片
  3. Name 这一栏填写一个名字(可以随便写)
    Tomcat Server 这一栏选择 Tomcat 所在的目录. 其他的选项不必做出修改.
    运行一个servlet项目_第16张图片
  4. 点击 OK 之后, 右上角变成了
    image.png
    点击绿色的三角号, IDEA 就会自动进行编译, 部署, 启动 Tomcat 的过程.
    此时 Tomcat 日志就会输出在 IDEA 的控制台中, 可以看到现在就不再乱码了.
    运行一个servlet项目_第17张图片
  5. 访问页面.
    在浏览器中使用http://localhost:8080/servlet-test/hello访问页面.
    运行一个servlet项目_第18张图片

访问出错怎么办?

出现 404

404 表示用户访问的资源不存在. 大概率是 URL 的路径写的不正确.
错误实例1: 少写了 Context Path
通过 /hello 访问服务器
运行一个servlet项目_第19张图片

错误实例2: 少写了 Servlet Path
通过/ServletHelloWorld访问服务器
运行一个servlet项目_第20张图片

错误实例3: Servlet Path 写的和 URL 不匹配
修改 @WebServlet 注解的路径
运行一个servlet项目_第21张图片
重启 Tomcat 服务器.
URL 中的路径写作 “/hello” , 而代码中写作的 Servlet Path 为 “/helloServlet”, 两者不匹配.
运行一个servlet项目_第22张图片

错误实例4: web.xml 写错了
清除 web.xml 中的内容,重启 Tomcat 服务器.
通过浏览器访问 URL, 可以看到:
运行一个servlet项目_第23张图片

出现 405

405 表示对应的 HTTP 请求方法没有实现.
**错误实例:**没有实现 doGet 方法.

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
}

重启 Tomcat 服务器.
在浏览器中访问, 可以看到:
运行一个servlet项目_第24张图片
在浏览器地址栏直接输入 URL , 会发送一个 HTTP GET 请求.
此时就会根据 /ServletHelloWorld/hello 这个路径找到 HelloServlet 这个类. 并且尝试调用
HelloServletdoGet 方法.
但是如果没有实现 doGet 方法, 就会出现上述现象.

出现 500

往往是 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 服务器.
重新访问页面, 可以看到:
运行一个servlet项目_第25张图片
在页面上已经有具体的异常调用栈.
异常信息里已经提示了出现异常的代码是 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");
   }
}

重启服务器,
访问服务器, 可以看到一个空白页面:
运行一个servlet项目_第26张图片

出现 “无法访问此网站”

一般是 Tomcat 启动就失败了.
错误实例: Servlet Path 写错了.
运行一个servlet项目_第27张图片
应该写作 “/hello”, Tomcat 在启动的时候已经提示了相关的错误.
Tomcat 启动的日志里面报错信息可能比较多, 需要耐心观察, 找到关键的提示.
运行一个servlet项目_第28张图片
看到的现象:
运行一个servlet项目_第29张图片

小结:

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

你可能感兴趣的:(JavaEE,servlet,java,tomcat)