工作流引擎-16-开源审批流项目之 整合Flowable官方的Rest包

article/2025/7/4 5:03:16

工作流引擎系列

工作流引擎-00-流程引擎概览

工作流引擎-01-Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎,支持现实世界的流程自动化需求

工作流引擎-02-BPM OA ERP 区别和联系

工作流引擎-03-聊一聊流程引擎

工作流引擎-04-流程引擎 activiti 优秀开源项目

工作流引擎-05-流程引擎 Camunda 8 协调跨人、系统和设备的复杂业务流程

工作流引擎-06-流程引擎 Flowable、Activiti 与 Camunda 全维度对比分析

工作流引擎-07-流程引擎 flowable-engine 入门介绍

工作流引擎-08-流程引擎 flowable-engine 优秀开源项目

工作流引擎-09-XState 是一个 JavaScript 和 TypeScript 的状态管理库,它使用状态机和状态图来建模逻辑

工作流引擎-10-什么是 BPM?

工作流引擎-11-开源 BPM 项目 jbpm

工作流引擎-12-开源 BPM 项目 foxbpm

工作流引擎-13-开源 BPM 项目 UFLO2

工作流引擎-14-开源审批流项目之 RuoYi-vue + flowable 6.7.2 的工作流管理

工作流引擎-15-开源审批流项目之 RuoYi-Vue-Plus 进行二次开发扩展Flowable工作流功能

工作流引擎-16-开源审批流项目之 整合Flowable官方的Rest包

工作流引擎-17-开源审批流项目之 flowable workflow designer based on vue and bpmn.io

工作流引擎-18-开源审批流项目之 plumdo-work 工作流,表单,报表结合的多模块系统

flowable-ui

经过两周左右时间的学习,Flowable基础知识自认为学习完毕,简单构思设计之后,开始上手实践了。

由于Flowable官方已经提供了丰富的REST包(和Activiti差不多),基本功能已经满足我们的要求了,个别接口不适用的可自行重写稍作调整即可。

Flowable官方提供的五个war包

starter描述在线体验
flowable-modeler让具有建模权限的用户可以创建流程模型、表单、选择表与应用定义。https://t.cn/A6cjNwAj
flowable-idm身份管理应用。为所有Flowable UI应用提供单点登录认证功能,并且为拥有IDM管理员权限的用户提供了管理用户、组与权限的功能。https://t.cn/A6cjCFHc
flowable-task运行时任务应用。提供了启动流程实例、编辑任务表单、完成任务,以及查询流程实例与任务的功能。https://t.cn/A6cjNLWv
flowable-admin管理应用。让具有管理员权限的用户可以查询BPMN、DMN、Form及Content引擎,并提供了许多选项用于修改流程实例、任务、作业等。管理应用通过REST API连接至引擎,并与Flowable Task应用及Flowable REST应用一同部署。https://t.cn/A6cjN4uq
flowable-restFlowable页面包含的常用REST API

在线体验账号:admin/123 (个人服务器,配置较低,仅供体验,请勿对应用进行压测)

先访问idm,使用体验账号登录后,再去访问modeler,task,admin其他模块

以官方提供的war包为基准,集成以上四个默认页面对应的REST接口。

开始集成

后端集成
  • maven
<dependency><groupId>org.flowable</groupId><artifactId>flowable-spring-boot-starter-rest</artifactId><version>${flowable.version}</version>
</dependency>
<!-- flowable UI集成 -->
<dependency><groupId>org.flowable</groupId><artifactId>flowable-ui-modeler-conf</artifactId><version>${flowable.version}</version>
</dependency>
<dependency><groupId>org.flowable</groupId><artifactId>flowable-ui-task-conf</artifactId><version>${flowable.version}</version>
</dependency>
<dependency><groupId>org.flowable</groupId><artifactId>flowable-ui-admin-conf</artifactId><version>${flowable.version}</version>
</dependency>
<dependency><groupId>org.flowable</groupId><artifactId>flowable-ui-idm-conf</artifactId><version>${flowable.version}</version>
</dependency>
  • gradle
compile group: 'org.flowable', name: 'flowable-spring-boot-starter-rest', version:'6.4.1'
compile group: 'org.flowable', name: 'flowable-ui-modeler-conf', version:'6.4.1'
compile group: 'org.flowable', name: 'flowable-ui-task-conf', version:'6.4.1'
compile group: 'org.flowable', name: 'flowable-ui-admin-conf', version:'6.4.1'
compile group: 'org.flowable', name: 'flowable-ui-idm-conf', version:'6.4.1'

