【仿写tomcat】二、扫描java文件,获取带有@WebServlet注解的类

tomcat仿写

    • 项目结构
    • 扫描文件
    • servlet注解
    • map容器
    • servlet工具类
    • 启动类调用

项目结构

扫描文件之前当然要确定一下项目结构了,我这里的方案是tomcat和项目同级
在这里插入图片描述

项目的话就仿照我们平时使用的结构就好了,我们规定所有的静态资源文件都在webApp目录下存放。

扫描文件

这部分工作我们在仿写spring中已经做过了,我就直接沿用之前的方案了,与之前不同的是我们添加了定位webApp的方法,并且存储在这个工具类里面了,代码如下:

package com.tomcatServer.utils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 扫描工具类
 *
 * @author tomcatProject.ez4sterben
 * @date 2023/08/15
 */
public class ScanUtil {

    public static List<String> javaFiles = new ArrayList<>();
    public static String JAVA = ".java";

    public static String WEB_APP_PATH;

    public static String PROJECT_PATH;


    /**
     * 得到所有java文件
     *
     * @param path 路径
     * @return {@link List}<{@link String}>
     */
    public static List<String> getAllJavaFile(String path){
        getAllFile(new File(path));
        return javaFiles;
    }


    /**
     * 让web应用程序路径
     *
     * @param root 根
     * @return {@link String}
     */
    public static String getWebAppPath(String root){
        File directory = new File(root);
        if (directory.exists() && directory.isDirectory()) {
            findWebAppFolder(directory, "webApp");
        } else {
            System.out.println("Directory does not exist or is not a directory.");
        }
        return PROJECT_PATH;
    }

    /**
     * 找到web应用程序文件夹
     *
     * @param directory        目录
     * @param targetFolderName 目标文件夹名称
     */
    private static void findWebAppFolder(File directory, String targetFolderName) {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory() && file.getName().equals(targetFolderName)) {
                    PROJECT_PATH = file.getParentFile().getAbsolutePath();
                    WEB_APP_PATH = PROJECT_PATH + "\\webApp";
                } else if (file.isDirectory()) {
                    findWebAppFolder(file, targetFolderName);
                }
            }
        }
    }

    /**
     * 获取所有文件
     *
     * @param file 文件
     */
    public static void getAllFile(File file){
        if (file.isFile()){
            if (file.toString().endsWith(JAVA)) {
                String javaPath = getJavaPath(file);
                javaFiles.add(javaPath);
            }
        }
        if (file.exists() && file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File file1 : files) {
                    getAllFile(file1);
                }
            }
        }
    }

    /**
     * 获取java路径
     *
     * @param file 文件
     * @return {@link String}
     */
    private static String getJavaPath(File file) {
        return file.toString().replace("\\",".").split("src.main.java.")[1].replace(".java","");
    }

}


servlet注解

注解这里没什么好说的,自定义一个就行了

package com.tomcatServer.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * web servlet
 *
 * @author tomcatProject.ez4sterben
 * @date 2023/08/15
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface WebServlet {

    String value() default "";
}

map容器

map容器就是存储servlet实例的地方

package com.tomcatServer.servlet;

import java.util.HashMap;
import java.util.Map;

/**
 * map存储
 *
 * @author tomcatProject.ez4sterben
 * @date 2023/08/15
 */
public class MapStore {
    public static Map<String,Class<?>> servletMap = new HashMap<>();
}


servlet工具类

目前工具类主要是两个方法,一个是判断java类是否有webservlet注解,另一个是初始化map容器的,将是servlet的类都丢进去,代码逻辑应该很好懂,不需要多说什么。

package com.tomcatServer.utils;

import com.tomcatServer.annotation.WebServlet;
import com.tomcatServer.servlet.MapStore;

import java.lang.reflect.InvocationTargetException;

/**
 * servlet工具类
 *
 * @author tomcatProject.ez4sterben
 * @date 2023/08/15
 */
public class ServletUtil {

