Java原生启动Tomcat

文章目录

  • 引入依赖
  • 启动Tomcat代码示例
    • 将嵌入式 Tomcat 服务器用于已有的 WAR 文件
    • 为现有的 Java Web 应用程序嵌入 Tomcat 服务器
  • 相关API
    • Tomcat API
    • Contonxt API
  • 启动错误
  • springboot底层Tomcat的实现
  • 学习博客


引入依赖

maven:

<dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId><version>${tomcat.version}</version>
</dependency>
<dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><version>${tomcat.version}</version>
</dependency>
<dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-logging-juli</artifactId><version>${tomcat.version}</version>
</dependency>
<properties><tomcat.version>8.0.48</tomcat.version>
</properties>

gradle:

dependencies {implementation 'org.apache.tomcat.embed:tomcat-embed-core:9.0.54'implementation 'javax.servlet:jstl:1.2' // 若需要JSTL支持
}

其他 :

如果您不使用 Maven,请 下载 以下 JAR 文件并将其添加到项目的类路径中:

ecj-3.12.3.jar
tomcat-annotations-api-8.0.48.jar
tomcat-embed-core-8.0.48.jar
tomcat-embed-el-8.0.48.jar
tomcat-embed-jasper-8.0.48.jar
tomcat-embed-logging-juli-8.0.48.jar

启动Tomcat代码示例

完整示例:

public static void test() throws LifecycleException {Tomcat tomcat = new Tomcat();tomcat.setBaseDir("/");// 设置服务器工作的基本目录。tomcat.setHostname("127.0.0.1");// 设置默认主机的主机名tomcat.setPort(8090);// 设置默认连接器的端口号Context context = tomcat.addContext("/context-url", null);// 添加上下文,映射路径为'context-url'// add context initialization parameterscontext.addParameter("param1", "value1");context.addParameter("param2", "value2");context.addErrorPage(new ErrorPage());context.setCookies(true);context.setSessionTimeout(30);// 现有的 Java servlet 添加到 Web 应用程序;addServlet要在addServletMappingDecoded之前执行//tomcat.addServlet("/context-url","defaultServlet",new IndexServlet());// 为context上下文添加servlettomcat.addServlet(context,"defaultServlet",new IndexServlet());// 为名称defaultServlet的servlet添加一个映射路径为'v1'context.addServletMappingDecoded("/v1","defaultServlet");//为 servlet 配置 URL 映射tomcat.start();tomcat.getServer().await();//阻塞}

Servlet :

public class IndexServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().print("this is index... tomcat");}}
public class XmlServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {PrintWriter writer = resp.getWriter();writer.println("<html><title>Welcome</title><body>");writer.println("<h1>Have a Great Day!</h1>");writer.println("</body></html>");}}

启动成功 :

103, 2024 3:57:45 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["http-nio-8090"]
103, 2024 3:57:47 下午 org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
信息: Using a shared selector for servlet write/read
103, 2024 3:57:47 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service [Tomcat]
103, 2024 3:57:47 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/8.5.28
103, 2024 3:57:49 下午 org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
警告: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [1,186] milliseconds.
103, 2024 3:57:49 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-nio-8090"]

访问 :http://127.0.0.1:8090/context-url/v1
在这里插入图片描述

访问 :http://127.0.0.1:8090/context-url/v2
在这里插入图片描述

将嵌入式 Tomcat 服务器用于已有的 WAR 文件

假设您在Bookstore.war文件中打包了一个 Java Web 应用程序,以下程序将创建一个 Tomcat 实例并从 WAR 文件中添加一个 Web 应用程序:

public class RunWarExample {public static void main(String[] args) throws ServletException, LifecycleException {Tomcat tomcat = new Tomcat();tomcat.setBaseDir("temp");tomcat.setPort(8080);String contextPath = "/bookstore";   String warFilePath = "D:\\Web\\Website\\Bookstore.war";tomcat.getHost().setAppBase(".");tomcat.addWebapp(contextPath, warFilePath);tomcat.start();tomcat.getServer().await();}
}

运行此程序,您可以看到 WAR 文件的内容被提取到基本目录,您可以使用指定的上下文路径访问 Web 应用程序。

