java-activiti笔记
版本:activiti7
<dependency><groupId>org.activiti</groupId><artifactId>activiti-json-converter</artifactId><version>7.0.0.Beta2</version><exclusions><exclusion><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></exclusion></exclusions></dependency><!--activiti与springboot整合包--><dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter</artifactId><version>7.0.0.Beta2</version><exclusions><exclusion><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></exclusion></exclusions></dependency>
发布
流程图
会签
这里是将流程图通过bpmn.io插件设计好流程图,存放到服务器端
public AjaxResult publishBpm(BpmFormVo bpmFormVo) {FileInputStream bpmnfileInputStream = null;try{BpmForm byId = getById(bpmFormVo.getId());xml=BpmFormManager.xmlnsActivitiEmpty(xml);xml=BpmFormManager.gatewaySupply(xml);activitiFlowService.delFlowByDefKey(bpmFormVo.getCode());repositoryService.createDeployment().addString(code+ ProcessConstants.SUFFIX, xml).name(code).key(code).deploy();bpmFormVo.setPublishTime(new Date());bpmFormVo.setState(1);bpmFormMapper.publishBpm(bpmFormVo);if("1".equals(byId.getCountersignature())){bpmCountersignService.bpmPublishHandle(byId,xml);}}catch (Exception e){e.printStackTrace();return AjaxResult.error("部署失败");}finally {try {if(bpmnfileInputStream!=null){bpmnfileInputStream.close();}}catch (Exception e){e.printStackTrace();}}return AjaxResult.success("部署成功");}
重新发布需要做如下处理
@SneakyThrowspublic void delFlowByDefKey(String code) {List<String> deploymentIdByName = activitiFlowMapper.getDeploymentIdByName(code+ ProcessConstants.SUFFIX);if(CollUtil.isEmpty(deploymentIdByName)){return;}for(String did:deploymentIdByName){repositoryService.deleteDeployment(did);}}
启动
@Overridepublic ProcessInstance startProcess(String definitionKey, String bussinessId,String userId,String userName, String projectId) {String bpmCode=definitionKey;Authentication.setAuthenticatedUserId(userId);Map<String, Object> map=new HashMap<>();map.put("state",ProcessConstants.AUDIT_YES);map.put("assignee",userId);ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(definitionKey, bussinessId, map);Task task = taskService.createTaskQuery().processDefinitionKey(definitionKey).taskAssignee(userId) //设置任务的负责人.orderByTaskCreateTime().desc().list().get(0);if (task!=null){taskService.addComment(task.getId(), task.getProcessInstanceId(), "流程提交","流程提交成功!");startTaskComplete(bpmCode,projectId,task.getId(),null);}startLogProcessHandle(bpmCode,definitionKey,bussinessId,projectId,userId,userName,processInstance,task);return processInstance;}
将会签中的占位的数据赋值
@Overridepublic void startTaskComplete(String bpmCode,String projectId,String taskId, Map<String, Object> variables) {BpmForm bpmForm = bpmFormService.queryInfoByCode(bpmCode, projectId);if(variables==null){variables=new HashMap<>();}if(bpmForm!=null&&"1".equals(bpmForm.getCountersignature())){//会签模式Object xmlByKey = activitiFlowMapper.getXmlByKey(bpmForm.getResCode() + ".bpmn");Map<String, List<String>> stringListMap = bpmUtil.collectionUseMap(bpmForm, (byte[]) xmlByKey);variables.putAll(stringListMap);}if(CollUtil.isEmpty(variables)){taskService.complete(taskId);}else{taskService.complete(taskId,variables);}}@SneakyThrowspublic Map<String,List<String>> collectionUseMap(BpmForm bpmForm,byte[] resByte){Map<String,List<String>> result=new HashMap<>();if("0".equals(bpmForm.getCountersignature())){return result;}String resStr = new String(resByte);BpmnModel bpmnModel = ModelUtil.getBpmnModel(resStr);Collection<UserTask> allUserTaskEvent = ModelUtil.getAllUserTaskEvent(bpmnModel);if(CollUtil.isEmpty(allUserTaskEvent)){return result;}SysRoleVo sysRoleVo=new SysRoleVo();sysRoleVo.setProjectId(bpmForm.getProjectId());List<SysRoleVo> sysRoleVos = sysRoleService.queryList(sysRoleVo);SysDept sysDept=new SysDept();sysDept.setProjectId(bpmForm.getProjectId());List<SysDept> sysDepts = sysDeptService.queryList(sysDept);for(UserTask userTask:allUserTaskEvent){if(userTask.hasMultiInstanceLoopCharacteristics()){MultiInstanceLoopCharacteristics loopCharacteristics = userTask.getLoopCharacteristics();String inputDataItem = loopCharacteristics.getInputDataItem();String coll = inputDataItem.replace("${", "").replace("}", "");String[] groups = coll.split("_");if("ROLE".equals(groups[0])){List<String> idListByRoleId = getIdListByRoleId(groups[1], sysRoleVos).getUserIdList();if(CollUtil.isNotEmpty(idListByRoleId)){result.put(coll,idListByRoleId);}}else if("DEPT".equals(groups[0])){List<String> idListByDeptId = getIdListByDeptId(groups[1], sysDepts).getUserIdList();if(CollUtil.isNotEmpty(idListByDeptId)){result.put(coll,idListByDeptId);}}}}return result;}
流程审批
@SneakyThrowspublic CompletResultVo orSignCompletHandle(String taskId, String result, String remark, String definitionKey, Map<String, Object> variables, String userName){Task task = taskService.createTaskQuery().taskId(taskId).singleResult();taskService.addComment(taskId, task.getProcessInstanceId(), result,remark);if(variables==null){variables=new HashMap<>();}variables.put("state",result);taskService.complete(taskId,variables);CompletResultVo completResultVo=new CompletResultVo();boolean afterHandle = afterHandle(task, userName, remark, result);completResultVo.setAuditEndState(afterHandle);return completResultVo;}boolean afterHandle(Task task,String userName,String remark,String result){//存储审核日志信息QueryWrapper queryWrapper=new QueryWrapper<>();queryWrapper.eq("process_instance_id",task.getProcessInstanceId());BussTask bussTask = bussTaskMapper.selectOne(queryWrapper);//日志记录
completByTaskLogHandle(bussTask,task,task.getProcessInstanceId(),userName,remark, result);//更新结束记录return endHandle(task.getProcessInstanceId(),bussTask,userName);}
判断流程结束后相关操作
boolean endHandle(String piid,BussTask bussTask,String userName){List<Task> task1 = taskService.createTaskQuery().processInstanceId(piid).list();bussTaskMapper.updateById(bussTask);if(CollUtil.isEmpty(task1)){bussTaskMapper.updateStatus(piid,ProcessConstants.AUDIT_NO);endLogHandle(bussTask);return true;}return false;}
会签审批
@SneakyThrowspublic CompletResultVo countersignCompletHandle(String taskId, String result, String remark,String definitionKey,String projectId,String userName,Long userId,BpmForm bpmForm){Task task = taskService.createTaskQuery().taskId(taskId).singleResult();String taskDefinitionKey = task.getTaskDefinitionKey();UserTask userTask = getUserTaskByNodeId(bpmForm.getResCode(), taskDefinitionKey);if(userTask==null){return orSignCompletHandle(taskId,result,remark,definitionKey,projectId,null,userName);}if(!userTask.hasMultiInstanceLoopCharacteristics()){return orSignCompletHandle(taskId,result,remark,definitionKey,projectId,null,userName);}MultiInstanceLoopCharacteristics loopCharacteristics = userTask.getLoopCharacteristics();String completionCondition = loopCharacteristics.getCompletionCondition();String codeByInfo = BpmCountersignTypeEnum.getCodeByInfo(completionCondition);Map<String,Object> variables=new HashMap<>();QueryWrapper queryWrapper=new QueryWrapper<>();queryWrapper.eq("process_instance_id",task.getProcessInstanceId());BussTask bussTask = bussTaskMapper.selectOne(queryWrapper);List<LogProcess> bussList = getLogs(bussTask.getBussId(), task.getProcessInstanceId());List<BpmCountersignRecord> bpmCountersignRecords=new ArrayList<>();if(CollUtil.isNotEmpty(bussList)){BpmCountersignRecord bpmCountersignRecord=new BpmCountersignRecord();bpmCountersignRecord.setExecutionId(bussList.get(0).getExecutionId());bpmCountersignRecords= bpmCountersignService.queryListByExeId(bpmCountersignRecord);}BpmCountersign bpmCountersignByTaskInfo = bpmCountersignService.getBpmCountersignByTaskInfo(task.getTaskDefinitionKey(), bussTask.getDefinitionKey());String[] user_split = bpmCountersignByTaskInfo.getUids().split(",");if("all".equals(codeByInfo)){if(ProcessConstants.AUDIT_NO.equals(result)){variables.put("pass",true);variables.put("state",ProcessConstants.AUDIT_NO);taskService.complete(taskId,variables);countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,false,true,bussList);}else{if(user_split.length<=(bpmCountersignRecords.size()+1)){variables.put("pass",true);variables.put("state",ProcessConstants.AUDIT_YES);taskService.complete(taskId,variables);countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,true,true,bussList);}else{variables.put("pass",false);taskService.complete(taskId,variables);countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,false,false,bussList);}}}else if("half".equals(codeByInfo)){if(user_split.length<=(bpmCountersignRecords.size()+1)){int ok_users=0;for(BpmCountersignRecord bpm:bpmCountersignRecords){if(ProcessConstants.AUDIT_YES.equals(bpm.getAuditResult())){ok_users+=1;}}if(ProcessConstants.AUDIT_YES.equals(result)){ok_users+=1;}String state=null;BigDecimal divide = new BigDecimal(ok_users).divide(new BigDecimal(user_split.length), 2, BigDecimal.ROUND_HALF_UP)double doubleValue = divide.doubleValue();if(doubleValue>=0.5){state=ProcessConstants.AUDIT_YES;}else{state=ProcessConstants.AUDIT_NO;}variables.put("state",state);variables.put("pass",true);taskService.complete(taskId,variables);countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,state.equals(ProcessConstants.AUDIT_YES)?true:false,true,bussList);}else{variables.put("pass",false);taskService.complete(taskId,variables);countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,false,false,bussList);}}else if("single".equals(codeByInfo)){if(ProcessConstants.AUDIT_YES.equals(result)) {variables.put("pass",true);variables.put("state",ProcessConstants.AUDIT_YES);taskService.complete(taskId,variables);countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,true,true,bussList);}else{if(user_split.length<=(bpmCountersignRecords.size()+1)){variables.put("pass",true);variables.put("state",ProcessConstants.AUDIT_NO);taskService.complete(taskId,variables);countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,false,true,bussList);}else{variables.put("pass",false);taskService.complete(taskId,variables);countersignRecordHandle(task,bpmForm,userName,userId,bpmCountersignByTaskInfo,result,remark,bussTask,false,false,bussList);}}}CompletResultVo completResultVo=new CompletResultVo();List<LogProcess> bussList2 = getLogs(bussTask.getBussId(), task.getProcessInstanceId());String aname="";if(CollUtil.isNotEmpty(bussList2)){aname=bussList2.get(0).getAssigneeName();}else{aname= bussList.get(0).getAssigneeName();}boolean endHandle = endHandle(task.getProcessInstanceId(), bussTask, aname);completResultVo.setAuditEndState(endHandle);return completResultVo;}//日志及操作记录/**** @param task* @param bpmForm* @param userName* @param userId* @param bpmCountersignByTaskInfo* @param result 当前人的审核状态* @param remark* @param auditState 最终审核状态(会签)* @param isEnd 当前节点是否全部完成*/void countersignRecordHandle(Task task,BpmForm bpmForm,String userName,Long userId,BpmCountersign bpmCountersignByTaskInfo,String result,String remark,BussTask bussTask,boolean auditState,boolean isEnd,List<LogProcess> bussList){LogProcess logRecord=null;if(CollUtil.isEmpty(bussList)){logRecord=new LogProcess();logRecord.setProjectId(bpmForm.getProjectId());String myExeId=UUID.randomUUID().toString();logRecord.setExecutionId(myExeId);logRecord.setBusinessId(bussTask.getBussId());logRecord.setTaskId(task.getId());logRecord.setAssigneeName(bpmCountersignByTaskInfo.getUnames());logRecord.setAssignee(bpmCountersignByTaskInfo.getUids());logRecord.setInstanceId(task.getProcessInstanceId());logRecord.setDefinitionKey(bpmForm.getResCode());if(isEnd){logRecord.setStepType(auditState?ActivitiStepType.approved.getCode():ActivitiStepType.reject.getCode());}else{logRecord.setStepType(ActivitiStepType.unapproved.getCode());}logProcessMapper.insert(logRecord);}else{if(isEnd){logRecord = bussList.get(0);logRecord.setStepType(auditState?ActivitiStepType.approved.getCode():ActivitiStepType.reject.getCode());logProcessMapper.updateById(logRecord);}}BpmCountersignRecord bcr=new BpmCountersignRecord();bcr.setNodeId(task.getTaskDefinitionKey());bcr.setBpmCode(bpmForm.getCode());bcr.setUserId(userId+"");bcr.setUserName(userName);if(logRecord!=null){bcr.setLogId(logRecord.getId());}else{bcr.setLogId(bussList.get(0).getId());}bcr.setBusinessId(bussTask.getBussId());bcr.setAuditRemark(remark);bcr.setAuditResult(result);bcr.setExecutionId(logRecord.getExecutionId());bcr.setProcessInstanceId(task.getProcessInstanceId());bpmCountersignRecordMapper.insert(bcr);}
会签流程表达式枚举,全部通过即通过,半数通过即通过,一人通过即通过:
public enum BpmCountersignTypeEnum {all("all", "${nrOfCompletedInstances==nrOfInstances||pass==true}"),half("half", "${nrOfCompletedInstances/nrOfInstances>=0.5&&pass==true}"),single("single", "${nrOfCompletedInstances>=1&&pass==true}");private final String code;private final String info;BpmCountersignTypeEnum(String code, String info){this.code = code;this.info = info;}public static String getCodeByInfo(String info){if(StringUtils.isBlank(info)){return null;}for(BpmCountersignTypeEnum bct:BpmCountersignTypeEnum.values()){String elEscape = EscapeUtil.elEscape(bct.info);if(info.equals(elEscape)){return bct.code;}}return null;}public String getCode(){return code;}public String getInfo(){return info;}
}
这里:
nrOfInstances:总实例数nrOfCompletedInstances:已完成实例数nrOfActiviteInstances:未完成的实例数
全部通过即通过和一人通过即通过直接处理即可,state是流线走向,按比例通过时,我这里用一张表记录了每次操作,即BpmCountersignRecord,将此次记录作为流程操作记录的子关联表,executionId作为关联键。
其他
每次流程启动表act_ge_bytearray中会出现如下图的数据,这就是会签流程里面的变量数据
当流程审批结束后,var-开头的数据就会消失,hist开头的是act_hi表中相关数据
相关文章:

java-activiti笔记
版本:activiti7 <dependency><groupId>org.activiti</groupId><artifactId>activiti-json-converter</artifactId><version>7.0.0.Beta2</version><exclusions><exclusion><groupId>org.mybatis</g…...

Layui——隐藏表单项后不再进行验证
目录 修改后的部分代码 修改后的完整代码 我编辑用户信息和添加新用户用的是同一个表单,不同的是编辑用户信息里没有密码项和确认密码项,但是把它们隐藏后仍然要进行验证,也就是说它们俩的验证并没有随着表单项的隐藏而关闭。原因…...

Github Copilot 使用技巧
🎯目标读者 本文不包含如何安装 Github Copilot本文介绍了 Github Copilot 使用方法和一些技巧 本人已经使用 Github Copilot 2 年了,交了 3 次年费,每年 100$ 着实心痛,但是用着确实爽歪歪 但是感觉一直只用了一小部分功能&am…...

【实现100个unity特效之20】用unity实现物品悬浮和发光像素粒子特效
最终效果 文章目录 最终效果新增飞升粒子效果光圈效果修改不同颜色完结 新增飞升粒子效果 效果 光圈效果 效果 修改不同颜色 完结 赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持…...

GPT-4o mini发布,轻量级大模型如何颠覆AI的未来?
从巨无霸到小巨人:GPT-4o Mini的创新之路 ©作者|潇潇 来源|神州问学 引言 随着人工智能技术的飞速进步,AI领域的竞争日益激烈,大型模型的发布几乎成为常态。然而,这些庞大的模型通常需要大量的计算资源和存储空间ÿ…...

