首页 > 其他分享 >嵌入式 Tomcat 使用

嵌入式 Tomcat 使用

时间:2023-04-02 23:33:52浏览次数:58  
标签:websocket Tomcat tomcat 使用 嵌入式 org apache import

目录

参考资料

1 简介

从Tomcat5.0开始提供和支持Embeded版本,即最简化Tomcat Server。Tomcat和Embedded Tomcat版本是同步发布的。

2 下载嵌入式 Tomcat

嵌入式 tomcat 具体表现是一组 jar包,可通过官方下载或者 Maven 仓库下载。

3 代码示例

3.1 实现 Servelt 和 Websocket

3.1.1 建立 maven 工程并引入jar包

<!-- 引入 嵌入式 tomcat 相关jar包-->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-core</artifactId>
      <version>9.0.68</version>
    </dependency>

    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-websocket</artifactId>
      <version>9.0.68</version>
    </dependency>

    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-el</artifactId>
      <version>9.0.68</version>
    </dependency>

    <!-- 由于没有 jsp 页面,jsp 解析功能由web容器提供 -->
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <version>9.0.24</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-logging-log4j</artifactId>
      <version>7.0.47</version>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-annotations-api</artifactId>
      <version>9.0.31</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.jdt</groupId>
      <artifactId>ecj</artifactId>
      <version>3.18.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-util</artifactId>
      <version>8.5.45</version>
    </dependency>

3.1.2 类说明

  1. 依次创建以下及各类

    • TomcatWebContanerBootstrap: 应用入口和调起嵌入式 tomcat,并配置 servelt
    • WelcomeServlet : Servlet 服务类
    • AnnotationEchoIMServer : 使用 @ServerEndpoint 声明 websocket 端点
    • EchoIMServerFilter : 过滤 websocket 端点类
  2. 类结构:

TomcatWebContanerBootstrap 
  |
  |--  servlet
  |     |-- WelcomeServlet
  |
  |-- im
  |     |-- AnnotationEchoIMServer
  |     |-- EchoIMServerFilter

如下图:
image

3.1.3 WelcomeServlet

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * Welcome Servlet
 */
public class WelcomeServlet extends HttpServlet {

    /**
     * 欢迎语句
     */
    private static String HELLO_WORLD = "Hello World , My Frind!";

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 响应码 200
        resp.setStatus(200);
        // 返回 “Hello World , My Frind!”
        try(ServletOutputStream out = resp.getOutputStream();){
            out.write(HELLO_WORLD.getBytes(StandardCharsets.UTF_8));
            out.flush();
        }
    }
}

3.1.4 AnnotationEchoIMServer

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

/**
 * Tomcat Websocket 代码示例 - 基于注解驱动实现服务端
 * 主要功能:消息处理器,处理客户端发送过来的消息
 */
@ServerEndpoint("/im/echo/{uid}")
public class AnnotationEchoIMServer {
    @OnOpen
    public void open(@PathParam("uid") String uid, Session session, EndpointConfig endpointConfig){
        // TODO
    }

    @OnMessage
    public void message(String wholeMessage, @PathParam("uid") String pathParam, Session session){
        try {
            String respMessage = "Server received message : " + wholeMessage;
            session.getBasicRemote().sendText(respMessage);
        }catch (Exception ex){

        }
    }

    @OnClose
    public void close(Session session, CloseReason closeReason, @PathParam("uid") String pathParam){
        // TODO
    }

    @OnError
    public void error(Throwable ex, Session session, @PathParam("uid") String pathParam){
        // TODO
    }

}

3.1.5 EchoIMServerFilter

import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
import java.util.Set;

/**
 * Tomcat Websocket 代码示例 - 过滤 websocket endpoint
 */
public class EchoIMServerFilter implements ServerApplicationConfig {

    /**
     * 过滤继承 Endpoint 类实现 websocket的类中能够作为 websocket Endpoint 的类。
     * @param endpointClasses Endpoint接口的所有子类
     * @return
     */
    @Override
    public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses) {
        // TODO
        return null;
    }

    /**
     * 过滤扫描到 @ServerEndpoint 标注的类中能够作为 websocket Endpoint 的类。
     * @param scanned 应用中 @ServerEndpoint 标注的类
     * @return
     */
    @Override
    public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
        if(scanned.contains(AnnotationEchoIMServer.class)){
            return scanned;
        }
        return null;
    }
}

