使用main方法启动tomcat升级版

在阅读此篇文章需要先阅读在此之前的一篇名叫(使用main方法启动tomcat)的文章作为准备。https://blog.csdn.net/qq_41294444/article/details/103630352

一. 制作一个可用的tomcat启动器并进行一些常用配置quickstart

0. 导入依赖(准备工作)

在上一篇的基础上加入一个自己写的依赖即可。jar包可在https地址:https://github.com/wenliangne/wl.git下找到,或者将报错的有关代码自己实现替换。


        <dependency>
            <groupId>com.wenliang</groupId>
            <artifactId>core</artifactId>
            <version>1.0.8</version>
        </dependency>

1. 创建一个注解名叫Servlet,用于标注自己的servlet。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Servlet {
    String value() default "";
}

2. 创建类ServletConfig用于保存用户自定义的servlet信息。

public class ServletConfig {
    private String pattern;
    private String servletName;
    private String className;

    public ServletConfig(String pattern, String servletName, String className) {
        this.pattern = pattern;
        this.servletName = servletName;
        this.className = className;
    }
    public String getPattern() {
        return pattern;
    }

    public String getServletName() {
        return servletName;
    }

    public String getClassName() {
        return className;
    }
}

3. 创建类ServletScanner用于扫描servlet。

public class ServletScanner {
    private String classPath;
    public List<ServletConfig> scan() {
        List<ServletConfig> servletConfigArrayList = new ArrayList<ServletConfig>();
        Set<Class<?>> servletSet = ClassUtils.getClassWithAnnotation(classPath, Servlet.class);
        if (servletSet == null) {
            return servletConfigArrayList;
        }
        Iterator<Class<?>> iterator = servletSet.iterator();
        while (iterator.hasNext()) {
            Class<?> servletClass = iterator.next();
            Servlet servlet = servletClass.getAnnotation(Servlet.class);
            String servletURL = servlet.value();
            String servletDefaultName = StringUtils.convertFirstCharToLowerCase(servletClass.getSimpleName());
            if ("".equals(servletURL)) {
                servletConfigArrayList.add(new ServletConfig("/" + servletDefaultName, servletDefaultName, servletClass.getName()));
            } else {
                servletConfigArrayList.add(new ServletConfig(servletURL, servletDefaultName, servletClass.getName()));
            }
        }
        return servletConfigArrayList;
    }
    public ServletScanner(String classPath) {
        this.classPath = classPath;
    }
}

4. 创建文件quickStartDefault.properties作为默认配置,内容如下。可创建配置文件application.properties并覆盖默认配置。

tomcat.host=localhost
tomcat.port=8080
tomcat.contextPath=
tomcat.docBase=static
tomcat.reloadable=false
tomcat.welcome=index.html,index.jsp
tomcat.currentJarName=quickstart-1.0.8.jar
tomcat.cacheObjectMaxSize=100
tomcat.allowCasualMultipartParsing = true
tomcat.servletScannerPath=
tomcat.defaultServletClassName = org.apache.catalina.servlets.DefaultServlet
#tomcat.defaultServletClassName = com.wenliang.controller.servlet.DispatcherServlet
tomcat.extensionClassName=
tomcat.listenerClassName=
tomcat.filterClassName=
#tomcat.filterClassName=com.wenliang.security.SecurityFilter:/*多个以逗号分割

5. 创建类TomcatRunner用于启动tomcat。

package com.wenliang.quickstart.tomcat;

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

import com.wenliang.core.io.Resources;
import com.wenliang.core.log.Log;

import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Wrapper;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.deploy.FilterDef;
import org.apache.catalina.deploy.FilterMap;
import org.apache.catalina.startup.Tomcat;

/**
 * @author wenliang
 * @date 2019-12-17
 * 简介:
 */
public class TomcatRunner {
    private static Tomcat tomcat;
    private static StandardContext context;
    private static Properties properties=new Properties();


    static {
        try {
            properties.load(TomcatRunner.class.getClassLoader().getResourceAsStream("quickStartDefault.properties"));

        } catch (IOException e) {
            Log.ERROR("加载文件:quickStartDefault.properties失败!", e);
        }
        try {
            properties.load(TomcatRunner.class.getClassLoader().getResourceAsStream("application.properties"));
        } catch (IOException e) {
            Log.ERROR("加载文件:application.properties失败!", e);
        }
    }