    /**
     * 是web servlet
     *
     * @param className 类名
     * @return {@link Boolean}
     */
    public static Boolean isWebServlet(String className){
        try {
            Class<?> aClass = Class.forName(className);
            WebServlet annotation = aClass.getAnnotation(WebServlet.class);
            if (annotation == null){
                return Boolean.FALSE;
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        return Boolean.TRUE;
    }


    /**
     * 初始化servlet
     *
     * @param className 类名
     */
    public static void initServlet(String className){
        try {
            Class<?> aClass = Class.forName(className);
            String url = aClass.getAnnotation(WebServlet.class).value();
            if (url.startsWith("/")) {
                MapStore.servletMap.put(url,aClass);
            }else {
                MapStore.servletMap.put("/" + url,aClass);
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}

启动类调用

package com.tomcatServer;

import com.tomcatServer.utils.MapUtil;
import com.tomcatServer.utils.ScanUtil;

import java.io.IOException;
import java.util.List;

import static com.tomcatServer.utils.ScanUtil.getWebAppPath;

/**
 * tomcat server启动类
 *
 * @author tomcatProject.ez4sterben
 * @date 2023/08/15
 */
public class Main {

    public static String ROOT;

    public static void main(String[] args) throws IOException {
        // 1.初始化根目录
        ROOT = System.getProperty("user.dir");

        // 2.获取webApp的位置
        String webAppPath = getWebAppPath(ROOT);

        // 3.获取所有带有@WebServlet注解的java文件,初始化servlet
        List<String> allJavaFile = ScanUtil.getAllJavaFile(webAppPath);
        for (String s : allJavaFile) {
            if (MapUtil.isWebServlet(s)) {
                ServletUtil.initServlet(s);
            }
        }
        // 4.处理http请求
        
    }
}

到这里基本工作就做完了,下一篇将会带大家完成对http请求的处理

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis进阶篇 - 04发布订阅、布隆过滤器、过期策略、回收机制、管道...核心知识原理

Redis底层原理篇&#xff0c;​让学习绚丽多彩起来&#xff01;&#xff01;&#xff01;&#xff08;需要原图私信&#xff09;

shell连接ubuntu

当使用aws的私钥连接时,老是弹出输入私钥密码,但是根本没有设置过密码,随便输入后,又提示该私钥无密码... 很早就使用过aws的ubuntu,这个问题也很早就遇到过,但是每次遇到都要各种找找找...索性这次记下来算了 此处用FinalShell连接为例 首先现在Putty连接工具: 点击官方下载 …

【PySide】QtWebEngine网页浏览器打开Flash网页

QWebEngineView 加载 flash插件&#xff0c;可成功显示Flash&#xff0c;如图 说明 QtWebEngine与Chromium版本对应关系 Chromium对Flash的支持 QtWebEngine模块 Qt WebEngine取代了Qt WebKit模块&#xff0c;后者基于WebKit项目&#xff0c;但自Qt 5.2以来没有主动与上游We…

LeetCode算法心得——限制条件下元素之间的最小绝对差(TreeSet)

大家好&#xff0c;我是晴天学长&#xff0c;今天用到了Java一个非常实用的类TreeSet&#xff0c;能解决一些看起来棘手的问题。 1 &#xff09;限制条件下元素之间的最小绝对差 2) .算法思路 初始化变量&#xff1a;n为列表nums的大小。 min为整型最大值&#xff0c;用于记录…

「Python|aiohttp|并发与协程」将HTTP请求提速成百上千倍!一次性掌握把requests请求改成协程的通用方法

本文主要介绍如何通过使用aiohttp库将同步的http请求改成异步方式请求&#xff0c;从而降低等待网络IO过程中时间和计算资源的浪费。 主要包括如何将常见的requests请求改用aiohttp异步执行以及如何将异步的批量请求方法封装成普通方法/同步调用方式&#xff0c;给业务模块调用…

去掉鼠标系列之一: 语雀快捷键使用指南

其实应该是系列之二了&#xff0c;因为前面写了一个关于Interlij IDEA的快捷键了。 为什么要写这个了&#xff0c;主要是觉得一会儿用鼠标&#xff0c;一会儿键盘&#xff0c;一点儿不酷&#xff0c;我希望可以一直用键盘&#xff0c;抛开鼠标。后面陆续记录一下各个软件的快捷…

如何在安卓设备上安装并使用 ONLYOFFICE 文档

您可以使用文档安卓版应用&#xff0c;在移动设备上访问存在您 ONLYOFFICE 帐号中的文件。阅读本文&#xff0c;了解如何操作。 什么是 ONLYOFFICE 文档安卓版 适用于 Android 系统的 ONLYOFFICE 文档是一款全面的办公工具&#xff0c;您可以使用它&#xff0c;查看、创建、编…

【Redis】Redis 的学习教程(五)之 SpringBoot 集成 Redis

在前几篇文章中&#xff0c;我们详细介绍了 Redis 的一些功能特性以及主流的 java 客户端 api 使用方法。 在当前流行的微服务以及分布式集群环境下&#xff0c;Redis 的使用场景可以说非常的广泛&#xff0c;能解决集群环境下系统中遇到的不少技术问题&#xff0c;在此列举几…

uniapp 小兔鲜儿 - 首页模块(1)

目录 自定义导航栏 静态结构 安全区域​ 通用轮播组件 静态结构 自动导入全局组件 全局组件类型声明 .d.ts文件 注册组件 vue/runtime-core 首页 – 轮播图指示点 首页 – 获取轮播图数据 首页 – 轮播图数据类型并渲染 首页 – 轮播图总结 首页分类 首页 – 前…

第九章 动态规划part11(代码随想录)

123.买卖股票的最佳时机III 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再次购买前出售掉之前的股票&…

RabbitMq-1基础概念

RabbitMq-----分布式中的一种通信手段 1. MQ的基本概念&#xff08;message queue,消息队列&#xff09; mq:消息队列&#xff0c;存储消息的中间件 分布式系统通信的两种方式&#xff1a;直接远程调用&#xff0c;借助第三方完成间接通信 消息的发送方是生产者&#xff0c…

部署piwigo网页 通过cpolar分享本地电脑上的图片

通过cpolar分享本地电脑上有趣的照片&#xff1a;发布piwigo网页 文章目录 通过cpolar分享本地电脑上有趣的照片&#xff1a;发布piwigo网页前言1. 设定一条内网穿透数据隧道2. 与piwigo网站绑定3. 在创建隧道界面填写关键信息4. 隧道创建完成 总结 前言 首先在本地电脑上部署…

linux下的lld命令

Linux下的lld命令的主要作用&#xff1a;用来查看程式运行所需的共享库&#xff08;动态链接库&#xff09;,常用来解决程式因缺少某个库文件而不能运行的一些问题。 1、首先ldd不是一个可执行程序&#xff0c;而只是一个shell脚本 2、ldd 的使用 lld 可执行程序或者动态库…

MyBatis动态SQL:打造灵活可变的数据库操作

目录 if标签trim标签where标签set标签foreach标签 动态SQL就是根据不同的条件或需求动态地生成查询语句&#xff0c;比如动态搜索条件、动态表或列名、动态排序等。 if标签 在我们填写一些信息时&#xff0c;有些信息是必填字段&#xff0c;有的则是非必填的&#xff0c;这些…

SpringBoot-lombok

为什么要使用lombok? Lombok是一个通过注解以达到减少代码的Java库,如通过注解的方式减少getter,setter方法,构造方法等。通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法&#xff0c;并可以自动化生成日志变量&#xff0c;简化java开发、提高…

c++--SLT六大组件之间的关系

1.SLT六大组件&#xff1a; 容器&#xff0c;迭代器&#xff0c;算法&#xff0c;仿函数&#xff0c;适配器&#xff0c;空间配置器 2.六大组件之间的关系 容器&#xff1a;容器是STL最基础的组件&#xff0c;没有容器&#xff0c;就没有数据&#xff0c;容器的作用就是用来存…

UI设计师个人工作总结范文精选

UI设计师个人工作总结范文(一) 在忙忙碌碌中&#xff0c;2019年又将过去了&#xff0c;在这一年当中&#xff0c;设计部无论是在运作模式、设计产值、还是人员结构&#xff0c;各方面的变化都比较大。 设计部的运作模式是从7月底开始进行调整的&#xff0c;以独立承包制的运营方…

Python学习笔记_基础篇(十一)_socket编程

python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和软件组成的。硬件中的CPU是计算机的核心&#xff0c;它承担计算机的所有任务。 操作系统是运行在硬件之上的软件&#xff0c;是计算机的管理者&#xff0c;它负责资源的管理和分配、任务的调度。 程序是运行…

应用在汽车前照灯系统中的环境光传感芯片

为了保证行车照明的安全性和方便性&#xff0c;减轻驾驶员的劳动强度。近年来&#xff0c;出现了许多新的照明控制系统&#xff0c;例如用于日间驾驶的自动照明系统、光束调节系统、延迟控制等。尤其是汽车自适应前照灯系统&#xff0c;它是一种能够自动改变两种以上的光型以适…

分类预测 | MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测

分类预测 | MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测 目录 分类预测 | MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现WOA-CNN-BiLSTM-Attention数据分类预测&#xff0c;运行环境Matlab2023b及以上…