注:

flowable-ui-xxx-conf: UI独立于业务外的配置
flowable-ui-xxx-logic: UI的业务逻辑
flowable-ui-xxx-rest: 提供常用的操作REST API

以上就是集成Flowable UI的基础包了。

由于flowable-ui-xxx-conf中包中,每个中都有对应自己的如ApplicationConfiguration等配置类,所以如果用默认配置会出现

conflicts with existing, non-compatible bean definition of same name and class

类似的错误信息,提示在Spring容器中存在两个相同名称的Bean。

所以不能使用默认的配置类,只能自己去编写配置类,完成flowable-ui-xxx-conf的配置。

  • AppDispatcherServletConfiguration
@Configuration
@ComponentScan(value = {"org.flowable.ui.admin.rest","org.flowable.ui.task.rest.runtime","org.flowable.ui.idm.rest.app","org.flowable.ui.common.rest.exception","org.flowable.ui.modeler.rest.app","org.flowable.ui.common.rest"},excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = RemoteAccountResource.class),@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = StencilSetResource.class),@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = EditorUsersResource.class),@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = EditorGroupsResource.class)})
@EnableAsync
public class AppDispatcherServletConfiguration implements WebMvcRegistrations
// 下面类内容省略,可参考org.flowable.ui.xxx.servlet.AppDispatcherServletConfiguration类

注: 通过StencilSetResource类汉化流程设计器(其实没必要重写类,只需要将stencilset_bpmn.json文件内容汉化即可,重写的目的是以后可以通过此处兼容国际化)

  • ApplicationConfiguration
@Configuration
@EnableConfigurationProperties({FlowableIdmAppProperties.class, FlowableModelerAppProperties.class, FlowableAdminAppProperties.class})
@ComponentScan(basePackages = {"org.flowable.ui.admin.repository","org.flowable.ui.admin.service","org.flowable.ui.task.model.component","org.flowable.ui.task.service.runtime","org.flowable.ui.task.service.debugger","org.flowable.ui.idm.conf","org.flowable.ui.idm.security","org.flowable.ui.idm.service","org.flowable.ui.modeler.repository","org.flowable.ui.modeler.service","org.flowable.ui.common.filter","org.flowable.ui.common.service","org.flowable.ui.common.repository","org.flowable.ui.common.security","org.flowable.ui.common.tenant"},excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = org.flowable.ui.idm.conf.ApplicationConfiguration.class)}
)

注: 通过@ComponentScan注解,扫描需要的包及其接口。

  • DatabaseConfiguration
/*** 重写flowable-ui-xxx-conf 中的 DatabaseConfiguration 类,* 包括:flowable-ui-modeler-conf和flowable-ui-admin-conf 的DatabaseConfiguration*/
@Configuration
@EnableTransactionManagement
public class DatabaseConfiguration {private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseConfiguration.class);@Beanpublic Liquibase modelerLiquibase(DataSource dataSource) {Liquibase liquibase = null;try {DatabaseConnection connection = new JdbcConnection(dataSource.getConnection());Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);database.setDatabaseChangeLogTableName("ACT_DE_" + database.getDatabaseChangeLogTableName());database.setDatabaseChangeLogLockTableName("ACT_DE_" + database.getDatabaseChangeLogLockTableName());liquibase = new Liquibase("META-INF/liquibase/flowable-modeler-app-db-changelog.xml", new ClassLoaderResourceAccessor(), database);liquibase.update("flowable");return liquibase;} catch (Exception e) {throw new InternalServerErrorException("Error creating liquibase database", e);} finally {closeDatabase(liquibase);}}@Beanpublic Liquibase adminLiquibase(DataSource dataSource) {LOGGER.debug("Configuring Liquibase");Liquibase liquibase = null;try {DatabaseConnection connection = new JdbcConnection(dataSource.getConnection());Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);database.setDatabaseChangeLogTableName("ACT_ADM_" + database.getDatabaseChangeLogTableName());database.setDatabaseChangeLogLockTableName("ACT_ADM_" + database.getDatabaseChangeLogLockTableName());liquibase = new Liquibase("META-INF/liquibase/flowable-admin-app-db-changelog.xml", new ClassLoaderResourceAccessor(), database);liquibase.update("flowable");return liquibase;} catch (Exception e) {throw new InternalServerErrorException("Error creating liquibase database");} finally {closeDatabase(liquibase);}}private void closeDatabase(Liquibase liquibase) {if (liquibase != null) {Database database = liquibase.getDatabase();if (database != null) {try {database.close();} catch (DatabaseException e) {LOGGER.warn("Error closing database", e);}}}}
}

