jbase编译与部署的优化

news2024/10/7 10:14:59

上一篇的演示只是涉及自动编译业务脚本。演示时候工程编译是超级慢的。因为把静态资源放在了Web工程下,每次编译都要拷贝,运行起码是1分钟,不能忍受,为此思考工程结构改解决这个问题,顺带方便开发的发布。运行WebLoader能达到5秒内把网站启动,同时打开辅助的页面打开器。

老的结构是这样子的,为了编译运行时候借助tomcat一起发布静态资源,就把静态资源放Web工程,导致的问题就是每次编译都要拷贝静态资源,超级慢,同时还要配idea的Tomcat设置
在这里插入图片描述
调整工程结构,把WebUI拆成WebBase和WebLoader两部分,WebBase只包含网站的servlet基础,剔除静态资源和业务脚本,WebLoader是一个控制台,负载加载Web,同时放静态资源和Java业务脚本
在这里插入图片描述

简化后的WebBase,平时不编译,涉及到调用和主体变动才编译得到WEB-INF拷贝到WebLoader
在这里插入图片描述
WebLoader是控制台程序复杂驱动Tomcat的停止和启动脚本,同时启动实现的页面打开器,他里面加上静态资源也Java业务脚本,既能让.java享受语法检查,又不用编译拷贝,同时发布时候只要拷贝WebSrc即可
在这里插入图片描述
加载器逻辑

package WebLoader;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.*;
import java.nio.file.Paths;
import java.util.Scanner;

//网站加载器,引导加载网站
public class Main {

    //加载入口
    public static void main(String[] args) {
        System.out.println("本控制台将负责引导启动网站");
        try
        {
            File directory = new File("");// 参数为空
            String courseFile = directory.getCanonicalPath();
            System.out.println(courseFile);
            String binPath= Paths.get(courseFile,"WebSrc","bin").toString();
            String stopBatPath= Paths.get(courseFile,"WebSrc","bin","shutdown.bat").toString();
            String startBatPath= Paths.get(courseFile,"WebSrc","bin","startup.bat").toString();
            //结束打开页面工具
            KillProcess("DevOpenPage.exe");
            System.out.println("尝试停止站点");
            System.out.println("执行脚本:"+stopBatPath);
            TryExecCmd(stopBatPath,binPath);

            //启动页面打开工具
            String openPageUtil= Paths.get(courseFile,"WebSrc","webapps","ankilis","DevOpenPage","DevOpenPage.exe").toString();
            StartExe(openPageUtil,binPath);
            System.out.println("尝试启动站点");
            System.out.println("执行脚本:"+startBatPath);
            TryExecCmd(startBatPath,binPath);
        }
        catch (Exception ex)
        {
            System.out.println(ex.getMessage());
        }

    }

