近期有需求需要做一个可视化工具,一个监控页面,需求较为轻量,且不想搞前后端分离,想要一个jar搞定,主要也是不想部署两套服务(一个前端,一个后端),所以想要自己搞一搞,于是开始了趟坑之旅
整体设计思路
- springboot整合整个服务
- jetty提供servlet容器
- springmvc提供路由
- 模板引擎+js渲染动态页面
- ui美化页面
数据采集
可视化的需求当然是用来数据分析,然后根据分析后的数据指定监控指标,发送异常告警。那么自然就少不了数据。那么就需要调用数据的采集问题
- grafana报表配置的api,查看官方api可以满足我们的需求,提供增删改查登录认证切换用户组织。切换组织是完全走的歪门邪道,非官方api,自己按照页面操作时看请求抓出来的api。
- dubbo元数据,当然可以从zk直接拉取自己想要的数据,但是还是需要走常规路线,提需求给工具团队或者运维团队,请求友方的帮助。自然数据采集不是问题
数据采集调研期间就出现了两个问题?
- grafana是否可以通过抓到的api进行切换组织,经过测试是可以的:http://grafana_host/?orgId=22
- grafana认证问题,从官方文档中看到,是有api提供认证的,操作的方式可以通过创建token,携带token进行操作报表。另一种方式则是使用登录后的cookie进行操作报表。我们选用的是登录的方式。因为公司有提供的cas服务,所以只要登录认证后便可以为所欲为了,哈哈
数据采集的问题基本全部走通,那么就可以进行下一步了,原型设计
页面原型
首先要搞一个原型工具,大体搜了搜选择了墨客mockplus,对于我个小白学习使用的体验来说,是很简单且友好的,界面获取不好看,不能责备工具,还是个人设计问题,不多说上图
UI设计
哈。。。完全空白,想要搞一个好看的页面真得不简单,首先想到了那原来的前端项目使用,使用的是node.js+angular.js,但是真得好重,要想改成自己用的简单页面,量不小,而且上线时还需要申请单独的前端服务部署的机器。于是就想到了我们伟大的开源社区贡献者们,开始选择了使用Bootstrap框架模板,但是发现真得没有适合的模板,为了能快速搞起来,最后选择了妹子ui,哈哈哈,其实是amazeui。感谢开源贡献者的小伙伴们。不多说上图。没错里面的表格选项正式我们的需要。
页面采用jquery.js+amaze.js实现。官方中文文档很详细,然后按照文档修改页面改成自己想要的样式,还是很容易上手的,麻雀虽小,功能俱全,主题风格切换,边框隐藏,登录页等等,图表采用的是百度开源的产品echart
撸码踩坑
有了页面,那还等什么,撸码
使用springboot开发,选择模板引擎。
- velocity,由于1.5.x之后的springboot不再支持,想要支持需要手工配置,不如其他自动配置便捷
- thymeleaf,开始搞起,结果发现其设计对页面的书写格式要求很严格,各种报错注释中不能包好"–",标签必须以结尾。因为页面较多书写不够严谨,所以改动量较大,于是放弃
- freemarker,切换成freemarker确实不会再各种格式报错了,于是开始撸码
选择js
感觉自己像个老古董一样捡起来了jquery开始撸码,哎,期间真得踩了好多坑,具体整理几个具有代表性的
- 为了实现复选框,下拉框+模糊匹配等等功能,使用jquery要各种对dom操作。且每次请求都要根据id或者其他属性获取dom读取其值。关联耦合性较强
- 当然厉害的还在后面。动态刷新表格,没错,jquery是没有双向绑定的,请求后端数据后,根据返回json数据拼接表格,再通过dom对其拼接的表格字符串进行替换。。。这个代码写完后,真得很酸爽。
这两点搞得有点崩溃,于是便想尝试新得一些框架,于是便找了找,angular、react、vue。最后发现vue这个框架。轻量,学习成本低,而且支持双向数据绑定,数据刷新后页面会同步渲染。这不正是我们的需要。而且使用mvvm的设计理念,代码结构更加简洁明了。几乎可以告别dom操作。与页面耦合性低
开始撸码,可怜之前的代码,咬牙也得重构,哈哈,其实没多少页面
改为Vue.js之后结果发现报错,前期认为是freemarker模板不支持的问题,于是切换成thymeleaf,之后便没有异常了。后来发现其实是需要配置一下就可以了,不过这个体验还是不好的,说明了thymeleaf的格式严谨还是有必要的
templates should only be responsible for mapping the state to the ui. avoid placing tags with side-effects in your templates, such as <script>, as they will not be parsed.
//解决方法
<script type="application/javascript">
// your code
</script>
饶了一大圈又回到了thymeleaf,springboot推荐还是有些依据的
踩坑干货
问题:jquery ajax POST(json)请求后端报错ERROR:415
原因:请求header没有设置json
headers: {'Accept': 'application/json','Content-Type': 'application/json'}
问题:jquery ajax POST(json)请求,后台响应成功,返回正确json但不执行success方法,执行error
原因:返回的json格式不对
问题:springboot+springMVC项目,控制台报错
JSON parse error: Unrecognized token 'appCode': was expecting ('true', 'false' or 'null')
原因:解决方法:data:JSON.stringify(str)。请求参数data数据JSON格式不规范,1.4+以上的jquery版本对json格式要求更加严格.如果不是严格的json格式,就不能正常执行success回调函数.
问题:数据刷新页面不同步刷新
原因:
- 方法(例如:异步请求的post方法中)中使用的this要复制到本地例如:var _this = this。
- 数组操作要使用push、set等操作,指针改变操作不会同步刷新数据。
- 直接通过dom操作元素属性也不会同步数据至vue的data model,例如:通过jquery将所有复选框置为选中状态
问题:增加@click之后页面加载不全且不报错
原因:click指向的方法定义有问题,因为我使用的方法名是"delete",与vue.js中的方法冲突导致的
问题:index页面支持点击按钮隐藏左边框,tables页面不支持
原因:发现模板的app.js中对于不同页面的body有个性化的处理,发现我在使用thymeleaf模板时用的replace将tables页面的body的data-type属性替换了,而模板中使用的data-type属性是index页面的,于是导致app.js在加载tables页面时采用了index的处理方式,由于页面差异大,数据格式也有很大差异,导致报错,没有继续加载后面的动作,而点击隐藏的动作正是在后面的代码中进行处理的,于是将模板的引用的replace方式改为include方式,每个页面使用自己正确的data-type属性,问题得以解决
问题:vue的data数据在页面中使用{{}}获取不到值
原因:因为自己的写script脚本放在了thymeleaf模板块的外面,而使用vue的数据是在thymeleaf模板块的内部导致的,将script脚本放入thymeleaf模板内部即可
总结
- Vue.js果真很抢单,轻量,学习成本低,并且拥有丰富多样的组件库,官方文档健全。支持双向数据同步。设计模式采用MVVM架构,将view与model隔离开,实现同样的功能代码比jquery更加简洁优雅。
- thymeleaf模板引擎3.x功能更加强大健全,支持模板的嵌套。如果不需要前后端分离,springboot的完美支持。相对于freemarker暂时没有想到什么优势,但是其严格规范使得其对于vue这类年轻的框架能够完美的融合,这一点是要比freemarker更好一些的,当然由于格式对的要求严谨,以至于一些开源框架使用起来涉及的改动要比freemarker要更多
- AmazeUI开源框架,页面很漂亮,开源模板也很丰富,官方文档健全,学习成本低,易上手,感谢开源大神们的贡献
- 感谢Element开源ui与vue组件,让前端的开发更加简洁
- 感谢vue-select提供的强大选项功能组件