高性能的 C++ Web 开发框架 CPPCMS + WebSocket 模拟实现聊天与文件传输案例。
1. 项目结构 2. config.json {"service": {"api": "http","port": 8080,"ip": "0.0.0.0"},"http": {"script": "","static": "/static"} }3. CMakeLists.txt…...

合合信息OCR支持30类国内常见票据一站式分类识别,支持医疗发票、数电票识别
合合信息TextIn平台明星产品——国内通用票据识别,重磅更新! 产品支持票据类型扩展到23大类、30小类,覆盖场景更全面,同时升级优化了多款票据识别模型,平均识别率较前版本提升11.5%,整体识别速度提升21.9%…...
LeetCode-day40-3151. 特殊数组 I
LeetCode-day40-3151. 特殊数组 I 题目描述示例示例1:示例2:示例3: 思路代码 题目描述 如果数组的每一对相邻元素都是两个奇偶性不同的数字,则该数组被认为是一个 特殊数组 。 Aging 有一个整数数组 nums。如果 nums 是一个 特殊…...

技术研究:Redis 数据结构与 I/O 模型
数据结构 Redis之所以“快”,一方面因为它是内存数据库,所有操作都在内存上完成,内存的访问速度本来就快。另一方面则是因为高效的数据结构,使得操作键值效率较高。总体来说,Redis使用了一个用来保存每个Key/Value的全…...