    //结束指定名称进程
    //processName:进程名
    public static void KillProcess(String processName) {
        try {
            String line;
            Process p = Runtime.getRuntime().exec(System.getenv("windir") + "\\system32\\" + "tasklist.exe");
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
            while ((line = input.readLine()) != null) {
                if (line.contains(processName)) {
                    String processId = line.split("\\s+")[1];
                    Runtime.getRuntime().exec("taskkill /F /PID " + processId);
                    System.out.println("Process " + processName + " has been killed.");
                }
            }
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //启动Exe
    //cmdStr:命令串
    //runDir:运行路径
    private static void StartExe(String cmdStr,String runDir)
    {
        File directory = new File(runDir);
        try
        {
            System.out.println("启动:"+cmdStr);
            // 创建进程并执行命令
            Process process = Runtime.getRuntime().exec(cmdStr,null,directory);
        }
        catch (Exception ex)
        {
            System.out.println(ex.getMessage());
        }
    }


    //执行cmd
    //cmdStr:命令串
    //runDir:运行路径
    private static void TryExecCmd(String cmdStr,String runDir)
    {
        File directory = new File(runDir);
        try
        {
            System.out.println("执行:"+cmdStr);
            // 创建进程并执行命令
            Process process = Runtime.getRuntime().exec(cmdStr,null,directory);
            // 获取命令行程序的输出结果
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            // 等待命令行程序执行完毕
            int exitCode=process.waitFor();
            // 关闭资源
            reader.close();
            System.out.println("返回:"+exitCode);
        }
        catch (Exception ex)
        {
            System.out.println(ex.getMessage());
        }
    }
}

WebSrc内嵌的是一个Tomcat
在这里插入图片描述

静态资源和业务脚本在这里
在这里插入图片描述

同时为了内嵌Tomcat改造了他的startup.bat和shutdown.bat
startup.bat

@echo off
rem Licensed to the Apache Software Foundation (ASF) under one or more
rem contributor license agreements.  See the NOTICE file distributed with
rem this work for additional information regarding copyright ownership.
rem The ASF licenses this file to You under the Apache License, Version 2.0
rem (the "License"); you may not use this file except in compliance with
rem the License.  You may obtain a copy of the License at
rem
rem     http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing, software
rem distributed under the License is distributed on an "AS IS" BASIS,
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rem See the License for the specific language governing permissions and
rem limitations under the License.

rem ---------------------------------------------------------------------------
rem Start script for the CATALINA Server
rem ---------------------------------------------------------------------------

setlocal

cd ..
set "CATALINA_HOME=%cd%"

rem Guess CATALINA_HOME if not defined
set "CURRENT_DIR=%cd%"
if not "%CATALINA_HOME%" == "" goto gotHome
set "CATALINA_HOME=%CURRENT_DIR%"
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
cd ..
set "CATALINA_HOME=%cd%"
cd "%CURRENT_DIR%"
:gotHome
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome

set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"

rem Check that target executable exists
if exist "%EXECUTABLE%" goto okExec
echo Cannot find "%EXECUTABLE%"
echo This file is needed to run this program
goto end
:okExec

rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs

call "%EXECUTABLE%" start %CMD_LINE_ARGS%

:end

shutdown.bat

@echo off
rem Licensed to the Apache Software Foundation (ASF) under one or more
rem contributor license agreements.  See the NOTICE file distributed with
rem this work for additional information regarding copyright ownership.
rem The ASF licenses this file to You under the Apache License, Version 2.0
rem (the "License"); you may not use this file except in compliance with
rem the License.  You may obtain a copy of the License at
rem
rem     http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing, software
rem distributed under the License is distributed on an "AS IS" BASIS,
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rem See the License for the specific language governing permissions and
rem limitations under the License.

rem ---------------------------------------------------------------------------
rem Stop script for the CATALINA Server
rem ---------------------------------------------------------------------------

setlocal

cd ..
set "CATALINA_HOME=%cd%"

rem Guess CATALINA_HOME if not defined
set "CURRENT_DIR=%cd%"
if not "%CATALINA_HOME%" == "" goto gotHome
set "CATALINA_HOME=%CURRENT_DIR%"
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
cd ..
set "CATALINA_HOME=%cd%"
cd "%CURRENT_DIR%"
:gotHome
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome

set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"

rem Check that target executable exists
if exist "%EXECUTABLE%" goto okExec
echo Cannot find "%EXECUTABLE%"
echo This file is needed to run this program
goto end
:okExec

rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs

call "%EXECUTABLE%" stop %CMD_LINE_ARGS%

:end

用C#实现页面打开器方便开发打开页面

在这里插入图片描述

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DevOpenPage
{
    public partial class FrmMian : Form
    {
        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="str"></param>
        private delegate void WriteLog(string str);

        /// <summary>
        /// java文件集合
        /// </summary>
        private List<Dto> list = new List<Dto>();

        /// <summary>
        /// 静态文件路径
        /// </summary>
        string StaticFilesPath = "";

        public FrmMian()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 加载函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            DirectoryInfo di = new DirectoryInfo(Application.StartupPath);
            StaticFilesPath = di.Parent.FullName;
            LoadTree();
            WriteLogToUI("本程序路径:" + Path.Combine(AppContext.BaseDirectory, "DevOpenPage.exe"));
            Task.Run(() =>
            {
                System.Threading.Thread.Sleep(7000);
                ChomeViewUtil.OpenChrome("http://localhost:8080/ankilis/login/form/Login.aspx");
            });
            

        }

        /// <summary>
        /// 加载数
        /// </summary>
        private void LoadTree()
        {
            treeViewMian.Nodes.Clear();
            list.Clear();
            TreeNode root = new TreeNode();
            root.Text = @"ankilis";
            root.Tag = StaticFilesPath;
            treeViewMian.Nodes.Add(root);
            BindChild(root);
            root.Expand();
        }


        /// <summary>
        /// 回调
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            //总是接受  
            return true;
        }

        /// <summary>
        /// 绑定子节点
        /// </summary>
        /// <param name="fNode"></param>
        private bool BindChild(TreeNode fNode)
        {
            string path = fNode.Tag.ToString();
            //父目录
            DirectoryInfo fDir = new DirectoryInfo(path);
            FileSystemInfo[] finfos = fDir.GetFileSystemInfos();
            bool HasFile = false;
            foreach (FileSystemInfo f in finfos)
            {
                if (fDir.GetType() != f.GetType())
                {
                    if(txtFilter.Text!=""&&(!f.Name.ToLower().Contains(txtFilter.Text.ToLower())))
                    {
                        continue;
                    }
                }
               TreeNode node = new TreeNode();
                node.Text = f.Name;
                node.Tag = f.FullName;
                if(f.Extension==".java")
                {
                    Dto dto = new Dto();
                    dto.FullName = f.FullName.Replace(".java",".ashx");
                    dto.LastTime = f.LastWriteTime;
                    list.Add(dto);
                }
                if (f.Extension == ".aspx"|| f.Extension == ".html" || f.Extension == ".java")
                {
                    node.ForeColor = Color.Blue;
                }
                //是文件夹时才递归调用自己
                if (fDir.GetType() == f.GetType()) 
                {
                    bool ChildHasFile=BindChild(node);
                    if(ChildHasFile==true)
                    {
                        HasFile = true;
                        fNode.Nodes.Add(node);
                    }
                }
                else
                {
                    HasFile = true;
                    fNode.Nodes.Add(node);
                }
            }
            return HasFile;
        }

        /// <summary>
        /// 双击打开
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeViewMian_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            string fullPath = e.Node.Tag.ToString();
            if (fullPath.Contains(".aspx")|| e.Node.Tag.ToString().Contains(".html") || e.Node.Tag.ToString().Contains(".java"))
            {
                ChomeViewUtil.OpenChrome("http://localhost:8080/"+e.Node.FullPath.Replace(".java", ".ashx"));
                WriteLogToUI("打开" + "http://localhost:8080/" + e.Node.FullPath.Replace(".java", ".ashx"));
            }
            else
            {
                if(File.Exists(fullPath))
                {
                    Process process = new Process();
                    process.StartInfo.FileName = "cmd.exe";
                    process.StartInfo.UseShellExecute = false;
                    process.StartInfo.RedirectStandardInput = false;
                    process.StartInfo.RedirectStandardOutput = false;
                    process.StartInfo.RedirectStandardError = false;
                    process.StartInfo.CreateNoWindow = true;
                    process.StartInfo.Arguments = @"/c " + fullPath;
                    process.Start();
                    WriteLogToUI("打开" + fullPath);
                }
            }
        }