    /**
     * 带上参数启动tomcat
     * @param host 主机名
     * @param port 端口号
     * @param contextPath 虚拟目录
     * @param docBase 静态资源路径
     */
    public static void run(String host,int port,String contextPath,String docBase) {
        if (host != null && !"".equals(host)) {
            getProperties().put("tomcat.host",host);
        }
        if (port != 0) {
            getProperties().put("tomcat.port", port);
        }
        if (contextPath != null && !"".equals(contextPath)&& !"/".equals(contextPath)) {
            getProperties().put("tomcat.contextPath",contextPath);
        }
        if (docBase != null && !"".equals(docBase)) {
            getProperties().put("tomcat.docBase",docBase);
        }
        run();
    }

    /**
     * 启动tomcat
     */
    public static void run() {
        tomcat = new Tomcat();
        // 设置主机名称
        tomcat.setHostname(getProperty("tomcat.host"));
        // 设置端口
        tomcat.setPort(Integer.parseInt(getProperty("tomcat.port")));
        tomcat.setBaseDir(System.getProperty("user.dir"));

        context = new StandardContext();
        // 设置资源路径
        context.setDocBase(getDocBase());
        //设置热部署
        context.setReloadable(Boolean.parseBoolean(getProperty("tomcat.reloadable")));
        // 设置应用路径
        context.setPath(getProperty("tomcat.contextPath"));
        context.addLifecycleListener(new Tomcat.FixContextListener());
        // 设置是否允许表单上传enctype="multipart/form-data"类型的数据
        context.setAllowCasualMultipartParsing(Boolean.parseBoolean(getProperty("tomcat.allowCasualMultipartParsing")));
        // 设置缓存大小
        context.setCacheObjectMaxSize(Integer.parseInt(getProperty("tomcat.cacheObjectMaxSize")));
        // 将context加入tomcat
        tomcat.getHost().addChild(context);
        //添加欢迎页面
        addWelcome(context);
        // 添加监听器
        addListener(context);
        //添加过滤器
        addFilter(context);
        // 执行扩展任务,需要实现TomcatExtension接口,并配置extensionClassName参数
        extension(tomcat,context);
        // 添加处理jsp的servlet
        addJspServlet(context);
        // 添加自定义的servlet
        addCustomServlet(context);
        // 添加处理所有请求的servlet
        addDefaultServlet(context);

        try {
            // 启动tomcat
            tomcat.start();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }
        // 等待请求
        tomcat.getServer().await();
    }

    /**
     * 获取资源路径
     * @return
     */
    public static String getDocBase() {
        String path = TomcatRunner.class.getProtectionDomain().getCodeSource().getLocation().getPath();
        if (!path.contains(getProperty("tomcat.currentJarName"))) {
            path = path.substring(0, path.lastIndexOf("/")) + File.separator;
        } else {
            path = TomcatRunner.class.getClassLoader().getResource("").getPath();
        }
        path = path + getProperty("tomcat.docBase");
        path = path.replace("/", File.separator).replace("\\", File.separator);
        File file = new File(path);
        if (!file.exists()) {
            file.mkdir();
        }
        return path;
    }

    /**
     * 添加欢迎页面
     * @param context
     */
    private static void addWelcome(Context context) {
        String welcomePages = getProperty("tomcat.welcome");
        String[] welcomePagesArr = welcomePages.split(",");
        for (int i = 0; i < welcomePagesArr.length; i++) {
            context.addWelcomeFile(welcomePagesArr[i]);
        }
    }


    /**
     * 添加自定义servlet
     * @param context
     */
    private static void addCustomServlet(Context context) {
        List<ServletConfig> servletConfigList = new ServletScanner(getProperty("tomcat.servletScannerPath")).scan();
        for (int i = 0; i < servletConfigList.size(); i++) {
            ServletConfig servletConfig = servletConfigList.get(i);
            Wrapper servlet = context.createWrapper();
            servlet.setName(servletConfig.getServletName());
            servlet.setServletClass(servletConfig.getClassName());
            servlet.addInitParameter("debug", "0");
            servlet.addInitParameter("listings", "false");
            servlet.setLoadOnStartup(5);
            servlet.setOverridable(true);
            context.addChild(servlet);
            context.addServletMapping(servletConfig.getPattern(), servletConfig.getServletName());
        }
    }