注: 创建Modeler的模型存储表和Admin首页的服务配置表。

  • TaskUserCacheImpl
/*** 重写 {@link org.flowable.ui.task.service.idm.UserCacheImpl} 类,避免启动时和 {@link org.flowable.ui.idm.service.UserCacheImpl} 命名冲突* Cache containing User objects to prevent too much DB-traffic (users exist separately from the Flowable tables, they need to be fetched afterward one by one to join with those entities).* <p>** @author Frederik Heremans* @author Joram Barrez* @author Filip Hrisafov*/
@Service
public class TaskUserCacheImpl implements UserCache 

注: 重写 {@link org.flowable.ui.task.service.idm.UserCacheImpl} 类,避免启动时和 {@link org.flowable.ui.idm.service.UserCacheImpl} 命名冲突

  • org.flowable.ui.admin.service.engine.CmmnTaskService
package org.flowable.ui.admin.service.engine;
/*** 覆盖jar包中的CmmnTaskService的定义,修改Bean的定义名称,避免和org.flowable.cmmn.api.CmmnTaskService命名冲突* Service for invoking Flowable REST services.*/
@Service("adminCmmnTaskService")
public class CmmnTaskService 

由于flowable官方提供的jar包导致的冲突问题解决完毕之后,以下是application.yml中需要对Flowable做的配置,其他如数据源相关配置省略,此处不再累述。