        /// <summary>
        /// 刷新树
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            list.Clear();
            LoadTree();
            WriteLogToUI("刷新目录成功");
        }

        /// <summary>
        /// 写日志到界面
        /// </summary>
        /// <param name="str"></param>
        private void WriteLogToUI(string str)
        {
            WriteLog txthandler = new WriteLog(SetLogTxt);
            txtLog.Invoke(txthandler, new object[] { str });
        }

        /// <summary>
        /// 设置日志控件文本
        /// </summary>
        /// <param name="str"></param>
        private void SetLogTxt(string str)
        {
            txtLog.Text += DateTime.Now.ToString("hh:mm:ss# ")+str + "\n";
        }



        /// <summary>
        /// 实体
        /// </summary>
        public class Dto
        {
            /// <summary>
            /// 全名
            /// </summary>
            public string FullName
            {
                get;
                set;
            }

            /// <summary>
            /// 最后修改时间
            /// </summary>
            public DateTime LastTime
            {
                get;
                set;
            }
        }

        /// <summary>
        /// 模糊查询
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtFilter_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode==Keys.Enter)
            {
                LoadTree();
            }
        }
    }
}


谷歌打开工具

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace DevOpenPage
{
    /// <summary>
    /// 用谷歌打开url工具
    /// </summary>
    public static class ChomeViewUtil
    {
        /// <summary>
        /// 谷歌打开url
        /// </summary>
        /// <param name="path">url</param>
        /// <param name="isApp">是否app模式</param>
        public static void OpenChrome(string path, bool isApp = false)
        {
            string chromePath = "";
            bool IsChrome = TryGetSoftwarePath("chrome", out chromePath);
            if (IsChrome && chromePath.Length > 0)
            {
                Console.WriteLine("驱动Chrome打开登录链接");
                if (isApp == true)
                {
                    System.Diagnostics.Process.Start(chromePath, "--app=" + path);
                }
                else
                {
                    System.Diagnostics.Process.Start(chromePath, path);
                }
            }
            else
            {
                Console.WriteLine("没安装Chrome,驱动默认浏览器打开登录链接");
                //调用系统默认的浏览器 
                System.Diagnostics.Process.Start(path);
            }
        }

        /// <summary>
        /// 获取某个安装文件的执行路径
        /// </summary>
        /// <param name="softName">软件名</param>
        /// <param name="path">路径</param>
        /// <returns></returns>
        public static bool TryGetSoftwarePath(string softName, out string path)
        {
            string strPathResult = string.Empty;
            string strKeyName = "";    
            object objResult = null;

            Microsoft.Win32.RegistryValueKind regValueKind;
            Microsoft.Win32.RegistryKey regKey = null;
            Microsoft.Win32.RegistryKey regSubKey = null;

            try
            {
                //Read the key 
                regKey = Microsoft.Win32.Registry.LocalMachine;
                regSubKey = regKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + softName.ToString() + ".exe", false);
                //如果在LocalMachine获取不到,可以在CurrentUser里获取
                if (regSubKey == null)
                {
                    regKey = Microsoft.Win32.Registry.CurrentUser;
                    regSubKey = regKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + softName.ToString() + ".exe", false);
                }
                if(regSubKey==null)
                {
                    path = "";
                    return false;
                }
                //Read the path 
                objResult = regSubKey.GetValue(strKeyName);
                regValueKind = regSubKey.GetValueKind(strKeyName);

                //Set the path 
                if (regValueKind == Microsoft.Win32.RegistryValueKind.String)
                {
                    strPathResult = objResult.ToString();
                }
            }
            catch (System.Security.SecurityException ex)
            {
                path = "";
                System.Windows.Forms.MessageBox.Show("你没有读取注册表的权限! "+ex.Message);
            }
            catch (Exception ex)
            {
                path = "";
                System.Windows.Forms.MessageBox.Show("读取注册表错误! " + ex.Message);
            }
            finally
            {

                if (regKey != null)
                {
                    regKey.Close();
                    regKey = null;
                }

                if (regSubKey != null)
                {
                    regSubKey.Close();
                    regSubKey = null;
                }
            }

            if (strPathResult != string.Empty)
            {
                path = strPathResult;
                return true;
            }
            else
            {
                path = "";
                return false;
            }
        }
    }
}