这种方法对于测试打包在 WAR 文件中的现有 Web 应用程序非常方便,并且您不必接触它们的代码。

对于此类应用程序,以与程序化 Web 应用程序中所述相同的方式生成可执行 JAR 文件。

为现有的 Java Web 应用程序嵌入 Tomcat 服务器

这也许是嵌入式 Tomcat 最常用的特性。这是这样的场景:您正在开发一个 Java Web 应用程序,现在您想要嵌入 Tomcat 以进行单元测试或将 Web 应用程序作为独立的 Java 程序交付。那么如何制作呢?

假设您的 Web 应用程序的文件存储在名为WebContent的目录中,如下所示:
在这里插入图片描述

以下程序启动一个嵌入式 Tomcat 实例来运行 Web 应用程序:

public class EmbeddedTomcatTest {public static void main(String[] args) throws LifecycleException, ServletException {String contextPath = "/UploadApp";String webappDir = new File("WebContent").getAbsolutePath();Tomcat tomcat = new Tomcat();tomcat.setBaseDir("temp");tomcat.setPort(8080);tomcat.addWebapp(contextPath, webappDir);tomcat.start();tomcat.getServer().await();    }
}

现在您可以使用浏览器使用上面程序中指定的端口号和上下文路径访问 Web 应用程序:

http://localhost:8080/UploadApp/upload.jsp

相关API

Tomcat API

  • setBaseDir(String baseDir):设置服务器工作的基本目录。这应该是第一个调用的方法。默认情况下,Tomcat 尝试按以下顺序使用这些系统属性:catalina.base、catalina.home和user.dir。

  • setHostname(String name):设置默认主机的主机名。默认为“本地主机”。

  • setPort(int port):设置默认连接器的端口号。

  • addContext(String contextPath,String docBase) : 向服务器添加上下文
    其中contextPath是 Web 应用程序名称,docBase是应用程序的基本目录。此方法返回一个表示单个 Web 应用程序的Context对象。您可以使用此Context对象来配置 Web 应用程序的各个方面,例如:

// add context initialization parameters
context.addParameter("param1", "value1");
context.addParameter("param2", "value2");context.addErrorPage(new ErrorPage());
context.setCookies(true);
context.setSessionTimeout(30);
  • addServlet(String contextPath, String servletName, Servlet servlet):将现有的 Java servlet 添加到 Web 应用程序。contextPath为context的访问路径,必须在当前Tomcat容器中已经存在。
    • 或者使用下面的静态方法:
Tomcat.addServlet(Context context,String servletName,Servlet servlet)

Contonxt API

  • addServletMappingDecoded(String urlPattern, String servletName):为 servlet 配置 URL 映射,为Context类的方法

使Tomcat异步阻塞等待请求:

tomcat.getServer().await();

在服务启动后,一定要调用 await() 方法异步进行接收请求,否则服务器启动成功就直接关闭了。

启动、停止和销毁服务器:

  • tomcat.start()
  • tomcat.stop()
  • tomcat.destroy()

Tomcat-Java类 官方描述

Tomcat-Java接口 官方API

启动错误

当tomcat为 9.0+ 时,运行最后一直卡在以下步骤运行不起来。

警告: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [773] milliseconds.

解决 : 降低为8.x.x解决

springboot底层Tomcat的实现

创建spring容器并启动Tomcat :

可将已有的Spring+mvc升级成SpringBoot

