造一个方形的轮子2--添加配置

造一个方形轮子文章目录:造一个方形的轮子

01、先把车正过来

在上一篇《造一个方形的轮子1--嵌入容器》的最后成功的翻车了,现在先把发现的这个问题解决,想一下如果不想源码暴露出去那么就得改变一下tomcat的web服务项目根目录 ,改成什么好呢?还好有现成的springboot可以借(抄)鉴(袭)。

在springboot里如果我们要添加静态资源有好几个目录可选,可以在resources目录下添加

-resources
    -META-INF.resources
    -public
    -resources
    -static

上边4个目录下的文件在打包的时候都会当作静态资源处理的,省点事,就用一个public吧。在square项目的resource目录下添加一下public文件夹,添加一个默认页面。

index.html

<!DOCTYPE html>
<html lang="en">
<body>
<h1>Whitelabel Error Page</h1><p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p><div>There was an unexpected error (type=Not Found, status=404).</div><div>No message available</div>
</body>
</html>

然后将SquareApplication.run()方法里的启动目录改一下:

 public static void run(Class clzz, String[] args) {
            //.....上略,可以翻看上篇代码
            tomcat = new Tomcat();
            // 设置Tomcat的工作目录:工程根目录/Tomcat
            tomcat.setBaseDir(project_path + "/Tomcat");
            tomcat.setPort(TOMCAT_PORT);
            // 在这里添加上public目录
            tomcat.addWebapp(CONTEXT_PATH, project_path+"/classes/public");
            //.....下略

启动后查看:


2-1.png

ok,问题解决了,解决的相当粗暴,这块下边会再统一改,就不多费话了。

02、解析配置准备

常用的配置文件有两种yamlproperties图省事我就只用yaml

yaml本身就不多说了,java里面支持yaml的工具包挺多的,看了一下Springboot使用的是snakeyaml,妥了,就用这个吧,添加一下yaml解析使用的依赖:

pom.xml

    <properties>
        ...
        <snakeyaml.version>1.9</snakeyaml.version>
    </properties>
    <dependencies>
        ...
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>${snakeyaml.version}</version>
        </dependency>
    </dependencies>

在resources文件夹下添加application.yml文件

application.yml

server:
  port: 8888
  servlet:
    context-path: /abc

03、添加资源加载工具类

这个工具类是利用snakeyaml包将application.yml配置的内容转换为Map类型key为配置的参数key比如server.port

LoadApplicationYmlUtil.java

/**
 * 加载application.yml文件
 * @author ixx
 * @date 2019-06-15
 */
public class LoadApplicationYmlUtil {
    private static final Logger log = LoggerFactory.getLogger(LoadApplicationYmlUtil.class);
    public static Map<String, Object> load(String projectPath){
        Map<String, Object> retMap = new HashMap<>();
        Yaml yaml = new Yaml();
        try {
            Map<String, Object> map = (Map<String, Object>)yaml.load(new FileInputStream(projectPath+"/classes/application.yml"));
            if(map != null && map.size()>0){
                for(Map.Entry e : map.entrySet()) {
                    convert("", retMap, e);
                }
            }
        } catch (FileNotFoundException e) {
            log.error("load application.yml file error.", e);
        }

        return retMap;
    }

    /**
     * 递归组装配置参数
     * @param key 父级key路径(类似server.servlet)
     * @param retMap 要返回的map
     * @param entry
     */
    private static void convert(String key, Map<String, Object> retMap, Map.Entry entry){
        if(entry.getValue() instanceof Map){
            key = key+entry.getKey()+".";
            for(Map.Entry e : ((Map<String, Object>)entry.getValue()).entrySet()){
                convert(key, retMap, e);
            }
        } else {
            key = key+entry.getKey();
            retMap.put(key, entry.getValue());
        }
    }
}

实现主要就是将读出来的内容利用convert递归转换一下

04、初始化配置

在SquareApplication.java里添加loadYaml方法,放个完整代码吧,重点看loadYaml方法:

/**
 * 项目启动类
 * @author ixx
 * @date 2019-6-13
 */
public class SquareApplication {
    private static final Logger log = LoggerFactory.getLogger(SquareApplication.class);
    private static Map<String, Object> CONF_MAP = new HashMap<>();
    private static Tomcat tomcat = null;
    private static String CONTEXT_PATH = "/";
    private static String ENCODING = "UTF-8";
    private static int TOMCAT_PORT = 8080;

    public static void run(Class clzz, String[] args) {
        try {
            long startTime = System.currentTimeMillis();
            String project_path = clzz.getResource("").getPath();
            project_path = project_path.substring(0, project_path.indexOf("classes"));
            // 加载配置
            loadYaml(project_path);
            // 初始化参数
            setArgs(args);
            // 输出banner
            printBanner(project_path);
            tomcat = new Tomcat();
            // 设置Tomcat的工作目录:工程根目录/Tomcat
            tomcat.setBaseDir(project_path + "/Tomcat");
            tomcat.setPort(TOMCAT_PORT);
            tomcat.addWebapp(CONTEXT_PATH, project_path+"/classes/public");
            // 执行这句才能支持JDNI查找
            tomcat.enableNaming();
            tomcat.getConnector().setURIEncoding(ENCODING);
            tomcat.start();
            log.info("Tomcat started on port(s): {} with context path '{}'", TOMCAT_PORT, CONTEXT_PATH);
            log.info("Started Application in {} ms." , (System.currentTimeMillis() - startTime));
            // 保持服务器进程
            tomcat.getServer().await();
        } catch (Exception e) {
            log.error("Application startup failed...", e);
        }
    }

    /**
     * 初始化参数
     * @param args
     */
    private static void setArgs(String[] args){
        Map<String, String> map = ArgsToKVUtil.convert(args);
        if(map.get("--server.port") != null){
            TOMCAT_PORT = Integer.parseInt(map.get("--server.port"));
        }
    }

    /**
     * 加载配置文件
     * @param projectPath
     */
    private static void loadYaml(String projectPath){
        CONF_MAP =  LoadApplicationYmlUtil.load(projectPath);
        if(CONF_MAP.get("server.port") != null){
            TOMCAT_PORT = (Integer)CONF_MAP.get("server.port");
        }
        if(CONF_MAP.get("server.servlet.context-path") != null){
            CONTEXT_PATH = (String)CONF_MAP.get("server.servlet.context-path");
        }
    }

    /**
     * 输出banner图
     */
    private static void printBanner(String projectPath){
        BufferedReader br = null;
        try{
            File f = new File(projectPath + "/classes/default-banner.txt");
            br = new BufferedReader(new FileReader(f));
            StringBuilder stringBuilder = new StringBuilder("\n");
            String line;
            while ((line = br.readLine()) != null){
                stringBuilder.append(line).append("\n");
            }
            log.info(stringBuilder.toString());
        } catch (Exception e){
            log.info("load banner file error!!", e);
            if(br != null){
                try {
                    br.close();
                } catch (IOException e1) {
                }
            }
        }
    }

}

启动T.main()方法测试,启动日志输出:

13:05:38.676 [main] INFO com.jisuye.core.SquareApplication - 
 __________  ____
|   ____   |/ ___|  __ _ _   _  __ _ _ __ ___
|  |    |  |\___ \ / _` | | | |/ _` | '__/ _ \
|  |____|  | ___) | (_| | |_| | (_| | | |  __/
|__________||____/ \__, |\__,_|\__,_|_|  \___|
======================|_|====================
 :: Square ::        (v0.1)

.....
信息: Starting ProtocolHandler ["http-nio-8888"]
13:05:40.912 [main] INFO com.jisuye.core.SquareApplication - Tomcat started on port(s): 8888 with context path '/abc'
13:05:40.914 [main] INFO com.jisuye.core.SquareApplication - Started Application in 2318 ms.

可以看到端口号及context-path已经使用的是application.yml配置文件中的了

05、翻车现场

又到了翻车时间了,到目前为止已经实现的代码好像都还ok,但不要忘记我的目的,我要造的是轮子,一个方形的轮子,轮子怎么能光自己跑呢,轮子是给别人用的,不然别人怎么翻车。

好的,把轮子打个包出来,找个”车“试试吧。

项目根目录下执行mvn clean install 编译完成并推到本地仓库里了,然后我们新建一个maven项目 car

在car项目的pom.xml里添加引用:

    <groupId>com.jisuye</groupId>
    <artifactId>car</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.jisuye</groupId>
            <artifactId>square</artifactId>
            <version>0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

添加resources/application.yml配置文件

server:
  port: 8989
  servlet:
    context-path: /car

添加main/java/com/jisuye/Application.java文件

package com.jisuye;

import com.jisuye.core.SquareApplication;

public class Application {
    public static void main(String args[]){
        SquareApplication.run(Application.class, args);
    }
}

启动main方法,查看日志输出:

13:29:51.529 [main] INFO com.jisuye.core.SquareApplication - load banner file error!!
java.io.FileNotFoundException: C:\Users\admin\ixx\car\target\classes\default-banner.txt (系统找不到指定的文件。)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileReader.<init>(FileReader.java:72)
    at com.jisuye.core.SquareApplication.printBanner(SquareApplication.java:88)
    at com.jisuye.core.SquareApplication.run(SquareApplication.java:36)
    at com.jisuye.Application.main(Application.java:7)
...
java.io.FileNotFoundException: C:\Users\admin\ixx\car\target\classes\public (系统找不到指定的文件。)
    at java.util.zip.ZipFile.open(Native Method)
    at java.util.zip.ZipFile.<init>(ZipFile.java:225)
    at java.util.zip.ZipFile.<init>(ZipFile.java:155)
    at java.util.jar.JarFile.<init>(JarFile.java:166)
    at java.util.jar.JarFile.<init>(JarFile.java:130)
    at org.apache.catalina.startup.Tomcat.getWebappConfigFileFromWar(Tomcat.java:1375)
    at org.apache.catalina.startup.Tomcat.getWebappConfigFile(Tomcat.java:1355)
    at org.apache.catalina.startup.Tomcat.addWebapp(Tomcat.java:718)
    at org.apache.catalina.startup.Tomcat.addWebapp(Tomcat.java:694)
    at org.apache.catalina.startup.Tomcat.addWebapp(Tomcat.java:236)
    at com.jisuye.core.SquareApplication.run(SquareApplication.java:41)
    at com.jisuye.Application.main(Application.java:7)
....
Process finished with exit code 0

这车翻的妥妥的....

下一篇再解决吧....

本篇代码地址: https://github.com/iuv/square

本文作者: ixx
本文链接: http://jianpage.com/2019/06/24/square2/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容