Linux部署
先安装jdk

[root@localhost ~]# yum install  java-1.8.0-openjdk* -y

然后打开8080端口和查看jdk版本

[root@localhost ~]# firewall-cmd --zone=public --add-port=8080/tcp --permanent
success
[root@localhost ~]# firewall-cmd --reload
success
[root@localhost ~]# java --version
Unrecognized option: --version
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
[root@localhost ~]# java -version
openjdk version "1.8.0_382"
OpenJDK Runtime Environment (build 1.8.0_382-b05)
OpenJDK 64-Bit Server VM (build 25.382-b05, mixed mode)

然后尝试启动测试网站,这里要给startup.sh、catalina.sh、shutdown.sh执行权限,给WebSrc目录权限,否则javac无法编译,别的没什么主意的。

在这里插入图片描述

[root@localhost ~]# bash /WebSrc/bin/startup.sh
Cannot find /WebSrc/bin/catalina.sh
The file is absent or does not have execute permission
This file is needed to run this program
[root@localhost ~]# chmod +x /WebSrc/bin/startup.sh
[root@localhost ~]# bash /WebSrc/bin/startup.sh
Cannot find /WebSrc/bin/catalina.sh
The file is absent or does not have execute permission
This file is needed to run this program
[root@localhost ~]# chmod +x /WebSrc/bin/catalina.sh
[root@localhost ~]# bash /WebSrc/bin/startup.sh
Using CATALINA_BASE:   /WebSrc
Using CATALINA_HOME:   /WebSrc
Using CATALINA_TMPDIR: /WebSrc/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /WebSrc/bin/bootstrap.jar:/WebSrc/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
[root@localhost ~]# bash /WebSrc/bin/shutdown.sh
Using CATALINA_BASE:   /WebSrc
Using CATALINA_HOME:   /WebSrc
Using CATALINA_TMPDIR: /WebSrc/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /WebSrc/bin/bootstrap.jar:/WebSrc/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
[root@localhost ~]# bash /WebSrc/bin/shutdown.sh
Using CATALINA_BASE:   /WebSrc
Using CATALINA_HOME:   /WebSrc
Using CATALINA_TMPDIR: /WebSrc/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /WebSrc/bin/bootstrap.jar:/WebSrc/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Nov 06, 2023 9:02:45 PM org.apache.catalina.startup.Catalina stopServer
SEVERE: Could not contact [localhost:8005] (base port [8005] and offset [0]). Tomcat may not be running.
Nov 06, 2023 9:02:45 PM org.apache.catalina.startup.Catalina stopServer
SEVERE: Error stopping Catalina
java.net.ConnectException: Connection refused (Connection refused)
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:607)
	at java.net.Socket.connect(Socket.java:556)
	at java.net.Socket.<init>(Socket.java:452)
	at java.net.Socket.<init>(Socket.java:229)
	at org.apache.catalina.startup.Catalina.stopServer(Catalina.java:667)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.catalina.startup.Bootstrap.stopServer(Bootstrap.java:393)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:483)

