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

tomcat仿写

项目结构

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

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

扫描文件

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

java 复制代码
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注解

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

java 复制代码
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实例的地方

java 复制代码
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的类都丢进去,代码逻辑应该很好懂,不需要多说什么。

java 复制代码
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);
        }
    }
}

启动类调用

java 复制代码
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请求的处理

【仿写tomcat】三、通过socket读取http请求信息

相关推荐
wm104319 分钟前
java web springboot
java·spring boot·后端
smile-yan20 分钟前
Provides transitive vulnerable dependency maven 提示依赖存在漏洞问题的解决方法
java·maven
老马啸西风21 分钟前
NLP 中文拼写检测纠正论文-01-介绍了SIGHAN 2015 包括任务描述,数据准备, 绩效指标和评估结果
java
Earnest~24 分钟前
Maven极简安装&配置-241223
java·maven
皮蛋很白27 分钟前
Maven 环境变量 MAVEN_HOME 和 M2_HOME 区别以及 IDEA 修改 Maven repository 路径全局
java·maven·intellij-idea
青年有志29 分钟前
JavaWeb(一) | 基本概念(web服务器、Tomcat、HTTP、Maven)、Servlet 简介
java·web
上海研博数据33 分钟前
flink+kafka实现流数据处理学习
java
KpLn_HJL35 分钟前
leetcode - 2139. Minimum Moves to Reach Target Score
java·数据结构·leetcode
小扳2 小时前
微服务篇-深入了解 MinIO 文件服务器(你还在使用阿里云 0SS 对象存储图片服务?教你使用 MinIO 文件服务器:实现从部署到具体使用)
java·服务器·分布式·微服务·云原生·架构
龙少95432 小时前
【深入理解@EnableCaching】
java·后端·spring