在日常当中对于常规使用 Web 项目都会集成 SpringBoot 工具, 一般来说直接按照以下方式启动就行:
# 启动 Jar 并携带启动配置文件
java -jar package.jar -Dspring.config.location=./application.yml
实际上其他简单和非Web应用并不需要集成这么重量级框架, 所以应该回归到传统附带启动参数的方法,
采用第三方库 JCommander 就能直接编写简单高效的命令行启动工具.
建议: 命令行最好全部采用英语而不要用中文emoji等特殊字符说明, 有的环境会因为缺少字符集乱码(英语最通用所以基本默认集成)
按照官方需要引入第三方库:
<!-- JCommander 第三方库 -->
<dependency>
<groupId>org.jcommander</groupId>
<artifactId>jcommander</artifactId>
<version>2.0</version>
</dependency>
这里推荐还需要设置打包工具, 让其打包的时候指定 main 入口类, 避免启动的时候无法找到入口类:
<!-- Maven打包配置 -->
<build>
<plugins>
<!-- 编译打包配置 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>17</source>
<target>17</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- Jar打包功能配置 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<!-- 这里就是默认启动的入口类文件 com.fusion.game.FusionHttpApplication.java -->
<mainClass>com.fusion.game.FusionHttpApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
这样基本安装配置就引入完成, 之后就是定义命令行工具的参数配置;
首先就是假设我们需要定义 静态Web 服务启动, 而 Web 服务需要以下参数来启动:
-l|--listen: 监听地址, 默认为127.0.0.1-p|--port: 监听端口, 默认为8080-d|--dir: Web服务映射的本地目录, 必须设置该参数-h|--help: 默认展示帮助信息(bool)-v|--version: 默认展示版本信息(bool)
JCommander支持简单的单独参数配置, 但还是推荐采用结构体定义规则之后参数验证单独管理比较好
这就是最基础的静态应用启动参数, 这里定义:
package com.fusion.game;
import com.beust.jcommander.Parameter;
/**
* 自定义的应用参数结构, 这里节约时间没有采用 Set|Get 处理
*/
public class FusionWebArgs {
/**
* 监听地址
*/
@Parameter(names = {"-l", "--listen"}, description = "Listen address")
String listen = "127.0.0.1";
/**
* 监听端口
*/
@Parameter(names = {"-p", "--port"}, description = "Listen port")
Integer port = 8080;
/**
* 映射目录
*/
@Parameter(names = {"-d", "--dir"}, description = "Local directory")
String directory = "";
/**
* 打印帮助内容
*/
@Parameter(names = {"-h", "--help"}, description = "print help info")
boolean help = false;
/**
* 打印版本信息
*/
@Parameter(names = {"-v", "--version"}, description = "print version info")
boolean version = false;
}
之后就是在入口类调用验证器过滤:
package com.fusion.game;
/**
* 应用入口
*/
public class FusionHttpApplication {
/**
* 入口方法
*
* @param args 参数
*/
public static void main(String[] args) {
// 规则生成并且解析
var rule = new FusionWebArgs();
var commander = JCommander
.newBuilder()
.addObject(rule)
.build();
commander.parse(args);
// 验证参数时候正确, help直接跳过
if (rule.help) {
commander.usage();
return; // 直接弹出
}
// 打印版本内容不做后续处理
if (rule.version) {
System.out.println("v1.1.1");
return;
}
// 确认目录有配置
if (rule.directory.isBlank()) {
commander.usage();
return;
}
// 确定目录存在
Path path = Paths.get(rule.directory);
if (!Files.exists(path)) {
System.err.println("Not found directory: " + rule.directory);
return;
}
System.out.printf("创建服务器完成 -> %s:%d <--> %s%n", rule.listen, rule.port, rule.directory);
}
}
不过为了高内聚的情况, 可以把验证放到结构体并弹出 `` 来确认最后验证完成:
// 这里修改参数结构体, 追加验证方法
public class FusionWebArgs {
/**
* 验证参数
*
* @return boolean
* @throws RuntimeException 验证异常
*/
public boolean run(JCommander commander) throws RuntimeException {
// 验证参数时候正确, help直接跳过
if (help) {
commander.usage();
return false;
}
// 打印版本内容不做后续处理
if (version) {
System.out.println("v1.1.1");
return false;
}
// 确认目录有配置
if (directory.isBlank()) {
commander.usage();
return false;
}
// 确定目录存在
Path path = Paths.get(directory);
if (!Files.exists(path)) {
throw new RuntimeException("Not found directory: " + directory);
}
return true;
}
}
之后简单移交给内部就行了:
/**
* 应用入口
*/
public class FusionHttpApplication {
/**
* 入口方法
*
* @param args 参数
*/
public static void main(String[] args) {
// 规则生成并且解析
var rule = new FusionWebArgs();
var commander = JCommander
.newBuilder()
.addObject(rule)
.build();
commander.parse(args);
// 直接移交给内部验证
if (!rule.run(commander)) {
return;
}
System.out.printf("创建服务器完成 -> %s:%d <--> %s%n", rule.listen, rule.port, rule.directory);
}
}
这样编译出命令行 Jar 包, 可以直接调用:
# 模拟传递参数就能调用运行
java -jar package.jar -d /tmp -l 192.168.1.1 -p 80