[root@localhost ~]# bash /WebSrc/bin/startup.sh
Using CATALINA_BASE:   /WebSrc
Using CATALINA_HOME:   /WebSrc
Using CATALINA_TMPDIR: /WebSrc/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /WebSrc/bin/bootstrap.jar:/WebSrc/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# bash /WebSrc/bin/shutdown.sh
Using CATALINA_BASE:   /WebSrc
Using CATALINA_HOME:   /WebSrc
Using CATALINA_TMPDIR: /WebSrc/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /WebSrc/bin/bootstrap.jar:/WebSrc/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
[root@localhost ~]# bash /WebSrc/bin/startup.sh
Using CATALINA_BASE:   /WebSrc
Using CATALINA_HOME:   /WebSrc
Using CATALINA_TMPDIR: /WebSrc/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /WebSrc/bin/bootstrap.jar:/WebSrc/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
[root@localhost ~]# bash /WebSrc/bin/shutdown.sh
Using CATALINA_BASE:   /WebSrc
Using CATALINA_HOME:   /WebSrc
Using CATALINA_TMPDIR: /WebSrc/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /WebSrc/bin/bootstrap.jar:/WebSrc/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
[root@localhost ~]# bash /WebSrc/bin/startup.sh
Using CATALINA_BASE:   /WebSrc
Using CATALINA_HOME:   /WebSrc
Using CATALINA_TMPDIR: /WebSrc/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /WebSrc/bin/bootstrap.jar:/WebSrc/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
[root@localhost ~]# chmod -R +777 /WebSrc
[root@localhost ~]# bash /WebSrc/bin/shutdown.sh
Using CATALINA_BASE:   /WebSrc
Using CATALINA_HOME:   /WebSrc
Using CATALINA_TMPDIR: /WebSrc/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /WebSrc/bin/bootstrap.jar:/WebSrc/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
[root@localhost ~]# bash /WebSrc/bin/startup.sh
Using CATALINA_BASE:   /WebSrc
Using CATALINA_HOME:   /WebSrc
Using CATALINA_TMPDIR: /WebSrc/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /WebSrc/bin/bootstrap.jar:/WebSrc/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.