@Target(ElementType.TYPE)  //类注解
@Retention(RetentionPolicy.RUNTIME)  //运行时
@Documented
@Inherited
@ComponentScan  //springboot扫描bean,内部spring容器就会有独赢controller的bean
public class MySpringApplication {public static void run(Class clazz){//创建一个spring容器AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();applicationContext.register(clazz);  //配置类applicationContext.refresh();//启动tomcatstartTomcat(applicationContext);}/*** 配置tomcat* WebApplicationContext:spring容器*/public static void startTomcat(WebApplicationContext applicationContext){Tomcat tomcat = new Tomcat();Server server = tomcat.getServer();Service service = server.findService("Tomcat");Connector connector = new Connector();connector.setPort(8081);StandardEngine engine = new StandardEngine();engine.setDefaultHost("localhost");StandardHost host = new StandardHost();host.setName("localhost");String contextPath = "";Context context = new StandardContext();context.setPath(contextPath);context.addLifecycleListener(new Tomcat.FixContextListener());host.addChild(context);engine.addChild(host);service.setContainer(engine);service.addConnector(connector);//关键:向tomcat容器添加dispatcherServlet的servlet,DispatcherServlet需要很具接受的请求去匹配某个controller中的对应方法tomcat.addServlet(contextPath, "dispatcher",new DispatcherServlet(applicationContext));  //SpringMVC中的DispatcherServlet,其中还有所有controller和注解,applicationContext就是所有Controller的所有的beancontext.addServletMappingDecoded("/*","dispatcher");  //接收的所有请求交给dispatcher处理try {tomcat.start();} catch (LifecycleException e) {e.printStackTrace();}}
}

启动类:

@MySpringBootApplication
public class MyApplication {public static void main(String[] args) {MySpringApplication.run(MyApplication.class);}
}

测试类:

@RestController
public class UserController {@GetMappingpublic String test(){return "xuyu";}
}

学习博客

当前博客的参考及示例博客原文

Tomcat中<Context>标签的使用方式和注意事项

Tomcat的xml基础配置

SpringBoot中整合Tomcat源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/229798.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在无公网IP环境使用Windows远程桌面Ubuntu

文章目录 一、 同个局域网内远程桌面Ubuntu二、使用Windows远程桌面连接三、公网环境系统远程桌面Ubuntu1. 注册cpolar账号并安装2. 创建隧道&#xff0c;映射3389端口3. Windows远程桌面Ubuntu 四、 配置固定公网地址远程Ubuntu1. 保留固定TCP地址2. 配置固定的TCP地址3. 使用…

48道Linux面试题

本博客将汇总 Linux 面试中常见的题目&#xff0c;并提供详细的解答。 文章目录 1、绝对路径用什么[符号表](https://so.csdn.net/so/search?q符号表&spm1001.2101.3001.7020)示&#xff1f;当前目录、上层目录用什么表示&#xff1f;主目录用什么表示? 切换目录用什么命…

DolphinScheduler实际应用

前言 最近公司新启动了一个项目&#xff0c;然后领导想用一下新技术&#xff0c;并且为公司提供多个大数据调度解决方案&#xff0c;我呢就根据领导要求调研了下当前的开源调度工具&#xff0c;最终决定采用DolphinScheduler&#xff0c; 因此研究了一下DolphinScheduler &…

php安装扩展event 提示 No package ‘openssl‘ found 解决方法

在使用pecl编译安装最新版event模块的时候提示 No package openssl found , 可是本机是安装了openssl的, 编译时找不到, 大概率就是环境配置的问题了, 增加 OPENSSL_CFLAGS OPENSSL_LIBS环境变量即可解决. 异常提示信息: checking for openssl > 1.0.2... no configure: …

阿里云服务器端口PPTP 1723放行教程

阿里云服务器安装PPTP VPN需要先开通1723端口&#xff0c;阿里云服务器端口是在安全组中操作的&#xff0c;阿里云服务器网aliyunfuwuqi.com来详细说明阿里云服务器安全组开放PPTP VPN专用1723端口教程&#xff1a; 阿里云服务器放行1723端口教程 PPTP是点对点隧道协议&#…

C++ 多态向下转型详解

文章目录 1 . 前言2 . 多态3 . 向下转型3.1 子类没有改进父类的方法下&#xff0c;去调用该方法3.2 子类有改进父类的方法下&#xff0c;去调用该方法3.3 子类没有改进父类虚函数的方法下&#xff0c;去调用改方法3.4 子类有改进父类虚函数的方法下&#xff0c;去调用改方法3.5…

接口测试场景:怎么实现登录之后,需要进行昵称修改?

在接口测试中有一个这样的场景&#xff1a;登录之后&#xff0c;需要进行昵称修改&#xff0c;怎么实现&#xff1f; 首先我们分别看下登录、昵称修改的接口说明&#xff1a; 以上业务中补充一点&#xff0c;昵称修改&#xff0c;还需要添加请求头Authorization传登录获取的to…

智慧监控平台/AI智能视频EasyCVR接口调用编辑通道详细步骤

视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;GB28181视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#xff0c…

AI:106-基于卷积神经网络的遥感图像地物分类

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

解决Redis序列化乱码问题

如果我们使用原生的JDK序列化&#xff0c;那么当我们将数据存储到Redis中就会出现乱码的情况 为了解决这个问题我们需要重写RedisTemplate从而解决序列化乱码问题 首先在Maven中引入相应的依赖 <dependency> <groupId>com.fasterxml.jackson.core</group…

面向对象综合训练综合练习(文字版格斗游戏,对象数组,复杂的对象数组操作)

文章目录 练习一&#xff1a;文字版格斗游戏练习二&#xff1a;文字版格斗游戏进阶练习三&#xff1a;对象数组&#xff08;商品&#xff09;练习四&#xff1a;对象数组&#xff08;汽车&#xff09;练习五&#xff1a;对象数组&#xff08;手机&#xff09;练习六&#xff1a…

【Linux】深度解剖环境变量

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟悉并掌握Linux的环境变量。 > 毒鸡汤&#x…

探索 3D 图形处理的奥秘

最近一年多来&#xff0c;在 3Dfx、Intel 们的狂轰滥炸中&#xff0c;在 Quake、古墓丽影们的推波助澜下&#xff0c;三维图形已经成为计算机迷眼中的又一个热点。3D 世界到底是怎样的神奇&#xff0c;我们又是怎样享受它的乐趣呢&#xff1f;就让我们来一探究竟吧。 图形基础…

流媒体学习之路(WebRTC)——GCC分析(4)

流媒体学习之路(WebRTC)——GCC分析&#xff08;4&#xff09; —— 我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost目标&#xff1a;可以让大家熟悉各类Qos能力、带宽估计能力&#xff0c;提供每个环节关键参数调节接口并实现一个json全配置…

视频剪辑方法:掌握视频嵌套合并技术,释放无限创意

随着数字媒体的普及&#xff0c;视频剪辑已是创意表达的重要技巧。通过掌握视频嵌套合并技术&#xff0c;可以将多个视频片段融合在一起&#xff0c;创造出独特的视觉效果和故事叙述。现在一起看云炫AI智剪批量剪辑视频嵌套合并方法&#xff0c;释放无限创意。 准备视频素材&a…

Certum ev多域名证书的优势

多域名证书作为一种能够为多个域名提供安全保护的证书类型&#xff0c;越来越受到企业的青睐。Certum作为一个成立了二十几年的CA认证机构&#xff0c;旗下的EV多域名SSL证书产品已经保护了多家企业的网站。Certum旗下的EV多域名证书作为一种能够为多个域名提供安全保护的证书类…

深度思考,AI项目的人工智能到底引领的是什么?

项目深度思考&#xff0c;人工智能到底引领的是什么&#xff1f; 人工智能引领技术之舞&#xff1a;项目深度思考项目背景&#xff1a;人工智能的魔法时代技术选择的深度思考&#xff1a;AI大决战团队协作的深度思考&#xff1a;AI联盟大会用户体验的深度思考&#xff1a;AI之光…

Redis(二)数据类型

文章目录 官网备注十大数据类型StringListHashSetZSetBitmapHyperLogLog&#xff1a;GEOStreamBitfield 官网 英文&#xff1a;https://redis.io/commands/ 中文&#xff1a;http://www.redis.cn/commands.html 备注 命令不区分大小写&#xff0c;key区分大小写帮助命令help…

DHCP定义

DHCP&#xff08;动态主机配置协议&#xff09;是一个局域网的网络协议。指的是由服务器控制一段IP地址范围&#xff0c;客户机登录服务器时就可以自动获得服务器分配的IP地址和子网掩码。默认情况下&#xff0c;DHCP作为Windows Server的一个服务组件不会被系统自动安装&#…

Android笔记(二十三):Paging3分页加载库结合Compose的实现分层数据源访问

在Android笔记&#xff08;二十二&#xff09;&#xff1a;Paging3分页加载库结合Compose的实现网络单一数据源访问一文中&#xff0c;实现了单一数据源的访问。在实际运行中&#xff0c;往往希望不是单纯地访问网络数据&#xff0c;更希望将访问的网络数据保存到移动终端的SQL…