Springboot 整合Flowable工作流框架搭建
我们在开发自动化办公软件时经常会遇到各种审批流程功能,这个使用就需要使用到工作流引擎。目前主流的工作流引擎有Activiti、Flowable、camunda,其中Flowable是在Activiti的基础上开发出来的,基于BPMN2.0协议,它包括 BPMN(Business Process Model and Notation)引擎、CMMN(Case Management Model and Notation)引擎、DMN(Decision Model and Notation)引擎、表单引擎(Form Engine)等模块。
这里我们基于springboot和PostgreSQL数据库,介绍一下如何搭建一个基础的Flowable工作流框架。
创建项目,添加依赖
- 下图是我在线创建的springboot项目,只添加了Spring Web和Postgre SQL Driver两个依赖。
- 添加Flowable依赖
<dependency><groupId>org.flowable</groupId><artifactId>flowable-spring-boot-starter</artifactId><version>6.7.2</version>
</dependency>
-
配置数据库链接
这里要解释一下,网上有的博文说,添加完数据库,启动服务,就会在数据库里自动创建一堆表,本人测试需要创建bpmn20.xml文件后,数据库才会自动生成对应的表。
spring:datasource:username: postgrespassword: postgresurl: jdbc:postgresql://192.168.2.172/test
到这里已经完成了项目的基础配置。
bpmn20.xml文件制作
在整个工作流框架中,比较核心的是bpmn20.xml文件的制作,如果之前没有一定的基础,制作整个文件还是有点难度的。idea的插件市场里有一个Flowable BPMN visualizer插件,可以在idea中直接用来制作bpmn20.xml文件。
安装插件后,在resources文件夹下创建processes文件夹,流程文件默认放在此文件夹下。idea中右键创建文件,选择BPMN 2.0 file。
注意文件名要以**.bpmn20.xml**结尾。在创建的文件上,右键选择View BPMN。
在弹出的编辑器中,即可进行相关的绘制操作。新手,注意,在编辑器上右键可以创建节点。
网上也有一些其他工具可以用来绘制的,都可以尝试。我的xml文件源码如下:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef"><process id="ask_for_leave" name="ask_for_leave" isExecutable="true"><startEvent id="sid-8f75290b-6d4f-4304-98e3-592be1f19a4e"/><endEvent id="sid-4d3f3115-90f9-4cad-a8d3-df415f8aaa9d"/><userTask id="sid-ca4fe38f-af1d-47ad-8646-d045a82fcb6a" name="请假"/><userTask id="sid-7b7c9585-5913-49fe-910f-fea79e53518c" name="组长审批" flowable:assignee="${taskUser}"/><userTask id="sid-627ef23c-3f54-4536-bda9-bbf0d3243230" name="经理审批" flowable:assignee="${taskUser}"/><exclusiveGateway id="sid-becd3cfd-2ede-4df6-8916-83d9e4b2eb5f" /><sequenceFlow id="sid-b1bdf216-3433-4052-ae80-ad753e16aed7" sourceRef="sid-becd3cfd-2ede-4df6-8916-83d9e4b2eb5f" targetRef="sid-627ef23c-3f54-4536-bda9-bbf0d3243230" name="通过"><conditionExpression xsi:type="tFormalExpression">${finishFlag==\"YES\"}</conditionExpression></sequenceFlow><sequenceFlow id="sid-0b327947-1e7f-48c3-8047-e8afc3d15005" sourceRef="sid-8f75290b-6d4f-4304-98e3-592be1f19a4e" targetRef="sid-ca4fe38f-af1d-47ad-8646-d045a82fcb6a"/><sequenceFlow id="sid-e5703760-35e2-497f-9501-7b616d5c1d02" sourceRef="sid-ca4fe38f-af1d-47ad-8646-d045a82fcb6a" targetRef="sid-7b7c9585-5913-49fe-910f-fea79e53518c"/><sequenceFlow id="sid-17b98be9-ef29-48a8-8cf6-cfde4be9d7c9" sourceRef="sid-7b7c9585-5913-49fe-910f-fea79e53518c" targetRef="sid-becd3cfd-2ede-4df6-8916-83d9e4b2eb5f"/><serviceTask id="sid-ddda9b4d-414e-40d0-aaa1-1a8bbac4d49a" flowable:exclusive="true" name="发送失败消息" flowable:class="com.work.flow.listener.TestServiceListener"/><sequenceFlow id="sid-7f8d7cc2-ddd0-4cb4-9ce6-81e8b42f4717" sourceRef="sid-becd3cfd-2ede-4df6-8916-83d9e4b2eb5f" targetRef="sid-ddda9b4d-414e-40d0-aaa1-1a8bbac4d49a" name="不通过"><conditionExpression xsi:type="tFormalExpression">${finishFlag==\"NO\"}</conditionExpression></sequenceFlow><sequenceFlow id="sid-95ed6745-c15f-4489-a9a5-93f4aeea1f43" sourceRef="sid-ddda9b4d-414e-40d0-aaa1-1a8bbac4d49a" targetRef="sid-4d3f3115-90f9-4cad-a8d3-df415f8aaa9d"/><exclusiveGateway id="sid-03e9886b-d80c-4a5a-8916-76f2b6683727" /><sequenceFlow id="sid-e8f7bf08-9b5b-4f0b-b0aa-c1a74d42e870" sourceRef="sid-03e9886b-d80c-4a5a-8916-76f2b6683727" targetRef="sid-ddda9b4d-414e-40d0-aaa1-1a8bbac4d49a" name="不通过"><conditionExpression xsi:type="tFormalExpression">${finishFlag==\"NO\"}</conditionExpression></sequenceFlow><sequenceFlow id="sid-fc8f3bf6-d817-4d6b-9dbd-f15d11032fae" sourceRef="sid-627ef23c-3f54-4536-bda9-bbf0d3243230" targetRef="sid-03e9886b-d80c-4a5a-8916-76f2b6683727"/><endEvent id="sid-f7bc1956-c2b1-4036-99fa-0318f6da4221"/><sequenceFlow id="sid-2a97e964-4e84-4936-9356-14b7b7b6ecb4" sourceRef="sid-03e9886b-d80c-4a5a-8916-76f2b6683727" targetRef="sid-f7bc1956-c2b1-4036-99fa-0318f6da4221" name="通过"><conditionExpression xsi:type="tFormalExpression">${finishFlag==\"YES\"}</conditionExpression></sequenceFlow></process><bpmndi:BPMNDiagram id="BPMNDiagram_ask_for_leave"><bpmndi:BPMNPlane bpmnElement="ask_for_leave" id="BPMNPlane_ask_for_leave"><bpmndi:BPMNShape id="shape-44c54737-7c91-4844-8210-7db7f6853bb6" bpmnElement="sid-8f75290b-6d4f-4304-98e3-592be1f19a4e"><omgdc:Bounds x="-245.0" y="-65.0" width="30.0" height="30.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-12f82f19-3220-442d-893b-b139db4834e4" bpmnElement="sid-4d3f3115-90f9-4cad-a8d3-df415f8aaa9d"><omgdc:Bounds x="-155.0" y="15.0" width="30.0" height="30.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-146cee26-7a5b-4da7-9bbb-6c392e645b94" bpmnElement="sid-ca4fe38f-af1d-47ad-8646-d045a82fcb6a"><omgdc:Bounds x="-180.0" y="-75.0" width="55.0" height="50.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-bd5bc59b-ab57-4e3c-8dfa-cb2827d9a331" bpmnElement="sid-7b7c9585-5913-49fe-910f-fea79e53518c"><omgdc:Bounds x="-75.0" y="-80.0" width="80.0" height="60.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-cc2b2bce-04fd-4641-ae8b-419d9f79c2b0" bpmnElement="sid-627ef23c-3f54-4536-bda9-bbf0d3243230"><omgdc:Bounds x="185.0" y="-97.5" width="100.0" height="55.0"/></bpmndi:BPMNShape><bpmndi:BPMNShape id="shape-43f90d29-b7d6-4a74-8acb-1fc7f3f29289" bpmnElement="sid-becd3cfd-2ede-4df6-8916-83d9e4b2eb5f"><omgdc:Bounds x="55.0" y="-80.0" width="40.0" height="40.0"/></bpmndi:BPMNShape><bpmndi:BPMNEdge id="edge-9eca388f-9baf-4a0b-8201-892c738b6ad0" bpmnElement="sid-b1bdf216-3433-4052-ae80-ad753e16aed7"><omgdi:waypoint x="95.0" y="-60.0"/><omgdi:waypoint x="185.0" y="-70.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-a5e04944-60fb-4696-ad16-c8092d6c0bb5" bpmnElement="sid-0b327947-1e7f-48c3-8047-e8afc3d15005"><omgdi:waypoint x="-215.0" y="-50.0"/><omgdi:waypoint x="-180.0" y="-50.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-6fb6a4c1-3b9a-4238-a66b-10f3d8571af1" bpmnElement="sid-e5703760-35e2-497f-9501-7b616d5c1d02"><omgdi:waypoint x="-125.0" y="-50.0"/><omgdi:waypoint x="-75.0" y="-50.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-e23fcf4e-1309-4639-a40e-9f0fe3fb42b7" bpmnElement="sid-17b98be9-ef29-48a8-8cf6-cfde4be9d7c9"><omgdi:waypoint x="5.0" y="-50.0"/><omgdi:waypoint x="55.0" y="-60.0"/></bpmndi:BPMNEdge><bpmndi:BPMNShape id="shape-d6c43ede-95db-49fe-a468-0c8678deff6f" bpmnElement="sid-ddda9b4d-414e-40d0-aaa1-1a8bbac4d49a"><omgdc:Bounds x="-20.0" y="7.5" width="110.0" height="75.0"/></bpmndi:BPMNShape><bpmndi:BPMNEdge id="edge-80b91b72-184a-4add-878d-a0553d8fdd04" bpmnElement="sid-7f8d7cc2-ddd0-4cb4-9ce6-81e8b42f4717"><omgdi:waypoint x="75.0" y="-40.0"/><omgdi:waypoint x="62.5" y="7.5"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-92accc38-c426-45f8-bf82-4ab1d8b6625b" bpmnElement="sid-95ed6745-c15f-4489-a9a5-93f4aeea1f43"><omgdi:waypoint x="-20.0" y="45.0"/><omgdi:waypoint x="-125.0" y="30.0"/></bpmndi:BPMNEdge><bpmndi:BPMNShape id="shape-aed10d1f-11b7-4c70-91ca-63514182f93f" bpmnElement="sid-03e9886b-d80c-4a5a-8916-76f2b6683727"><omgdc:Bounds x="225.0" y="15.0" width="40.0" height="40.0"/></bpmndi:BPMNShape><bpmndi:BPMNEdge id="edge-1a9651dc-930e-4642-b2f3-4ba0b47fe97d" bpmnElement="sid-e8f7bf08-9b5b-4f0b-b0aa-c1a74d42e870"><omgdi:waypoint x="225.0" y="35.0"/><omgdi:waypoint x="90.0" y="45.0"/></bpmndi:BPMNEdge><bpmndi:BPMNEdge id="edge-5e55bb58-f07a-45d5-bb8a-8c13a6c0b9dd" bpmnElement="sid-fc8f3bf6-d817-4d6b-9dbd-f15d11032fae"><omgdi:waypoint x="260.0" y="-42.5"/><omgdi:waypoint x="245.0" y="15.0"/></bpmndi:BPMNEdge><bpmndi:BPMNShape id="shape-12be209b-f581-4e87-b480-41c60acb8d8e" bpmnElement="sid-f7bc1956-c2b1-4036-99fa-0318f6da4221"><omgdc:Bounds x="255.0" y="100.0" width="30.0" height="30.0"/></bpmndi:BPMNShape><bpmndi:BPMNEdge id="edge-7aba8c58-63e5-4c57-b3d7-679ad58b6388" bpmnElement="sid-2a97e964-4e84-4936-9356-14b7b7b6ecb4"><omgdi:waypoint x="245.0" y="55.0"/><omgdi:waypoint x="270.0" y="100.0"/></bpmndi:BPMNEdge></bpmndi:BPMNPlane></bpmndi:BPMNDiagram>
</definitions>
接口开发
-
防止流程图乱码配置
package com.work.flow.config;import org.flowable.spring.SpringProcessEngineConfiguration; import org.flowable.spring.boot.EngineConfigurationConfigurer; import org.springframework.context.annotation.Configuration;@Configuration public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {@Overridepublic void configure(SpringProcessEngineConfiguration engineConfiguration) {engineConfiguration.setActivityFontName("宋体");engineConfiguration.setLabelFontName("宋体");engineConfiguration.setAnnotationFontName("宋体");} }
-
发起流程接口
package com.work.flow.controller;import org.flowable.bpmn.model.BpmnModel; import org.flowable.engine.*; import org.flowable.engine.runtime.Execution; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.image.ProcessDiagramGenerator; import org.flowable.task.api.Task; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List;@RestController public class TestController {@AutowiredRuntimeService runtimeService;@AutowiredTaskService taskService;@AutowiredRepositoryService repositoryService;@AutowiredProcessEngine processEngine;@GetMapping( "/add")public String addExpense(@RequestParam String userId) {//启动流程HashMap<String, Object> map = new HashMap<>(4);//name="客服代表" flowable:candidateGroups="${customerServiceId}"map.put("userId", userId);//<process id="adviceApply" name="投诉建议" isExecutable="true">ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("ask_for_leave", map);return "提交成功.流程Id为:" + processInstance.getId();} }
-
获取流程图接口
@GetMapping("/pic")public void showPic(HttpServletResponse resp, @RequestParam String processId) throws Exception {System.out.println("收到请求"+processId);List<ProcessInstance> instances =runtimeService.createProcessInstanceQuery().list();for (ProcessInstance instance : instances) {System.out.println(instance.getId());}ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();if (pi == null) {return;}List<Execution> executions = runtimeService.createExecutionQuery().processInstanceId(processId).list();List<String> activityIds = new ArrayList<>();List<String> flows = new ArrayList<>();for (Execution exe : executions) {List<String> ids = runtimeService.getActiveActivityIds(exe.getId());activityIds.addAll(ids);}/*** 生成流程图*/BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, false);OutputStream out = null;byte[] buf = new byte[1024];int legth = 0;try {out = resp.getOutputStream();while ((legth = in.read(buf)) != -1) {out.write(buf, 0, legth);}out.flush();} catch (Exception e) {e.printStackTrace();} finally {if (in != null) {in.close();}if (out != null) {out.close();}System.out.println("运行结束");}}
- 流程推进接口
/*** 流转** @param processId 流程id*/@GetMapping("/apply")public String apply(@RequestParam String processId,@RequestParam String userId,@RequestParam boolean isPass) {//查询当前办理人的任务IDTask task = taskService.createTaskQuery()//使用流程实例ID.processInstanceId(processId)//任务办理人.singleResult();if (task == null) {throw new RuntimeException("流程不存在");}//通过审核HashMap<String, Object> map = new HashMap<>();map.put("taskUser", userId);String pass = "NO";if(isPass){pass = "YES";}map.put("finishFlag", pass);taskService.complete(task.getId(), map);return "processed ok!";}
走流程后,再次查看流程图
总结
- 总体bpmn20.xml的配置比较麻烦,需要一定的专业知识
- 上手还是有一定的难度的
相关文章:

Springboot 整合Flowable工作流框架搭建
我们在开发自动化办公软件时经常会遇到各种审批流程功能,这个使用就需要使用到工作流引擎。目前主流的工作流引擎有Activiti、Flowable、camunda,其中Flowable是在Activiti的基础上开发出来的,基于BPMN2.0协议,它包括 BPMN&#x…...

ASE0510SH-ASEMI的MOS管ASE0510SH
编辑-Z ASE0510SH在SOT-89封装里的静态漏极源导通电阻(RDS(ON))为140mΩ,是一款N沟道中低压MOS管。ASE0510SH的最大脉冲正向电流ISM为15A,零栅极电压漏极电流(IDSS)为1uA,其工作时耐温度范围为-55~150摄氏度。ASE0510…...

Golang学习Day2
Go语言中的函数go语言中函数特性go语言有三种函数:普通函数、匿名函数(没有名称的函数)方法(定义在struct上的函数)。receivergo语言中不运算函数重载(overload),也就是说不允许函数…...

Android 中malloc_debug 原理详解
版本基于:Android R 0. 前言 最近上项目中遇到一个native 可能内存泄漏的问题,曾考虑使用HWASAN,但这个工具是针对整个系统,运行代价还是很高的。而笔者遇到的问题大致有所方向,能指定到某一个进程,针对单…...

D. Triangle Coloring【组合数学,乘法逆元】
链接 分析 题目要求我们去求出最优的染色的方法数。首先什么时候是最优的,这里只有两种颜色,不可能取到三条边,即蓝色为B,红色为R,有BBB,RRR,BBR,RRB四种组合,显然最多的就是取两条边,我们想取到…...

【读论文】AttentionFGAN
【读论文】AttentionFGAN介绍网络架构提取红外图像目标信息的网络辨别器损失函数生成器损失函数辨别器损失函数总结参考论文: https://ieeexplore.ieee.org/document/9103116/如有侵权请联系博主介绍 好久没有读过使用GAN来实现图像融合的论文了,正好看…...

ClickHouse 配置文件使用说明
本文主要介绍 ClickHouse 的配置文件。在 ClickHouse 中配置主要分为两类,一类是负责 server 端配置的,另一类是负责用户端配置的。负责 server 端配置的一般会放在 config.xml 文件中,负责用户端配置的一般会放在 users.xml 文件中。当然如果…...

如果不是互联网人,谁会找到这些神器?
一、上线啦 你肯定该问了,这个是什么鬼东西。它本来是一个创建自己网站的网站。 现在使用它可以创建自己的小程序,又不是有点小厉害了。 而且功能强大,还支持微信支付,分销,优惠券,营销等多种功能。 还有多…...

Neo4j优化
使用参数 查询参数 :params设置参数 :param actorName: Tom Hanks参数的冒号后要用空格使用参数用 $ MATCH (p:Person)-[:ACTED_IN]->(m:Movie) WHERE p.name $actorName RETURN m.released AS releaseDate,m.title AS title ORDER BY m.released DESC多个参数 MATCH (p:Pe…...

CF1692G 2^Sort 题解
CF1692G 2^Sort 题解题目链接字面描述题面翻译题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示思路代码实现题目 链接 https://www.luogu.com.cn/problem/CF1692G 字面描述 题面翻译 给你一个长度为 n(∑n<2⋅105)n \ (\sum n < 2\cdot 10^5)n (∑n<…...

关于物理像素,逻辑像素,像素比
关于物理像素、逻辑像素(css像素)、分辨率、像素比的超详细讲解 在日常生活中,有这样一个问题。同样的图片为什么在不同的设备上显示的大小是不一样的。🤒带着这个问题来说明一下。 一、物理像素 设备刚生产出来就已经固定了&a…...

JavaSE基础部分总结
JavaSe基础部分 文章目录JavaSe基础部分1.命名规范2.基本的数据类型3.方法3.1方法的基本格式3.2 方法的分类3.3 方法的注释4.数组4.1 数组的命名格式4.2 数组中存在的址交换的操作4.3数组Arrays常用的方法1. Arrays.asList(数组作为参数或者数据作为参数):2.Arrays.…...

C++基础知识
目录类和对象C static_cast、dynamic_cast、const_cast和reinterpret_cast1、为什么要引入这四种类型转化?2、应用场景。C/C类型转换的本质struct和class的区别为什么会诞生面向对象的编程思想析构函数的执行时机初始化 const 成员变量C const对象(常对象…...

2023/2/24 图数据库Neo4j的理解与应用
1 什么是图数据库(graph database) 十大应用案例:https://go.neo4j.com/rs/710-RRC-335/images/Neo4j-Top-Use-Cases-ZH.pdf “大数据”每年都在增长,但如今的企业领导者不仅需要管理更大规模的数据,还迫切需要从现有…...

适合视力障碍者的Linux
导读有哪些最适合视障用户的 Linux 发行版?让我们一起来看看。 如果有人视力障碍或失明,他们可能会依赖声音提示或其他交互方式(如盲文)来阅读和交流。 他们怎样才能使用 Linux 发行版? 嗯,一般来说&…...

Tina Linux 存储开发指南
Tina Linux 存储开发指南 1 概述 1.1 编写目的 介绍TinaLinux Flash,分区,文件系统等存储相关信息,指导方案的开发定制。 1.2 适用范围 Tina V3.0 及其后续版本。 1.3 相关人员 适用于TinaLinux 平台的客户及相关技术人员。 2 分区管…...

【洛谷 P2670】[NOIP2015 普及组] 扫雷游戏 题解(模拟)
[NOIP2015 普及组] 扫雷游戏 题目背景 NOIP2015 普及组 T2 题目描述 扫雷游戏是一款十分经典的单机小游戏。在 nnn 行 mmm 列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻…...

【nohup引发磁盘读写高】nohup命令导致服务器磁盘读写占满该如何修复?
【写在前面】自己在跑一个项目的时候,猛然发现服务器挂了,直接访问不了,呈现出一种卡死现象,我当时都懵了,难道阿里在后端升级,也不会选择在工作日的时间升级吧,于是乎就咨询了一下客服。才有下…...

MySQL(二)索引和SQL优化
MySQL进阶MySQL体系结构存储引擎存储引擎特点InnoDB逻辑存储结构MyISAMMemory存储引擎选择索引索引结构二叉树B-TreeBTreeHash索引分类索引语法SQL性能分析工具SQL执行频率慢查询日志profile详情explain索引使用联合索引索引失效情况SQL提示覆盖索引前缀索引单列索引与联合索引…...

Java常用日期类(包含三代)_Date类及Calendar类等
一.java.util.Date类概述从JDK 1.0出现。表示一个日期和时间,精确到毫秒,内部getTime()从1970年1月1号开始算。1. java.util.Date类构造部份构造已经过时,重点看以下两个构造。public Date()从运行程序的此时此刻到时间原点经历的毫秒值&…...

计算机网络你都懂了吗
文章目录一、计算机网络的定义简单定义通用定义二、计算机网络通信过程三、什么是网络协议(Protocol)四、网络协议组成及功能一、计算机网络的定义 简单定义 计算机网络是一些相互连接的、自治的计算机系统的集合。 通用定义 将处于不同位置并具有独…...

3.4 Spring Boot 日志配置
第3章 Spring Boot 的系统配置 3.1 Spring Boot 系统配置文件 3.2 Spring Boot 自定义配置项 3.3 Spring Boot 其他配置 3.4 Spring Boot 日志配置 3.5 实战:Spring Boot 实现系统多环境配置 3.4 Spring Boot 日志配置 日志对于系统监控、故障定位非常重要…...

3款百里挑一的国产软件,逆天好用,装了就舍不得卸载
推荐3款让你偷懒,让你上头的提效电脑软件,个个功能强大,让你远离加班! 很多几个小时才能做好的事情,用上它们,只需要5分钟就行!! 1、JNPF快速开发平台 JNPF 是一款精巧耐用的软件…...

Java实现在线沟通功能
文章目录1、介绍 和 特点2、整合SpringBoot2.1、导入依赖2.2、websocket 配置类2.3、消息处理类2.4、启动服务2.5、前端代码:张三2.6、前端代码:李四3、效果4、小结1、介绍 和 特点 t-io是基于JVM的网络编程框架,和netty属同类,所…...

识别密文加密类型
离线密码破解:离线不会触发密码锁定机制不会产生大量登录失败日志引起管理员注意HASH识别工具(识别哈希类型):hash-identifierHashid yara规则匹配文件得到特定加密算法一、hash-identifierKali Linux提供工具hash-identifier来识…...

node报错
记录bug:运行 npx -p storybook/cli sb init 时报错gyp info spawn C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exegyp info spawn args [gyp info spawn args build/binding.sln,gyp info spawn args /nologo,gyp info spawn args…...

如何使用开源 BI 工具 DataEase 实现系列数据分析呢?
当我们使用可视化分析工具制作仪表板时,可能需要制作的仪表板不是单个单个的可视化大屏,而是一系列的仪表板,我们需要用它来产生一个连续性的故事,那么这个时候我们该怎么办呢?例如说总分形式,我们需要一个…...

金仓数据库安装
一、麒麟操作系统安装金仓数据库 操作系统 DISTRIB_IDKylin DISTRIB_RELEASEV10 DISTRIB_CODENAMEjuniper 按照安装文档的步骤安装,记得记住设置的数据库的用户名、密码 二、window安装连接数据库的工具软件 三、jdbc连接数据库 (1)连接工…...

深入浅出Webpack2-快速掌握webpack基本配置
深入浅出Webpack2-快速掌握webpack基本配置1.Entry1.1 context1.2 Entry类型2.Output2.1 filename2.2 path3.Module3.1配置Loader4.Resolve4.1 alias4.2 extensions4.3 modules5.Plugin6.DevServer7.其他配置项上一篇文章我们快速上手认识了一下webpack,今天这篇文章…...

如何使评论具有可操作性?取悦客户的指南
永远不要低估承认的力量。 当品牌与客户互动时,认可会带来更好的关系和更好的沟通。与买家和客户建立更多的个人联系意味着品牌需要证明他们支持他们的产品和客户。评论是利用客户分享他们的故事的那些时刻的绝佳机会。 为什么评论在 SaaS 中至关重要 在 B2B 软件的…...