部署只要上传WebSrc文件夹到Linux或者直接运行Windows下的WebSrc/bin的启动脚本(前提是安装jdk)。Linux上设置文件夹权限和启动停止脚本权限,非常简单。

CentOS7上发布效果
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

改业务代码测试
在这里插入图片描述

在这里插入图片描述

轻松加愉快,开发和Linux发布都很简单,不依赖Maven、不用配开发idea的tomcat,不用niginx代理前后台。前后台做到分而不离。下一阶段实现代码生成器和通用码表,通用码表可以解决百分之80左右的基础维护界面。生效的百分之二十的维护界面借助代码生成器生成的代码解决这里面的百分之80工作量,从而极大降低基础维护的开发量,等于剩下约百分之四。

通用码表原理

代码生成器原理

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录第四十四天 | 动态规划 完全背包:纯完全背包理论基础(卡码网第52题);应用(注意遍历顺序):组合(518),排列(377)

1、动态规划&#xff1a;完全背包理论基础 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大…

详解基于Android的Appium+Python自动化脚本编写

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

排序算法之-选择

算法原理 在未排序的数列中找出最大&#xff08;或最小&#xff09;的元素&#xff0c;然后将其存入到已排序的数列起始位置&#xff0c;紧接着在剩余的未排序数列中继续查找最大&#xff08;或最小&#xff09;的元素&#xff0c;并将其放入到已排序的数列末尾&#xff0c;依…

数据结构:Map和Set(1)

搜索树 概念 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 它的左右子树也分别为二叉搜索树 这棵树的中序遍历结果是有序的 接下来我们来模拟一棵二叉搜索树&#xff0c…

串口通信(3)-接收一组固定长度的数据

本文为博主 日月同辉&#xff0c;与我共生&#xff0c;csdn原创首发。希望看完后能对你有所帮助&#xff0c;不足之处请指正&#xff01;一起交流学习&#xff0c;共同进步&#xff01; > 发布人&#xff1a;日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

Godot4实现游戏的多语言版本

要在Godot 4中实现多语言版本的游戏&#xff0c;您需要按照以下几个步骤来设置和管理游戏文本以及可能的其他资源&#xff0c;如图像或声音。以下是根据官方文档和详细教程整理的简明指南&#xff1a; 准备翻译文件&#xff1a; Godot支持使用.csv文件或.po文件进行国际化​​…

C语言习题整理①

一些C语言习题的整理。 目录 一、判断质数 二、判断回文数 三、判断水仙花数 四、输出乘法表 五、输出杨辉三角 一、判断质数 质数是指在大于1的自然数中&#xff0c;除了1和它本身以外不再有其他因数的自然数。质数又称素数。一个大于1的自然数&#xff0c;除了1和它自身…

数据结构与算法C语言版学习笔记(2)-线性表、顺序存储结构的线性表

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 数据结构部分的知识框架一、线性表的定义和特点1.定义2.特点 二、线性表的实际案例引入1.案例一&#xff1a;多项式的加减乘除2.案例二&#xff1a;当多项式是稀疏多…

AI 女友突然下线,大叔集体「崩溃」;谷歌聊天机器人称谷歌滥用垄断力量丨 RTE 开发者日报 Vol.78

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

微服务项目,请求从发出到后端处理器的历程

点击登录按钮,发出 http://localhost:8803/service_6001/admin/login/in请求,这是一个由nginx配置的前端项目 查看配置文件,该条请求会被映射形成对http://localhost:51603/admin/login/in的post请求 upstream heima-admin-gateway {server localhost:51603; } server {liste…

笔记50:正则表达式入门宝典

