1. wiki
当处理 java 传参问题时,可以简单的将 main
函数的 args[]
直接拿来处理,此时仅能利用传参顺序来处理,更加优雅的方式是使用 apache commons-cli
来获取长短参数来定义和获取参数
2. 引入
使用 maven 来引入此工具包
1 | <properties> |
3. 使用
使用预先定义好参数的规则,对 main
函数的 args[]
解析
1. 创建参数选项
Option
是预定义的参数选项类
1 | // 1. 创建 |
2. 注册参数选项
Options
本质是包含各个选项的数组
1 | Option o = ...; |
3. 格式化
利用预定义好的参数对命令行传参进行格式化,即对 main
函数的 args[]
中参数进行映射
1 | Options options = ...; |
4. 参数使用
1 | CommandLine line = ...; |
4. 实战
使用时一般利用枚举类、者配置文件或数据库表等静态方式,将参数规则定义好,之后将映射的实体类定义好,再对传参进行解析,利用反射,将传参值直接映射为相应实体类,方便后续使用
可以使用枚举类,将预定义好的参数格式封装起来,方便使用和修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public enum EOptParams {
HELP("h", "help", "show optional parameters", false, ""),
SQL("s", "sql", "sql file path", true, ""),
NAME("n", "name", "name of job", true, "jobName"),
;
private String simple;
private String full;
private String desc;
private Boolean hasArg;
private String argName;
EOptParams(String simple, String full, String desc, Boolean hasArg, String argName) {
this.simple = simple;
this.full = full;
this.desc = desc;
this.argName = argName;
this.hasArg = hasArg;
}
// 省略 getter、setter
}注册之
1
2
3
4
5
6Options options = new Options();
Arrays.stream(EOptParams.values()).forEach(p -> {
Option o = Option.builder(p.getSimple()).longOpt(p.getFull()).hasArg(p.getHasArg()).argName(p.getArgName())
.desc(p.getDesc()).build();
options.addOption(o);
});格式化以及帮助信息打印
1
2
3
4
5
6
7
8
9
10
11
12
13CommandLineParser parser = new DefaultParser();
CommandLine line = null;
HelpFormatter formatter = new HelpFormatter();
try {
line = parser.parse(options, args);
if (line.hasOption("h")) {
formatter.printHelp("Job options", options);
}
} catch (ParseException e) {
String message = "Input param is not true,use \"-h\" or \"--help\" to view available parameters.";
throw RuntimeException(e, message);
}
return line;
调用时可以根据预定义好的参数进行传参
1 | java -cp ${CLASS_PATH} ${MAIN_CLASS} -h |
- 使用,利用反射,将传参与实体类绑定,此举主要是避免出现一些魔数或者静态值,可以定义映射规则,将之与实体类绑定,调用时就可以使用 get 方法来使用,只是隐藏了映射规则,其实还是约定大于规则的使用方法
1
2
3
4
5
6// 实体类
public class OptionEntity {
private String name;
private String sql;
// 省略 getter、setter
}
尽量保证实体类字段与传参一致,这样可以简单的利用反射获取值,避免调用时,使用形如 line.getOptionValue("name")
等不优雅的方式
1 | public static OptionEntity getOptionEntity(String[] args) { |
此时调用其来就简单且优雅
1 | OptionEntity ops = getOptionEntity(args); |