位置: 编程技术 - 正文

通过Spring Shell 开发 Java 命令行应用(通过扣缴义务人申报和综合所得年度自行申报)

编辑:rootadmin

推荐整理分享通过Spring Shell 开发 Java 命令行应用(通过扣缴义务人申报和综合所得年度自行申报),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:通过身份证怎么能查出个人所有信息,通过架设伪基地能对周围的手机通信进行窃听和截获,通过手机号查对方身份证信息,通过扣缴义务人申报和综合所得年度自行申报,通过车牌号定位车位置,通过车牌号定位车位置,通过车牌号定位车位置,通过手机号怎么查对方的位置,内容如对您有帮助,希望把文章链接给更多的朋友!

提到 Java,大家都会想到 Java 在服务器端应用开发中的使用。实际上,Java 在命令行应用的开发中也有一席之地。在很多情况下,相对于图形用户界面来说,命令行界面响应速度快,所占用的系统资源少。在与用户进行交互的场景比较单一时,命令行界面是更好的选择。命令行界面有其固定的交互模式。通常是由用户输入一系列的参数,在执行之后把相应的结果在控制台输出。命令行应用通常需要处理输入参数的传递和验证、输出结果的格式化等任务。Spring Shell 可以帮助简化这些常见的任务,让开发人员专注于实现应用的业务逻辑。本文对 Spring Shell 进行详细的介绍。

Spring Shell 入门