引自&#xff1a;正则表达式是什么? - 知乎 中“龙吟九野”所写的一个回答&#xff0c;个人感觉看完之后如同醍醐灌顶&#xff0c;查了很多资料都没有这篇文章写的基础和通透&#xff0c;感觉是正则表达式扫盲好文&#xff0c;所以搬运一下&#xff0c;侵权删&#xff0c;感谢…

吃透BGP,永远绕不开这些基础概述,看完再也不怕BGP了!

你们好&#xff0c;我的网工朋友。 总有人在私信里抱怨&#xff0c;BGP实在是太难了&#xff01; 一是这玩意儿本来就很复杂&#xff0c;需要处理大量的路由信息和复杂的算法&#xff1b;再一个是需要你有一定的实战经验才能深入理解运作。 虽然BGP确实有一定难度&#xff0c…

简简单单入门Makefile

笔记来源&#xff1a;于仕琪教授&#xff1a;Makefile 20分钟入门&#xff0c;简简单单&#xff0c;展示如何使用Makefile管理和编译C代码 操作环境 MacosVscode 前提准备 新建文件夹 mkdir learn_makefile新建三个cpp文件和一个头文件 // mian.cpp #include <iostrea…

fio数据整理之二

fio数据简单抓取 上文我们完成了一些fio output数据的简单抓取&#xff0c;本文将针对抓取的数据做进一步的处理&#xff0c;输出到表格之中&#xff0c;方便我们查看&#xff0c;统计结果。 本文先使用最简单的方法创建csv档案 我们现有个基本认知&#xff0c;在csv档案中&am…

通过you-get命令行工具下载B站等常见网站高清视频

参考&#xff1a; you-get&#xff1a;https://github.com/soimort/you-get EditThisCookie 源码&#xff1a;https://github.com/ETCExtensions/Edit-This-Cookie EditThisCookie 官网&#xff1a;https://www.editthiscookie.com/ you-get 是一个非常好用的命令行版视频下载工…

[wp]NewStarCTF 2023 WEEK5|WEB

前言:比赛是结束了&#xff0c;但我的学习还未结束&#xff0c;看看自己能复习几道题吧&#xff0c;第四周实在太难 Final 考点&#xff1a; ThinkPHP 5.0.23 RCE一句话木马上传SUID提权&#xff08;find&#xff09; 解题: 首先页面就给了ThinkPHP V5&#xff0c; 那无非考…

java制作游戏,如何使用libgdx,入门级别教学

第一步&#xff0c;进入libgdx的官网。点击get started 进入这个页面&#xff0c;点击setup a project 进入这个页面直接点击&#xff0c;Generate a project. 点击下载&#xff0c;下载创建工具 它会让你下载一个jar包&#xff0c;有java环境的人可以双击直接打开。 把android…

Linux学习之vim跳转到特定行数

参考的博客&#xff1a;《Vim跳到最后一行的方法》 《oeasy教您玩转vim - 14 - # 行头行尾》 《Linux&#xff1a;vim 中跳到首行和最后一行》 想要跳到特定行的话&#xff0c;可以在命令模式和正常模式进行跳转。要是对于vim的四种模式不太熟的话&#xff0c;可以到博客《Linu…

Arrays.asList() 和 List.of() 的列表之争

1. 概述 有时在Java中&#xff0c;为了方便&#xff0c;我们需要创建一个小列表或将数组转换为列表。Java 为此提供了一些辅助方法。 在本文中&#xff0c;我们将比较初始化小型临时数组的两种主要方法&#xff1a;List.of()和 Array.asList()。 2. Arrays.asList() Java 自…

跨境电商商城源码,助力商家全球布局(多语言切换\多货币转换\多商户入驻)

今天&#xff0c;我们要给大家介绍一款强大且多元化的跨境电商解决方案——WoShop跨境电商源码!这款源码拥有许多令人惊叹的功能&#xff0c;其中最引人注目的就是支持多语言切换、多货币转换以及多商户入驻! 设想一下&#xff0c;你是一个跨境电商的卖家&#xff0c;你的业务遍…