zoukankan      html  css  js  c++  java
  • Maven项目+内嵌tomcat+Servlet

    写在前面

    上篇文章 使用 Intellij IDEA 新建一个 Servlet 项目 ,文章中如何在 Intellij IDEA 中启动 Tomcat 并加载 webapp,但是配置的过程十分繁琐。至少需要进行以下三项的设置:

    1. Add Configuration
    2. Project Structure -> Modules -> Web
    3. Project Structure -> Artifacts -> Add Artifact
    4. Project Structure -> Libraries -> Add Java Library

    这个繁琐的过程,不是一个初学者,尤其是想要立马开始敲代码的开发者想要的。因此,我们需要一种简单可靠,能直接在 IDE 中启动并调试 webapp 的方法。

    项目地址

    git clone https://gitee.com/kendoziyu/code-servlet-parent.git
    

    其中,maven-tomcat-servlet-example 是本文的项目示例。

    Maven 配置文件

    我们新建一个 maven-tomcat-servlet-example 工程,编写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>coderead.servlet</groupId>
        <artifactId>maven-tomcat-servlet-example</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>war</packaging>
    
        <properties>
            <servlet-api.version>3.1.0</servlet-api.version>
            <tomcat.version>9.0.39</tomcat.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-core</artifactId>
                <version>${tomcat.version}</version>
                <scope>provided</scope>
            </dependency>
    
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-jasper</artifactId>
                <version>${tomcat.version}</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    
        <build>
            <finalName>Hello</finalName>
        </build>
    </project>
    

    其中,<packaging> 类型为 war,引入依赖 tomcat-embed-coretomcat-embed-jasper,引入的 Tomcat 版本 <tomcat.version>9.0.39

    tomcat-embed-core 依赖包含 javax.servlet 下的内容,因此需要再额外引入依赖 javax.servlet-api

    <scope>指定为 provided,表示编译时使用,但不会打包到.war文件中,因为运行期 Web服务器本身已经提供了 Servlet API 相关的 jar 包。

    我们目光转到 <finalName> 这个标签,这个标签将决定你所打包的 war 包的名称。在本文的后续的 Tomcat 部署 war 章节,会为大家展示打包操作。

    使用 WebServlet 注解

    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;
    import java.io.PrintWriter;
    
    @WebServlet(urlPatterns = "/")
    public class HelloServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html");
            String name = req.getParameter("name");
            if (name == null) {
                name = "world";
            }
            PrintWriter pw = resp.getWriter();
            pw.write("<h1>Hello, " + name + "!</h1>");
            pw.flush();
        }
    }
    

    使用@WebServlet注解,可以简化繁琐的 xml 配置。使用注解前web.xml 配置如下:

    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
             version="3.1">
    
        <servlet>
            <servlet-name>helloServlet</servlet-name>
            <servlet-class>coderead.servlet.HelloServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>helloServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    

    改为使用注解以后web.xml 配置如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
             version="3.1">
    
    </web-app>
    

    1 行的 Java 注解,可以减少 8 行 xml 配置,何乐而不为呢?

    Main 函数启动

    因为Tomcat实际上也是一个Java程序,我们看看Tomcat的启动流程:

    1. 启动 JVM 并执行 Tomcat 的 main() 方法;
    2. 加载 war 并初始化 Servlet;
    3. 正常服务。

    启动Tomcat无非就是设置好 classpath 并执行 Tomcat 某个 jar 包的 main() 方法,我们完全可以把 Tomcat 的 jar 包全部引入进来,然后自己编写一个 main() 方法,先启动 Tomcat,然后让它加载我们的 webapp 就行。

    Main.java

    import org.apache.catalina.Context;
    import org.apache.catalina.LifecycleException;
    import org.apache.catalina.WebResourceRoot;
    import org.apache.catalina.startup.Tomcat;
    import org.apache.catalina.webresources.DirResourceSet;
    import org.apache.catalina.webresources.StandardRoot;
    
    import java.io.File;
    
    public class Main {
    
        public static void main(String[] args) throws LifecycleException {
            // 启动 tomcat
            Tomcat tomcat = new Tomcat();
            tomcat.setPort(Integer.getInteger("port", 8080));
            tomcat.getConnector();
            // 创建 WebApp
            Context context = tomcat.addWebapp("", new File("src/main/webapp").getAbsolutePath());
            WebResourceRoot resources = new StandardRoot(context);
            resources.addPreResources(
                    new DirResourceSet(resources, "/WEB-INF/classes",
                            new File("target/classes").getAbsolutePath(), "/"));
            context.setResources(resources);
    
            tomcat.start();
            tomcat.getServer().await();
        }
    }
    

    小插曲:我在第一次写 Demo 的时候,遇到了一个 WebServlet 不生效的问题,我最后发现,我没有为 context 设置资源。也就是没写 context.setResources(resources); 这句话。囧

    至此,我们已经搞定了一个启动方便,且可以本地调试的 Servlet 程序。接着我们就来讲讲 war 包部署到 Tomcat 容器。

    运维篇:war 包部署

    本文还是选择在 Windows 上演示,作为开发,有时候不会真的上手部署项目到 Tomcat 容器上,但是我们还是可以了解一下大致的流程。

    打包 war 包

    如果使用 Intellij Idea,打包位置如下:

    这个对应的命令就是 mvn package,也可以在项目根目录下执行该命令。输出结果如下

    红色框1部分Hello 文件夹 其实就是 war 包里面的内容, Hello.war 相当于是压缩包,只不过后缀是 .war

    拷贝 war 包

    Hello.war 拷贝到 Tomcat 安装目录的 webapps 文件夹下(如果你的 Tomcat 版本不支持的话,你还是解压一下吧)。然后,我们就可以在浏览器中通过 http://localhost:8080/Hello/ 访问该项目了。

    如果想直接用 http://localhost:8080/ 访问我们的项目,

    • 首先把 webapps 备份一下,我把它改名为 webapps_backup
    • 重新创建一个全新的文件夹 webapps,并创建一个子文件夹 ROOT,然后把 Hello.war 解压一下

    经过上面两步骤就可以直接用 localhost:端口号 访问了~

    参考博客

    廖雪峰的官方网站之Servlet开发
    Create a Java Web Application Using Embedded Tomcat

  • 相关阅读:
    python之路day08--文件的操作
    python之路day07-集合set的增删查、列表如何排重(效率最高的方法)、深浅copy
    python之路day06-python2/3小区别,小数据池的概念,编码的进阶str转为bytes类型,编码和解码
    python之路day05--字典的增删改查,嵌套
    python之路day04--列表的增删改查,嵌套、元组的嵌套、range、for循环嵌套
    python之路day03--数据类型分析,转换,索引切片,str常用操作方法
    python之路day02--格式化输出、初始编码、运算符
    python之路day01--变量
    线程、进程、协程 异步io
    Ubuntu学习(转载)
  • 原文地址:https://www.cnblogs.com/kendoziyu/p/embedded-tomcat-servlet.html
Copyright © 2011-2022 走看看