最简单的创建 Spring Shell 应用的方式是使用 Spring Boot。从 Spring Initializr 网站( Apache Maven 的 Spring Boot 应用,然后添加 Spring Shell 相关的依赖即可。本文介绍的是 Spring Shell 2.0.0.M2 版本,目前还只是 Milestone 版本,因此需要在 pom.xml 中添加 Spring 提供的包含 Milestone 版本工件的 Maven 仓库,如代码清单 1 所示。否则的话,Maven 会无法找到相应的工件。

清单 1. 添加 Spring Shell 的 Maven 仓库

在添加了 Spring Shell 的 Maven 仓库之后,可以在 Spring Boot 项目中添加对于spring-shell-starter 的依赖,如代码清单 2 所示。

清单 2. 添加 Spring Shell 所需 Maven 依赖

我们接着可以创建第一个基于 Spring Shell 的命令行应用。该应用根据输入的参数来输出相应的问候语,完整的代码如清单 3 所示。从代码清单 3 中可以看到,在 Spring Shell 的帮助下,完整的实现代码非常简单。代码的核心是两个注解:@ShellComponent 声明类GreetingApp 是一个 Spring Shell 的组件;@ShellMethod 表示方法 sayHi 是可以在命令行运行的命令。该方法的参数 name 是命令行的输入参数,而其返回值是命令行执行的结果。

清单 3. 输出问候语的命令行应用

接下来我们运行该应用。运行起来之后,该应用直接进入命令行提示界面,我们可以输入 help 来输出使用帮助。help 是 Spring Shell 提供的众多内置命令之一,在列出的命令中,可以看到我们创建的 say-hi 命令。我们输入"say-hi Alex"来运行该命令,可以看到输出的结果"Hi Alex"。如果我们直接输入"say-hi",会看到输出的错误信息,告诉我们参数"--name"是必须的。从上面的例子可以看出,在 Spring Shell 的帮助下,创建一个命令行应用是非常简单的。很多实用功能都已经默认提供了。在使用 Spring Initializr 创建的 Spring Boot 项目中,默认提供了一个单元测试用例。这个默认的单元测试用例与 Spring Shell 在使用时存在冲突。在进行代码清单 3 中的项目的 Maven 构建时,该测试用例需要被禁用,否则构建过程会卡住。

参数传递与校验

下面我们讨论 Spring Shell 中的参数传递和校验。Spring Shell 支持两种不同类型的参数,分别是命名参数和位置参数。命名参数有名称,可以通过类似--arg 的方式来指定;位置参数则按照其在方法的参数列表中的出现位置来进行匹配。命名参数和位置参数可以混合起来使用,不过命名参数的优先级更高,会首先匹配命名参数。每个参数都有默认的名称,与方法中的对应的参数名称一致。

在代码清单 4 中的方法有 3 个参数 a、b 和 c。在调用该命令时,可以使用"echo1 --a 1 --b 2 --c 3",也可以使用"echo1 --a 1 2 3"或"echo1 1 3 --b 2"。其效果都是分别把 1,2 和 3 赋值给 a、b 和 c。

清单 4. 包含多个参数的命令方法

如果不希望使用方法的参数名称作为命令对应参数的名称,可以通过@ShellOption 来标注所要使用的一个或多个参数名称。我们可以通过指定多个参数名称来提供不同的别名。在代码清单 5 中,为参数 b 指定了一个名称 boy。可以通过"echo2 1 --boy 2 3"来调用。

清单 5. 指定参数名称

对于命名参数,默认使用的是"--"作为前缀,可以通过@ShellMethod 的属性 prefix 来设置不同的前缀。方法对应的命令的名称默认是从方法名称自动得到的,可以通过属性 key 来设置不同的名称,属性 value 表示的是命令的描述信息。如果参数是可选的,可以通过@ShellOption 的属性 defaultValue 来设置默认值。在代码清单 6 中,我们为方法 withDefault 指定了一个命令名称 default,同时为参数 value 指定了默认值"Hello"。如果直接运行命令"default",输出的结果是"Value: Hello";如果运行命令"default ",则输出的结果是"Value: "。

清单 6. 指定方法名称和参数默认值

一个参数可以对应多个值。通过@ShellOption 属性 arity 可以指定一个参数所对应的值的数量。这些参数会被添加到一个数组中,可以在方法中访问。在代码清单 7 中,方法 echo3 的参数 numbers 的 arity 值是 3,因此可以映射 3 个参数。在运行命令"echo3 1 2 3"时,输出的结果是"a = 1, b =2, c = 3"。

清单 7. 参数对应多个值

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

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

清单 8. 校验参数

结果处理

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. 带前缀的处理结果

在代码清单 中,我们为 PrefixedResult 添加了具体的处理器实现。该实现也非常简单,只是把结果按照某个格式进行输出。

清单 . PrefixedResult 对应的处理器实现

在代码清单 中,命令方法 resultHandler 返回的是一个 PrefixedResult 对象,因此会被代码清单 中的处理器来进行处理,输出相应的结果。

清单 . 使用 PrefixedResult 的命令

代码清单 给出了具体的命令运行结果。

通过Spring Shell 开发 Java 命令行应用(通过扣缴义务人申报和综合所得年度自行申报)

清单 . 命令的处理结果

自定义提示符

在启动命令行应用时,会发现该应用使用的是默认提示符"shell:>"。该提示符是可以定制的,只需要提供接口 org.springframework.shell.jline.PromptProvider 的实现即可。接口 PromptProvider 中只有一个方法,用来返回类型为 org.jline.utils.AttributedString 的提示符。在代码清单 中,我们定义了一个 PromptProvider 接口的实现类,并使用"myshell=>"作为提示符,而且颜色为蓝色。

清单 . 自定义提示符

动态命令可用性

前面所创建的命令都是一直可用的。只要应用启动起来,就可以使用这些命令。不过有些命令的可用性可能取决于应用的内部状态,只有内部状态满足时,才可以使用这些命令。对于这些命令,Spring Shell 提供了类 org.springframework.shell.Availability 来表示命令的可用性。通过类 Availability 的静态方法 available()和 unavailable()来分别创建表示命令可用和不可用的 Availability 对象。

在代码清单 中,我们创建了两个命令方法 runOnce()和 runAgain()。变量 run 作为内部状态。在运行 runOnce()之后,变量 run 的值变为 true。命令 runAgain 的可用性由方法 runAgainAvailability()来确定。该方法根据变量 run 的值来决定 runAgain 是否可用。按照命名惯例,检查命令可用性的方法的名称是在命令方法名称之后加上 Availability 后缀。如果需要使用不同的方法名称,或是由一个检查方法控制多个方法,可以在检查方法上添加注解@ShellMethodAvailability 来声明其控制的方法名称。

清单 . 动态命令可用性

输入参数转换

之前的@ShellMethod 标注的方法使用的都是简单类型的参数。Spring Shell 通过 Spring 框架的类型转换系统来进行参数类型的转换。Spring 框架已经内置提供了对常用类型的转换逻辑,包括原始类型、String 类型、数组类型、集合类型、Java 8 的 Optional 类型、以及日期和时间类型等。我们可以通过 Spring 框架提供的扩展机制来添加自定义的转换实现。

代码清单 中的 User 类是作为示例的一个领域对象,包含了 id 和 name 两个属性。

清单 . User

代码清单 中的 UserService 用来根据 id 来查找对应的 User 对象。作为示例,UserService 只是简单使用一个 HashMap 来保存作为测试的 User 对象。

清单 . UserService

在代码清单 中,UserConverter 实现了 Spring 中的 Converter 接口并添加了从 String 到 User 对象的转换逻辑,即通过 UserService 来进行查找。

清单 . 使用类型转换

在代码清单 中,命令方法 user 的参数是 User 类型。当运行命令"user alex"时,输入参数 alex 会通过代码清单 中的类型转换服务转换成对应的 User 对象,然后输出 User 对象的属性值 name。如果找不到与输入参数值对应的 User 对象,则输出"User not found"。

清单 . 使用类型转换的命令

命令组织方式

当创建很多个命令时,需要有一种把这些命令组织起来。Spring Shell 提供了不同的方式来对命令进行分组。处于同一分组的命令会在 help 命令输出的帮助中出现在一起。默认情况下,同一个类中的命令会被添加到同一分组中。默认的分组名称根据对应的 Java 类名来自动生成。除了默认分组之外,还可以显式的设置分组。可以使用@ShellMethod 注解的属性 group 来指定分组名称;还可以为包含命令的类添加注解@ShellCommandGroup,则该类中的所有命令都在由@ShellCommandGroup 指定的分组中;还可以把@ShellCommandGroup 注解添加到包声明中,则该包中的所有命令都在由@ShellCommandGroup 指定的分组中。

在代码清单 中,通过@ShellCommandGroup 为命令所在类添加了自定义的分组名称 Special。其中的方法 command2 则通过@ShellMethod 的 group 属性指定了不同的分组名称"Basic Group"。

清单 . 组织命令

图 1 显示了示例应用的 help 命令的输出结果,从中可以看到命令的分组情况。

图 1. 所有的命令列表

commands.png

内置命令

Spring Shell 提供了很多内置的命令,如下所示。

运行 help 命令可以列出来应用中的所有命令和对应的描述信息。运行 clear 命令可以进行清屏操作。运行 exit 命令可以退出命令行应用。运行 script 命令可以执行一个文件中包含的所有命令。如果不需要某个内置命令,可以通过把上下文环境中的属性 spring.shell.command.<command>.enabled 的值设为 false 来禁用。如果希望禁用全部的内置命令,可以把 spring-shell-standard-commands 从 Maven 依赖中排除,如代码清单 所示。

清单 . 排除内置命令对应的 Maven 依赖

小结

命令行应用以其简单易用,占有资源少,速度快的特点,仍然在 Java 应用开发中占据一席之地。Spring Shell 为开发命令行应用提供了坚实的基础,可以极大的提高开发效率。本文对 Spring Shell 进行了详细的介绍,从基础的入门,到参数的传递和校验,再到结果处理、自定义提示符、动态命令可用性、输入参数转换、命令组织和内置命令等。在阅读本文之后,读者可以了解如何使用 Spring Shell 开发命令行应用。

以上所述是小编给大家介绍的通过Spring Shell 开发 Java 命令行应用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对积木网网站的支持!

shell中的source命令的巧妙用法 首先,通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。例如,当我们修改了/etc/profile文件,并想让它立刻生效,而不

Git Tag 标签详解 GitTag标签gittag按字母排序显示标签gittagv1.打上v1.这个标签gitshowv1.显示这个标签的详情可以同时打多个tag指向同一个时间点上的版本gitpushorigin--tags推

linux虚拟机上安装配置redis3.0.7 我们给大家列出详细的图文步骤教给大家在linux虚拟机上安装redis以及相关的配置流程。将redis-3.0.7.tar.gz上传到linux虚拟机上编译:a)因为redis是C语言开发,

