当前位置: 首页 > news >正文

后端程序员开发win小工具(未完待续)

github:https://gitee.com/forgot940629/win-tool-demo
本地启动,查看http://127.0.0.1:8080/form
在这里插入图片描述

场景

在日常工作中可能需要后端开发者开发一些辅助工具。这些辅助工具通常希望能想其他软件一样在桌面系统运行,并且有一些桌面应用的基本功能(可视化页面,配置文件,日志)。与其他应用程序最大的不同是,这种小工具只在很小范围内的开发者之间使用,通常情况下使用者都是开发者的同事。所以对可靠性要求不会特别高(毕竟不是给客户使用),对页面美观或者交互逻辑也没有很高要求,但是需要在较短的时间内实现相应功能。
本篇文章针对上述场景提供了一个demo(代码链接在最上面),便于有类似场景的java后端开发者可以快速构建出一些小工具。需要使用者有一定的spring使用经验,能够写一点前端代码。

问题

问题详述
交互工具如何与使用者交互?命令行交互还是可视化页面?如果是可视化页面选择什么技术展示页面?
错误软件出问题时如何排查错误?如何让用户感知到错误?
配置很多东西不能写死在程序中,不能有一点改动就需要重新编译发布。需要有一种方式可以加载配置文件
发布使用者可能没有开发者相同的运行环境,所以需要一种方式让没有相应运行环境的用户也可以使用此工具

方案

方案概述

问题方案
交互后端使用thymeleaf编写页面,程序运行之后用户可在浏览器上进行相应操作
错误可视化页面中打印错误日志,程序运行时在某个文件中记录运行日志
配置将工作目录下特定名称的作为配置文件
发布使用jpackage将可执行的jar包打包成安装包,用户可通过此安装包安装程序

方案选择的原因

交互

交互的实现方案首先要考虑我会什么。我不想为了开发一个小工具而去学习其他知识,没那么多时间。所以我在方案选择上只考虑了vue和thymeleaf。最终导致我抛弃vue的原因是vue好像要单独启动一个进程去提供前端页面服务(我在github上看了下halo这个项目中对于vue和thymeleaf的使用),而thymeleaf和后端应用都在一个进程,启动spring之后直接就可以在浏览器上看到thymeleaf的页面。所以选择了thymeleaf。

选用thymeleaf更多的原因是我在这方面了解的确实不多,如果有其他好用的且好学(最好也是用html+js/ts编写页面)的工具,辛苦大佬们告知下。

错误

web服务中,错误一般通过两种形式展示出来,一种是通过页面弹窗告知客户,另一种是通过后端日志或者后端报警告知相关运维人员。
作为一个小工具,不需要连接报警平台,但是需要日志文件记录运行状况。同时为了让用户能在页面感知到相应错误,我决定使用文本框展示错误信息,每次新增的错误信息都追加到"运行日志"这个文本框中。
相比于弹窗,文本框有两点好处,一个是可以展示更多的错误细节,甚至可以把报错堆栈打印到文本框上(因为使用者通常也是程序员,所以打印报错堆栈可能更有助于使用);另一个好处是文本框有对历史报错信息的保留,如果是弹窗的话可能报错信息一闪而过,于是就只能F12中一条条翻看请求寻找报错信息。
在这里插入图片描述

配置

我能想到的最直接的设置配置文件的方式就是让程序去某个绝对路径找配置文件,比如"C:\config.properties"。但是如果所有小工具都是这么加载配置文件,那么不同的工具直接可能会共用一个配置文件,会造成一些问题。比如不能同时使用多个工具,因为多个工具之间会抢占端口。

所以我希望配置文件可以与程序在同一个文件夹。

为了实现这一目的,我调用System.getProperty("user.dir") 获取当前工作目录(这个当前工作目录实际上就是程序安装之后exe文件所在目录,后续会介绍如何生成安装包),然后在当前目录下找"config.properties"这个文件并加载。

发布

D:\software\jdk17\java\bin\jpackage.exe --win-dir-chooser --name PhoneNumberGeo --main-jar demo-0.0.1-SNAPSHOT.jar --input .\ --type exe

Tips

安装时尽量不要在C盘下,如果一定要安装到C盘下也尽量不要放到"Program Files"这个文件夹下,jpackage默认安装路径就是这个文件夹,但是我安装到这个文件夹下之后总是会出现奇怪的问题,比如日志不全或者配置文件加载错误。

待解决的问题

程序运行时没有图标,只能通过任务管理器关闭程序

相关文章:

  • JS浏览器的默认行为及阻止行为,阻止右键菜单、阻止超链接跳转、阻止拖拽事件
  • k8s的yaml文件中的kind类型都有哪些?(详述版Part1/2)
  • C#高级 10 Linq操作
  • 记mongodb7.0安装时的常用操作 windows
  • Docker容器进入的4种方式(推荐最后一种)
  • 部署可道云网盘的一个漏洞解决
  • UISegmentedControl控件定制
  • 结构体的含义、表示、规范、运用
  • uniapp小程序当页面内容超出时显示滚动条,不超出时不显示---样式自定义
  • Python中魔术方法汇总
  • 华为OD机试 - 最小矩阵宽度(Java JS Python C)
  • 【无标题】关于异常处理容易犯的错
  • 控制台项目和ASP.Net Core 1.项目创建 2.一键启动多个服务 3.引入别的库
  • 继续理解Nacos的CP和AP架构模型!
  • Github上传代码/删除仓库/新建分支的操作流程记录
  • express + mock 让前后台并行开发
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • Java新版本的开发已正式进入轨道,版本号18.3
  • Rancher-k8s加速安装文档
  • Sublime text 3 3103 注册码
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • webgl (原生)基础入门指南【一】
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 给初学者:JavaScript 中数组操作注意点
  • 构造函数(constructor)与原型链(prototype)关系
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 我从编程教室毕业
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • ​第20课 在Android Native开发中加入新的C++类
  • $.each()与$(selector).each()
  • (¥1011)-(一千零一拾一元整)输出
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (1) caustics\
  • (1)SpringCloud 整合Python
  • (4) PIVOT 和 UPIVOT 的使用
  • (八)Flask之app.route装饰器函数的参数
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (一)u-boot-nand.bin的下载
  • (转)socket Aio demo
  • .net framework 4.0中如何 输出 form 的name属性。
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .NET 指南:抽象化实现的基类
  • .Net下C#针对Excel开发控件汇总(ClosedXML,EPPlus,NPOI)
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • [AIGC] Redis基础命令集详细介绍
  • [Angular] 笔记 8:list/detail 页面以及@Input
  • [bzoj 3534][Sdoi2014] 重建
  • [C]整形提升(转载)
  • [Erlang 0129] Erlang 杂记 VI 2014年10月28日
  • [G-CS-MR.PS02] 機巧之形2: Ruler Circle
  • [ISITDTU 2019]EasyPHP
  • [LeetCode]: 145: Binary Tree Postorder Traversal
  • [leetcode]114. Flatten Binary Tree to Linked List由二叉树构建链表
  • [Linux]文件基础-如何管理文件
  • [Oh My C++ Diary]Main函数参数argc,argv如何传入