3.1.6 创建程序启动入口 TomcatWebContanerBootstrap

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Wrapper;
import org.apache.catalina.servlets.DefaultServlet;
import org.apache.catalina.startup.ContextConfig;
import org.apache.catalina.startup.Tomcat;
import study.lihw.demo.webcontainer.tomcat.servlet.WelcomeServlet;

import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 嵌入式 tomcat web 容器代码示例
 */
public class TomcatWebContanerBootstrap {

    private static Logger logger = Logger.getLogger(TomcatWebContanerBootstrap.class.getName());

    // main()应用启动入口
    public static void main(String[] args) throws LifecycleException, URISyntaxException {
        // 1. 实例化 Tomcat 示例( tomcat 最小启动,Tomcat 类用于嵌入了 tomcat 的应用)
        Tomcat tomcat = new Tomcat();
        // 2. 配置应用上下文
        configContext(tomcat);
        // 2. 配置 Servlet
        configServlet(tomcat);
        // 3. 启动 tomcat 服务
        tomcat.start();
        logAfterStart(tomcat);
        // 4. 同步等待关闭窗口命令关闭
        tomcat.getServer().await();

    }

    /**
     * 配置 context
     * @param tomcat
     */
    private static Context configContext(Tomcat tomcat) throws URISyntaxException {
        // 添加应用上下文配置,并制定 webapp 目录为:/G:/***/embedded-web-container/target/classes/
        String docPath = TomcatWebContanerBootstrap.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
        Context appContext =  tomcat.addContext("/", docPath);
        // 必须添加 ContextConfig ,否则 SPI 无法加载 WsSci
        appContext.addLifecycleListener(new ContextConfig());
    }

    private static void configServlet(Tomcat server){
        /*
          1. 在应用上下文 "/" 下添加默认 Servlet,映射 url: /
          注意:必须配置 DefaultServlet, webcoket 的 url 依赖。
         */
        Wrapper defaultServletWrapper = server.addServlet("/", "default", DefaultServlet.class.getTypeName());
        defaultServletWrapper.addMapping("/");
        // 2. 在应用上下文 "/" 下配置 Welcome Servlet,映射 url: /index
        Wrapper welcomeServletwrapper = server.addServlet("/", "hello", WelcomeServlet.class.getTypeName());
        welcomeServletwrapper.addMapping("/index");

    }

    /**
     * 启动日志
     * @param tomcat
     */
    private static void logAfterStart(Tomcat tomcat){
        int port = tomcat.getConnector().getPort();
        logger.log(Level.INFO," Embed Tomcat Server listen on port : "+ port);
        logger.log(Level.INFO," Embed Tomcat Server Start success.");
    }
}

3.1.7 验证

1.启动

四月 02, 2023 11:20:45 下午 org.apache.catalina.core.StandardContext setPath
警告: A context path must either be an empty string or start with a '/' and do not end with a '/'. The path [/] does not meet these criteria and has been changed to []
四月 02, 2023 11:20:47 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service [Tomcat]
四月 02, 2023 11:20:47 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet engine: [Apache Tomcat/9.0.68]
四月 02, 2023 11:20:49 下午 org.apache.catalina.startup.ContextConfig getDefaultWebXmlFragment
信息: No global web.xml found
四月 02, 2023 11:21:04 下午 org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
警告: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [456] milliseconds.
四月 02, 2023 11:21:04 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["http-nio-8080"]
四月 02, 2023 11:21:04 下午 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler ["http-nio-8080"]
四月 02, 2023 11:21:05 下午 study.lihw.demo.webcontainer.tomcat.TomcatWebContanerBootstrap logAfterStart
信息:  Embed Tomcat Server listen on port : 8080
四月 02, 2023 11:21:05 下午 study.lihw.demo.webcontainer.tomcat.TomcatWebContanerBootstrap logAfterStart
信息:  Embed Tomcat Server Start success.


  1. 访问 http://localhost:8080/index
    image

  2. postman 连接 localhost:8080/im/echo/black
    image
    测试完成

