【仿写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请求信息

相关推荐
BillKu28 分钟前
Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的方法
java·tomcat·mybatis
全栈凯哥29 分钟前
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
java·算法·leetcode·链表
chxii30 分钟前
12.7Swing控件6 JList
java
全栈凯哥31 分钟前
Java详解LeetCode 热题 100(27):LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)详解
java·算法·leetcode·链表
YuTaoShao32 分钟前
Java八股文——集合「List篇」
java·开发语言·list
PypYCCcccCc37 分钟前
支付系统架构图
java·网络·金融·系统架构
华科云商xiao徐1 小时前
Java HttpClient实现简单网络爬虫
java·爬虫
扎瓦1 小时前
ThreadLocal 线程变量
java·后端
BillKu1 小时前
Java后端检查空条件查询
java·开发语言
jackson凌2 小时前
【Java学习笔记】String类(重点)
java·笔记·学习