46-扇孔的处理及铺铜以及布线
1.先连信号线 2.电源管脚,以如下方式处理: 引线打孔处理...

LVS实验的三模式总结
文章目录 LVS的概念叙述NAT工作模式实战案例**思想:**NAT工作模式的优点NAT工作模式的缺点 NAT工作模式的应用场景大致配置 route:打开路由内核功能 部署DR模式集群案例工作思想:大致工作图如下思路模型 具体配置与事实步骤补充 防火墙标签解…...

游戏安全入门-扫雷分析远程线程注入
前言 无论学习什么,首先,我们应该有个目标,那么入门windows游戏安全,脑海中浮现出来的一个游戏 – 扫雷,一款家喻户晓的游戏,虽然已经被大家分析的不能再透了,但是我觉得自己去分析一下还是极好…...

bert-base-chinese模型的完整训练、推理和一些思考
前言 使用google-bert/bert-base-chinese模型进行中文文本分类任务,使用THUCNews中文数据集进行训练,训练完成后,可以导出模型,进行预测。 项目详细介绍和数据下载 数据集下载地址 Github完整代码 现记录训练过程中的一些感悟…...
JS基础5(JS的作用域和JS预解析)
JS的作用域 1. 全局作用域 全局作用域是在代码的任何地方都能访问到的最外层作用域。在浏览器环境下,全局作用域就是window对象,因此所有在全局作用域中声明的变量和函数都会成为window对象的属性和方法。 var globalVar "I am global"; …...
Doris 夺命 30 连问!(中)
导言 抱歉,作为从 S2 开始的骨灰级玩家看到 EDGUZI 官宣首发上线,兴奋之余忘了写文档 - -||,还望各位看官老爷见谅,这次错了,下次还敢 ^_^ 这是继上次的 30 问上篇的中篇,也是 10 个问题,有些…...

