用Spring Boot创建CLI应用
因为我觉得我已经开始看到一种可以写得很整洁的方法,所以我打算总结一下。
环境
-
- Java 1.8.0_91
-
- Maven 3.3.9 (Maven wrapper)
-
- Spring Boot 1.4.3.RELEASE
- Apache Commons CLI 1.3.1
$ ./mvnw -version
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T01:41:47+09:00)
Maven home: /Users/yo1000/.m2/wrapper/dists/apache-maven-3.3.9-bin/2609u9g41na2l7ogackmif6fj2/apache-maven-3.3.9
Java version: 1.8.0_91, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.11.5", arch: "x86_64", family: "mac"
使用的东西 de
-
- Spring Boot
- Apache Commons CLI
摘录依存关系的部分。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<commons-cli.version>1.3.1</commons-cli.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>${commons-cli.version}</version>
</dependency>
</dependencies>
要做的事
-
- オプション付きパラメタの受け取り
-
- オプション無しパラメタの受け取り
-
- オプションに対するヘルプの表示
-
- パイプされた標準入力の受け取り
- エラーハンドリング
配置成可作为CLI应用启动的形式。
在Spring Boot中,当创建CLI应用程序时的基础知识。创建一个实现org.springframework.boot.CommandLineRunner接口的组件。
如果创建这样一个类,当从终端启动应用程序时,将调用run方法。
@Component
public class DemoCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) {
// 以下 ここに処理を実装していく
}
}
处理参数
由于使用了Apache Commons CLI,处理命令行参数非常简单。可以执行以下操作。
Options options = new Options();
options.addOption("?", "help", false, "Print this message.");
options.addOption("o", "output", true, "Output directory.");
// void run(String... args) throws Exception {..}
CommandLine cl = new DefaultParser().parse(options, args);
if (cl.hasOption("o")) {..}
String output = cl.getOptionValue("o");
// どちらもパラメタの内容自体は同じ
String[] params = cl.getArgs();
List<String> paramList = cl.getArgList();
if (cl.hasOption("?")) {
new HelpFormatter().printHelp("demo [-o <arg>]", options)
}
如上所述,参数可以非常简单地处理。
处理标准输入
如果是CLI应用程序,可以从标准输入接收值,并且可以通过管道连接进行处理,这样感觉很聪明,但是在这里不能使用Apache Commons CLI进行处理。使用System.in,可以处理标准输入,如下所示。
// パイプされた標準入力を受け取ると、対話式 CLI に使用する System.console() は null を返す
if (System.console() == null) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
String stdin = reader.lines().collect(Collectors.joining());
} catch (IOException e) {
..
}
}
只要了解了处理已经传输的标准输入的方法,处理起来并不复杂。
错误处理
因为我使用了 Spring,所以通过 AOP 来集中处理异常并将其输出到标准错误流非常简单方便。
@Aspect
@Component
public class ExceptionHandlerAdvice {
@Around("execution(* org.springframework.boot.CommandLineRunner+.run(..))")
public void handleException(ProceedingJoinPoint joinPoint) {
try {
joinPoint.proceed()
} catch (Exception e) {
System.err.println(e.getMessage())
}
}
}
其他
由于使用Spring Boot,在作为CLI应用程序时,我们会抑制横幅显示和框架日志输出等内容。
通过将以下文件放置在src/resources/下,可以抑制CLI应用程序中不需要的日志输出。
spring:
main:
banner-mode: log
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<root level="ERROR">
<appender-ref ref="CONSOLE_APPENDER"/>
</root>
</configuration>
如何启动
最后,让我们确认一下创建的 CLI 应用程序的启动方法。
如果尚未创建可执行的JAR文件,我们将直接从Maven启动。在这种情况下,参数传递的方式有一点不同。
$ java -jar cli.jar -o oParam nonOptionParam
$ ./mvnw spring-boot:run -Drun.arguments=-o,oParam,nonOptionParam
我认为通过以上的内容,我们已经基本了解了使用Spring Boot创建CLI应用程序时需要考虑的方面。
我已经创建了一个包含这些内容的 CLI 应用程序,你可以参考一下(虽然是 Kotlin 项目)。
链接:https://github.com/yo1000/pdf2img