标签: 通过扣缴义务人申报和综合所得年度自行申报

本文链接地址:https://www.jiuchutong.com/biancheng/368670.html 转载请保留说明!

上一篇:shell编程跨服务器备份文件(linux跨服务器调用shell脚本)

下一篇:shell中的source命令的巧妙用法(shell source不起作用)

  • 红字冲回账务处理
  • 企业之间交换房屋 契税
  • 个税两种申报方式哪种好
  • 买的矿泉水可以烧开吗
  • 人力资源公司代招的岗位可以去吗
  • 发票专用章章号是什么
  • 车险 专票
  • 汇票贴息入什么科目
  • 怎么算应纳税收多少
  • 自行研发无形资产暂时性差异
  • 稽查补缴增值税做账
  • 外购商品用于促销能抵扣吗
  • 人力资源公司劳务派遣怎么收费
  • 从个人处借款的法律规定
  • 房地产建造运费怎么计算
  • 住房公积金如何在手机上提取
  • 退税勾选后如何开红字
  • 企业的公益性捐赠支出
  • 成本算错了
  • 以前年度费用如何列支
  • iphone怎么格式化掉所有内容和设置
  • 笔记本低电量提示
  • mac系统10.10
  • 电力安装有前途吗
  • 定额发票收入
  • Win10 (21H1)Build 19043.1266更新补丁KB5005611正式版发布:附修复更新内容
  • vue怎么拿到后端数据
  • 用人单位如何缴纳医疗保险
  • 印花税贴花怎么贴划线
  • 应纳税所得额准予扣除的有
  • visual studio code怎么创建vue项目
  • 小规模纳税人季报需要报什么
  • 网站禁止了有什么方法打开
  • yolov3训练自己的数据超详细
  • python查看type
  • dpkg命令详解
  • sensor tester
  • php设置标题
  • 企业确认收入实现的条件有哪些?
  • 公司的现金收入包括
  • 购买监控器计入什么科目
  • 政府补助的相关法律法规
  • 建筑公司内账收什么费用
  • 增值税现代服务业包括哪些内容
  • 收到社保的退费是怎么回事
  • 预收租金发票怎么开
  • 事业单位劳务派遣工能长期干下去吗
  • 出口退税暂不抵税怎么办
  • 长期股权投资全部亏损汇算清缴怎么填
  • 企业的期间费用包括制造费用吗
  • 报销管理规定
  • 预收账款的会计编码
  • 待认证进项税额期末怎么办
  • 收据能作为抵减成本吗
  • 关于注册资本的最新规定
  • windows7软件运行没反应
  • win8系统打开苹果系统文件
  • mac终端好玩的命令
  • sethook.exe - sethook进程是什么文件 有何作用
  • 一岁的宝宝可以喝枸杞水吗
  • win10 系统桌面
  • 手机ssh远程连接服务器
  • kpg是什么文件
  • win8.1开机慢
  • win8更改账户
  • Windows 8 Modern Apps 网络隔离如何解除?
  • 角色格斗类游戏
  • opengl 位图
  • extjs 为某个事件设置拦截器
  • perl调试
  • js浅拷贝的方法
  • vue如何用
  • js判断ua
  • python算法怎么用
  • jquery做下拉
  • Android调用系统的电话拨号程序
  • js字段截取
  • 北京增值税普通发票图片
  • 广西南宁税务12366
  • 青岛电子税务局电话人工客服电话
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设