通过Spring Shell 开发 Java 命令行应用

2019-09-23 09:00:59刘景俊

如果参数的类型是布尔类型 Boolean,在调用的时候不需要给出对应的值。当参数出现时就表示值为 true。

Spring Shell 支持对参数的值使用 Bean Validation API 进行验证。比如我们可以用@Size 来限制字符串的长度,用@Min 和@Max 来限制数值的大小,如代码清单 8 所示。

清单 8. 校验参数

@ShellComponent
public class ParametersValidationApp {
 @ShellMethod("String size")
 public String stringSize(@Size(min = 3, max = 16) String name) {
 return String.format("Your name is %s", name);
 }
 @ShellMethod("Number range")
 public String numberRange(@Min(10) @Max(100) int number) {
 return String.format("The number is %s", number);
 }
}

结果处理

Spring Shell 在运行时,内部有一个处理循环。在每个循环的执行过程中,首先读取用户的输入,然后进行相应的处理,最后再把处理的结果输出。这其中的结果处理是由 org.springframework.shell.ResultHandler 接口来实现的。Spring Shell 中内置提供了对于不同类型结果的处理实现。命令执行的结果可能有很多种:如果用户输入的参数错误,输出的结果应该是相应的提示信息;如果在命令的执行过程中出现了错误,则需要输出相应的错误信息;用户也可能直接退出命令行。Spring Shell 默认使用的处理实现是类 org.springframework.shell.result.IterableResultHandler。IterableResultHandler 负责处理 Iterable 类型的结果对象。对于 Iterable 中包含的每个对象,把实际的处理请求代理给另外一个 ResultHandler 来完成。IterableResultHandler 默认的代理实现是类 org.springframework.shell.result.TypeHierarchyResultHandler。TypeHierarchyResultHandler 其实是一个复合的处理器,它会把对于不同类型结果的 ResultHandler 接口的实现进行注册,然后根据结果的类型来选择相应的处理器实现。如果找不到类型完全匹配的处理器实现,则会沿着结果类型的层次结构树往上查找,直到找到对应的处理器实现。Spring Shell 提供了对于 Object 类型结果的处理实现类 org.springframework.shell.result.DefaultResultHandler,因此所有的结果类型都可以得到处理。DefaultResultHandler 所做的处理只是把 Object 类型转换成 String,然后输出到控制台。

了解了 Spring Shell 对于结果的处理方式之后,我们可以添加自己所需要的特定结果类型的处理实现。代码清单 9 给了一个作为示例的处理结果类 PrefixedResult。PrefixedResult 中包含一个前缀 prefix 和实际的结果 result。

清单 9. 带前缀的处理结果

public class PrefixedResult {
 private final String prefix;
 private final String result;
 public PrefixedResult(String prefix, String result) {
 this.prefix = prefix;
 this.result = result;
 }
 public String getPrefix() {
 return prefix;
 }
 public String getResult() {
 return result;
 }
}