书生.浦江大模型实战训练营——(四)书生·浦语大模型全链路开源开放体系
最近在学习书生.浦江大模型实战训练营,所有课程都免费,以关卡的形式学习,也比较有意思,提供免费的算力实战,真的很不错(无广)!欢迎大家一起学习,打开LLM探索大门…...

SpringBoot 整合 RabbitMQ 实现延迟消息
一、业务场景说明 用于解决用户下单以后,订单超时如何取消订单的问题。 用户进行下单操作(会有锁定商品库存、使用优惠券、积分一系列的操作);生成订单,获取订单的id;获取到设置的订单超时时间࿰…...

Cilium:基于开源 eBPF 的网络、安全性和可观察性
基于 eBPF 的网络、安全性和可观察性 Cilium 是一种开源的云原生解决方案,它利用 Linux 内核中的 eBPF 技术来提供、保护和监控工作负载之间的网络连接。 什么是 eBPF? eBPF 是一项源自 Linux 内核的技术,允许沙盒程序在特权上下文&#x…...
Axios 详解与使用指南
Axios 详解与使用指南 1. Axios 简介 Axios 是一个基于 Promise 的 HTTP 客户端,能够在浏览器和 Node.js 环境中运行。它提供了一种简便的方式来执行 HTTP 请求,并支持多种请求方法,如 GET、POST、PUT、DELETE 等。Axios 的配置灵活&#x…...

深度学习 —— 个人学习笔记20(转置卷积、全卷积网络)
声明 本文章为个人学习使用,版面观感若有不适请谅解,文中知识仅代表个人观点,若出现错误,欢迎各位批评指正。 三十九、转置卷积 import torch from torch import nndef trans_conv(X, K):h, w K.shapeY torch.zeros((X.shape[…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...