    /**
     * 添加jspServlet
     * @param context
     */
    private static void addJspServlet(Context context) {
        Wrapper jspServlet = context.createWrapper();
        jspServlet.setName("jsp");
        jspServlet.setServletClass("org.apache.jasper.servlet.JspServlet");
        jspServlet.addInitParameter("fork", "false");
        jspServlet.setLoadOnStartup(3);
        context.addChild(jspServlet);
        context.addServletMapping("*.jsp", "jsp");
        context.addServletMapping("*.jspx", "jsp");
    }

    /**
     * 添加默认servlet
     * @param context
     */
    private static void addDefaultServlet(Context context) {
        Wrapper defaultServlet = context.createWrapper();
        defaultServlet.setName("default");
        defaultServlet.setServletClass(getProperty("tomcat.defaultServletClassName"));
        defaultServlet.addInitParameter("debug", "0");
        defaultServlet.addInitParameter("listings", "false");
        defaultServlet.setLoadOnStartup(1);
        defaultServlet.setOverridable(true);
        context.addChild(defaultServlet);
        context.addServletMapping("/", "default");
    }

    /**
     * 添加监听器
     * @param context
     */
    private static void addListener(StandardContext context) {
        String listenerClassName = getProperty("tomcat.listenerClassName");
        if ("".equals(listenerClassName)) {
            return;
        } else {
            String[] listenerClassNameArr = listenerClassName.split(",");
            for (int i = 0; i < listenerClassNameArr.length; i++) {
                if ("".equals(listenerClassNameArr[i])) {
                    continue;
                }
                try {
                    Class<?> applicationListener = Class.forName(listenerClassNameArr[i]);
                    Object o = applicationListener.newInstance();
                    if (ServletContextListener.class.isAssignableFrom(applicationListener)) {
                        context.addApplicationLifecycleListener(o);
                    } else {
                        context.addApplicationEventListener(o);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 添加过滤器
     * @param context
     */
    private static void addFilter(StandardContext context) {
        String filterClassName = getProperty("tomcat.filterClassName");
        if ("".equals(filterClassName)) {
            return;
        } else {
            String[] filterClassNameArr = filterClassName.split(",");
            for (int i = 0; i < filterClassNameArr.length; i++) {
                if ("".equals(filterClassNameArr[i])) {
                    continue;
                }
                try {
                    int index = filterClassNameArr[i].indexOf(':');
                    String className = filterClassNameArr[i].substring(0, index);
                    String path = filterClassNameArr[i].substring(index+1);

                    FilterDef filterDef = new FilterDef();
                    filterDef.setFilterName(className);
                    filterDef.setFilterClass(className);
                    context.addFilterDef(filterDef);

                    FilterMap filterMap = new FilterMap();
                    filterMap.setFilterName(className);
                    filterMap.addURLPattern(path);
                    context.addFilterMap(filterMap);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 提供给用户并支持接口TomcatExtension用于一些扩展设置
     * @param tomcat
     * @param context
     */
    private static void extension(Tomcat tomcat,StandardContext context) {
        String extensionClassName = getProperty("tomcat.extensionClassName");
        if ("".equals(extensionClassName)) {
            return;
        } else {
            Class<?> extensionClass;
            try {
                extensionClass = Class.forName(extensionClassName);
                TomcatExtension o = (TomcatExtension)extensionClass.newInstance();
                o.extension(tomcat,context);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static Properties getProperties() {
        return properties;
    }

    private static String getProperty(String key) {
        return getProperties().getProperty(key);
    }


}

6. 创建接口TomcatExtension用于用户的扩展支持。

可实现此接口对tomcat进行配置,并配置参数tomcat.extensionClassName为全限定类名,也可啥也不做。

public interface TomcatExtension {
    public void extension(Tomcat tomcat, StandardContext context);
}

7. 使用

7.1 创建一个servlet并加上servlet注解,如图:

 

完整代码地址:

ssh地址:git@github.com:wenliangne/wl.git

https地址:https://github.com/wenliangne/wl.git

路径名:wl/wl/quickstart

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值