flowable:labelFontName: 宋体activityFontName: 宋体annotationFontName: 宋体rest:app:authentication-mode: verify-privilegeprocess:definition-cache-limit: 1idm:app:admin:password: testuser-id: adminfirst-name: adminlast-name: admincommon:app:role-prefix:idm-url: http://localhost:${server.port}/${spring.application.name}/idmxml:encoding: UTF-8modeler:app:rest-enabled: trueadmin:app:security:encryption:credentials-secret-spec: 9FGl73ngxcOoJvmLcredentials-i-v-spec: j8kdO2hejA9lKmm6server-config:app:context-root: ${spring.application.name}password: testserver-address: http://localhostuser-name: adminport: ${server.port}rest-root: app-apiname: Flowable App appdescription: Flowable App REST configprocess:context-root: ${spring.application.name}server-address: http://localhostpassword: testuser-name: adminrest-root: process-apiport: ${server.port}name: Flowable Process appdescription: Flowable Process REST configform:context-root: ${spring.application.name}server-address: http://localhostpassword: testuser-name: adminport: ${server.port}rest-root: form-apiname: Flowable Form appdescription: Flowable Form REST configdmn:context-root: ${spring.application.name}server-address: http://localhostpassword: testuser-name: adminport: ${server.port}rest-root: dmn-apiname: Flowable DMN appdescription: Flowable DMN REST configcmmn:context-root: ${spring.application.name}password: testserver-address: http://localhostuser-name: adminport: ${server.port}rest-root: cmmn-apiname: Flowable CMMN appdescription: Flowable CMMN REST configcontent:context-root: ${spring.application.name}server-address: http://localhostpassword: testuser-name: adminrest-root: content-apiport: ${server.port}name: Flowable Content appdescription: Flowable Content REST configdatabase-schema-update: true
management:endpoint:health:roles: access-adminshow-details: when_authorizedendpoints:jmx:unique-names: true
# MyBatis配置比较重要,手动去扫描Flowable默认的Mapper.xml,以及设置字段类型
mybatis:mapper-locations:- classpath:/META-INF/admin-mybatis-mappings/*.xml- classpath:/META-INF/modeler-mybatis-mappings/*.xmlconfiguration-properties:prefix:boolValue: TRUEblobType: BLOB

至此后端集成完毕。

集成思路出现偏差

一开始准备将官方提供的页面集成到后端工程来,但是由于modeler页面我是直接放到static目录下的,而其他三个页面只能自己建目录存放(idm, admin, task),导致访问modeler时是以后端项目请求路径为根访问路径的,在modeler请求后端接口时,请求路径没有问题;可访问idm、admin、task时,则必须加上idm/路径,导致请求后端接口时,不管将前端请求后端的路径改为相对路径还是绝对路径,最终请求路径都存在问题。此处花费时间较多。下面会讲讲新的页面集成方式。

Flowable与SpringBoot版本坑

flowable-ui-modeler-confAppDispatcherServletConfiguration配置类,实现了WebMvcRegistrations接口,SpringBoot1.x中,WebMvcRegistrations在spring-boot-autoconfigure中的web包下,而在SpringBoot2.x中,WebMvcRegistrations被移到web.servlet下了,所以在使用默认类时,SpringBoot版本必须是2.x。

Flowable官方包冲突

由于是根据flowable-modeler、flowable-idm、flowable-task、flowable-admin来集成的,所以后端基础包也是需要这对应的四个,故直接集成了flowable-ui-modeler-conf、flowable-ui-idm-conf、flowable-ui-task-conf、flowable-ui-admin-conf,但是由于这四个包中存在各自的自动配置类,而且在modeler和admin中,自动配置类又和他自己的业务逻辑有关联,而且存在多个类命名相同的Spring Bean,导致Spring上下文由于出现相同名称的Bean而初始化失败,但是默认配置有些又不能不用,最终的解决办法就是去除原来所有的默认配置,将冲突的通过@ComponentScan的excludeFilters属性移除掉,然后自己去自定义配置。

登录权限问题

flowable-ui-modeler-conf、flowable-ui-idm-conf、flowable-ui-task-conf、flowable-ui-admin-conf这四个包中都存在SecurityConfiguration配置类,顾名思义是安全配置,但是在集成的过程中,modeler-conf其实我们希望的是以idm的登录为主,其他模块自己的安全校验配置不需要,但是实际上由于其他模块存在安全配置以及默认的拦截器,导致idm自己的安全验证不能通过。解决方式和上面一样,通过包扫描路径,只扫描自己需要的包路径,而有影响的包要么移除掉,要么自己去实现其中的配置。

页面集成

页面集成一开始采用的是集成到后端工程,以后开发自己的页面时,也可直接调用集成好的流程设计器,但是由于其他模块的页面存在问题,故暂时放弃掉这种集成方式,采用Nginx来部署前端,正好满足前后端分离架构。

  • Nginx配置
server {listen 8081;server_name flowable_ui;location / {root /user/local/nginx/flowable-ui;index index.html index.htm;}location /flowable_idm {proxy_pass http://localhost:8080/flowable;proxy_cookie_path  /flowable  /flowable_idm;}location /flowable_task {proxy_pass http://localhost:8080/flowable;proxy_cookie_path  /flowable  /flowable_task;}location /flowable_admin {proxy_pass http://localhost:8080/flowable;proxy_cookie_path  /flowable  /flowable_admin;}location /flowable_modeler {proxy_pass http://localhost:8080/flowable;proxy_cookie_path  /flowable  /flowable_modeler;}
}

注: 其实可以通过Nginx将静态资源和动态资源分开解析处理即可,但是我这边尝试的过程中有问题,只能采用简单粗暴的方式了。

然后在flowable-ui目录下新建modeler、idm、task、admin目录,将flowable-modeler.war、flowable-idm.war、flowable-task.war、flowable-admin.war中的flowable-xxx/WEB-INF/classes/static下的内容分别复制到对应目录下,此时通过http://localhost:8086/modeler…可看到对应的页面,但是由于动静资源路径一致,导致请求不能转发到后端,所以需要对动态请求和静态资源请求做区分,则需要修改官方页面源码,增加统一的请求路径前缀。

flowable-ui

统一请求路径修改:

在modeler/scripts/app-cfg.js文件中,修改contextRoot为flowable_modeler,与静态资源访问路径区分开。

'use strict';
var FLOWABLE = FLOWABLE || {};
var pathname = window.location.pathname.replace(/^(\/[^\/]*)(\/.*)?$/, '$1').replace(/\/$/, '');
FLOWABLE.CONFIG = {'onPremise' : true,'contextRoot' : "/flowable_modeler",'webContextRoot' : pathname,'datesLocalization' : false
};

在idm/scripts/app-cfg.js文件中,修改contextRoot为flowable_idm,与静态资源访问路径区分开。

'use strict';
var FLOWABLE = FLOWABLE || {};
var pathname = window.location.pathname.replace(/^(\/[^\/]*)(\/.*)?$/, '$1').replace(/\/$/, '');
FLOWABLE.CONFIG = {'onPremise' : true,'contextRoot' : "/flowable_idm",'webContextRoot' : pathname,'datesLocalization' : false
};

在task/scripts/app-cfg.js文件中,修改contextRoot为flowable_task,与静态资源访问路径区分开。

'use strict';
var FLOWABLE = FLOWABLE || {};
var pathname = window.location.pathname.replace(/^(\/[^\/]*)(\/.*)?$/, '$1').replace(/\/$/, '');
FLOWABLE.CONFIG = {'onPremise' : true,'contextRoot' : "/flowable_task",'webContextRoot' : pathname,'datesLocalization' : false
};

admin和其他的不一样,所以我作为一个后端人员修改前端,采取的方式是在admin/scripts/config.js文件中,增加上面类似配置。

FlowableAdmin.webContextRoot = '/flowable_admin';

然后通过开发工具,给所有的REST请求的增加FlowableAdmin.webContextRoot + 前缀。

如:

url: '/app/

替换为

url: FlowableAdmin.webContextRoot + '/app/

其他非这种格式的URL,可自行手动修改。

至此前后端基本集成完毕。

执行后端SpringBoot启动类,启动后端服务。

启动Nginx。

此时通过以下四个链接,即可访问Flowable官方提供的四个操作页面,不过在第一次访问时,由于没有登录,会跳转到登录页面,在后端工程初次启动时,会初始化两个账号,可通过ACT_ID_USER表查询用户名密码。

http://localhost:8081/idm/


http://www.hkcw.cn/article/xeAAJfwrRX.shtml

相关文章

Windows+VSCode搭建小智(xiaozhi)开发环境

作为一名DIY达人&#xff0c;肯定不会错过最近很火的“小智AI聊天机器人”&#xff0c;网上教程非常丰富&#xff0c;初级玩家可以直接在乐鑫官方下载ESP-IDF安装包并经过简单的菜单式配置后&#xff0c;即可进行代码编译和烧录&#xff08;详见&#xff1a;Docs&#xff09;。…

《仿盒马》app开发技术分享-- 购物车业务逻辑完善(端云一体)

开发准备 之前我们已经实现了购物车相关的内容&#xff0c;实现了购物车数据列表的展示&#xff0c;但是我们结算订单之后我们的购物车列表并没有刷新&#xff0c;而且底部的状态栏并没有明显的数据展示来提醒用户&#xff0c;而且当我们在商品详情页添加新商品&#xff0c;底…

谷歌CEO皮查伊眼中的“下一代平台“与未来图景

目录 前言 一、从"能力秀"到"平台重构"&#xff1a;AI的"第二乐章" 二、"万物皆可创"&#xff1a;AI如何引爆每个人的创造力&#xff1f; 三、AI走出屏幕&#xff1a;XR眼镜与机器人的未来交响曲 四、Web不死&#xff0c;只是换了…

DDC Learning Record(2)

这些是 “UV 生成策略”&#xff0c;决定了 Houdini 如何分析模型空间&#xff0c;并分配 UV 坐标。它们只影响 UV 坐标的生成方式&#xff0c;不影响后续贴图的读取行为。 face得到的结果是&#xff1a; 每个面都被映射到了整张贴图&#xff08;[0,1]&#xff09;&#xff0c;…

MySQL数据库从0到1

目录 数据库概述 基本命令 查询命令 函数 表的操作 增删改数据和表结构 约束 事务 索引 视图 触发器 存储过程和函数 三范式 数据库概述 SQL语句的分类&#xff1a; DQL&#xff1a;查询语句&#xff0c;凡是select语句都是DQL。 DML&#xff1a;insert,delete,up…

STM32CubeDAC及DMA配置

STM32CubeDAC及DMA配置 一&#xff0c;问题1二&#xff0c;解决11&#xff0c;宏观思路CubeMX配置2&#xff0c;HAL_TIM_Base_Start(&htim6) 的作用1&#xff0c;作用1&#xff1a;使能TIM6的时钟并让它开始计数2&#xff0c;作用2&#xff1a;当 TIM6 溢出时&#xff0c;会…

c++ 赋值函数和拷贝构造函数的调用时机

测试代码&#xff1a; void testcopyAndFuzhi() {class Dog {private:string name;public:Dog(string myname) : name(myname) {}Dog(Dog& otherDog) {std::cout << "调用拷贝构造函数." << endl;this->name otherDog.name;}Dog& operator …

Python列表、字典、元组、集合

列表 list 基本格式&#xff1a;列表名 [元素1,元素2,元素3] 所有元素放在[ ]之中&#xff0c;元素之间用逗号","隔开&#xff0c;元素可以是不同的类型 列表的类型也是列表 li [1,"hello",2] print(type(li)) 列表是可迭代对象&#xff0c;可以用fo…

sctpscan:用于发现 SCTP 网络扫描器!全参数详细教程!Kali Linux教程!

简介 用于发现和安全的 SCTP 网络扫描器 sctpscan 是一款 SCTP 协议端口扫描工具&#xff0c;主要用于识别目标主机上开放的 SCTP&#xff08;Stream Control Transmission Protocol&#xff09;服务端口。 sctpscan 的主要功能是&#xff1a; 探测目标主机 SCTP 协议是否开…

力扣题解654:最大二叉树

一、题目内容 题目要求根据一个不重复的整数数组 nums 构建最大二叉树。最大二叉树的构建规则如下&#xff1a; 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值左边的子数组前缀上构建左子树。递归地在最大值右边的子数组后缀上构建右子树。返回由 nums 构…

车载诊断架构 --- DTC消抖参数(Trip Counter DTCConfirmLimit )

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

75.解决当编辑完用户消息,确认重新生成AI回答时,已有的AI回答还是存在,并且新生成的回答并没有显示到气泡里bug

在上一个bug解决完后&#xff0c;又出来一个bug&#xff0c;我真是服了哈哈哈 新的bug是&#xff1a; 当编辑完用户消息&#xff0c;确认重新生成AI回答时&#xff0c;已有的AI回答还是存在&#xff0c;并且新生成的回答并没有显示到气泡里 出现这个bug的原因还是出现在rege…

C# 用户控件(User Control)详解:创建、使用与最佳实践

在C#应用程序开发中&#xff0c;用户控件&#xff08;User Control&#xff09;是一种强大的工具&#xff0c;它允许开发者将多个标准控件组合成一个可复用的自定义组件。无论是Windows Forms还是WPF&#xff0c;用户控件都能显著提高UI开发的效率&#xff0c;减少重复代码&…

SpringBoot-配置Spring MVC

一、Spring MVC回顾 Spring MVC是一种常用的Java Web框架&#xff0c;它提供了一种基于MVC模式的开发方式&#xff0c;可以方便地实现Web应用程序。在Spring MVC中&#xff0c;WebMvcConfigurer是一种常用的配置方式&#xff0c;可以允许我们自定义Spring MVC的行为&#xff0c…

Python训练营打卡 Day26

知识点回顾&#xff1a; 函数的定义变量作用域&#xff1a;局部变量和全局变量函数的参数类型&#xff1a;位置参数、默认参数、不定参数传递参数的手段&#xff1a;关键词参数传递参数的顺序&#xff1a;同时出现三种参数类型时 ——————————————————————…

【Delphi】接收windows文件夹中文件拖拽

本文根据EmailX45的视频文件&#xff0c;进行了优化改进&#xff0c;原文参见&#xff1a;Delphi: Drag and Drop Files from Explorer into TPanel / TMemo - YouTube 在Windows中&#xff0c;如果将选择的文件拖动到Delphi程序的控件上&#xff0c;有很多实现方法&#xff0c…

电脑的ip地址会自动变怎么办?原因解析和解决方法

在当今互联网时代&#xff0c;IP地址是每台联网设备的"身份证"&#xff0c;但很多用户都遇到过IP地址自动变化的情况。这种现象既可能发生在内网&#xff08;局域网&#xff09;环境中&#xff0c;也可能出现在外网&#xff08;公网&#xff09;连接中。要理解IP地址…

CppCon 2014 学习: C++11 in the Wild

介绍了三个现代 C 的实用工具或功能。下面是对每部分的解释和总结&#xff1a; 1. Auto() 宏 用途&#xff1a;在作用域结束时自动执行清理代码&#xff0c;类似于 RAII 的机制。功能&#xff1a;你可以定义一段代码&#xff0c;在作用域结束时自动执行&#xff08;不需要手动…

三大模块曝光:分钟级搭建专属平台,解锁算力灵活操控新体验,重新定义智能开发效率天花板

一. 蓝耘元生代 MaaS介绍及简单使用 背景介绍 创新产品定位&#xff1a; 蓝耘元生代 MaaS 平台于 2024 年 11 月 28 日推出&#xff0c;非传统智算平台&#xff0c;以资源聚合能力整合上下游资源&#xff0c;为用户提供优质全面服务。 核心模块功能&#xff1a; 集成智算算…

乾坤qiankun的使用

vue2 为主应用 react 为子应用 在项目中安装乾坤 yarn add qiankun # 或者 npm i qiankun -Svue主应用 在main.js中新增 &#xff08;需要注意的是路由模型为history模式&#xff09; registerMicroApps([{name: reactApp,entry: //localhost:3011,container: #container,/…