标签:websocket,Tomcat,tomcat,使用,嵌入式,org,apache,import
From: https://www.cnblogs.com/lihw-study/p/17281721.html

相关文章

  • 专业开发人员使用低代码是什么体验?
     相关数据显示,74%的公司计划将低代码此业务线集成到应用程序开发生命周期中,显而易见,公司正在采用低代码技术来缓解应用程序开发需求的压力。现在你的老板告诉你低代码开发是一种新方式,你需要向你的团队宣布这个消息。您现有的一些开发人员可能对低代码持怀疑态度,他们会说“低代码......
  • Git 的使用
    Git的使用1.提交:gitcommit-m"NewFile"2.新建分支:gitbranchnewImage切换到新的分支上:gitcheckout<name>;提交:gitcommit新建分支并切换到新分支:gitcheckout-b<name>3.分支与合并:gitmerge(bugFix合并到main:在main指点上命令gitmergebugFix)(main合并到bugFi......
  • stm32------使用keil和标准外设库进行stm32工程模板创建
    keil软件版本:V5.35.00st官网:STM32固件-意法半导体STMicroelectronics单片机型号:STM32F103VET6配置步骤大致为:新建本地文件夹--->新建工程--->添加本地文件到相应工程--->打开魔术棒进行配置--->添加main文件step1:新建本地工程文件夹(这里取名为template,因后续想要做为模板使......
  • GCC使用#pragma开启O3优化
    #pragmaGCCoptimize(3,"Ofast","inline")ViewCode ......
  • Django使用数据库
    一、数据库配置使用前要设置时区TIME_ZONE,TIME_ZONE='UTC'还要注意setting.py配置文件头部的INSTALLED_APPS选项(已安装程序)。确认自建的pollsapp应用已经安装到总项目容器中了。就是添加一句话:‘pollsapp.apps.PollsappConfig’,其中pollsapp是你创建应用的名字,apps表示应......
  • 使用vue实现方法、计算属性、侦听器完成的简易计算器
    第一步:创建一个新的web项目(Jisuanqi),引入js文件第二步:搭好基本框架,为后面写代码打好基础(这里更改一个小错误:把class="app"改为id="app") 第三步:编写输入框效果图展示如下: 第四步:添加“计算”按钮第五步:编写实例化 结果显示: 最后完整代码展示1<!DOCTYPEh......
  • mybatis plus的简单使用
    mybatisplus作用就是可以少些sql,实现对数据一系列操作的功能首先查询所有数据根据指定的时间查询根据时间范围查询,时间倒序  其中QueryWrapper叫做条件构造器sql表结构,直接放到sql工具执行就好/*SQLyogUltimatev10.00Beta1MySQL-5.7.22-log:Database-y......
  • 关于Date使用不当的bug
    关于Date使用不当的bug1、背景用户调用接口,传入一个参数分钟,表示想要查询距离现在多少分钟的记录。有的时候会查不到记录。2、排查过程大致代码。获取当前的时间的date对象now,通过now的时间戳计算前beforeMinute的时间戳,转换成date对象查询executeTime>=before&&exec......
  • 04_靶机Kioptrix1.2:CMS漏洞利用,使用ht编辑器修改sudoers文件提权,mysql查询
    思路:发现主机后进行目录扫描,发现登录口标注了CMS的版本,查看该类型CMS有没有漏洞,针对漏洞去github搜索脚本,拿到脚本后运行得到靶机的初级Shell,根据靶机内的文件内容指示使用ht编辑器,利用编辑器去修改用户的权限然后提权,拿到root权限结束基操代码不再粘贴首先进行目标靶机地址的......
  • 快速使用ChatGpt Web Server
    快速使用ChatGptWebServerChatGptWebServer是使用BlazorServer模式部署的一个服务,所有的逻辑和代码执行都会在服务器执行,然后通过SignalR传输到前端渲染。通过这样模式,我们部署ChatGptWebServer只需要新加坡服务器,不需要在搭建Gateway做中间层转发,并且ChatGptWebServer......