首页 文章 精选 留言 我的

精选列表

搜索[子流程],共10000篇文章
优秀的个人博客,低调大师

bootx-platform v1.1.0-bate4-fix:认证流程优化

项目介绍 项目地址:https://gitee.com/bootx/bootx-platform 基于 Spring Boot 框架打造,针对单体式应用进行专门设计,提供整套服务模块,努力为打造全方位企业级开发解决方案, 致力将开源版打造成超越商业版后台管理框架的项目。 特色功能 针对敏感信息,可以通过注解配置实现返回时自动脱敏 针对重要信息,可以通过添加注解,实现在数据库中保密存储,配合数据脱敏使用可以更好的保护系统数据的安全 支持多种范围的数据权限控制,如只能查看自己、只能查询指定部门、用户、可以查询全部的数据等等 支持嵌套查询的超级查询构造器,自动生成对应条件 SQL 语句 异常时返回链路追踪 id,方便错误日志追踪 提供项目对应的代码生成器,方便开发 定制 Mybatis Plus 组件,更方便开发 支持多种消息中间件,MQTT、RabbitMQ、Redis 支持全局级 Websocket 集成,通过事件机制可以分发到指定页面 支持通过 ELK 和轻量级 PlumeLog 来管理项目日志,以适应不同的场景 提供移动端开发脚手架,方便开发 H5 与各种小程序 支持通过微信、钉钉、企业微信等第三方开放平台进行扫码登录 本次功能更新 bate4版本发布后发现认证终端这块设计有问题,秉持着有问题早解决的想法,把这一块进行了重构,同时修正了一些其他与登录认证相关的问题,特此发个版本 重构认证应用和认证终端重新设计为认证终端和登录方式 增加用户手机号/邮箱绑定功能 优化微信、钉钉、企业微信绑定时重复校验 优化@IgnoreAuth鉴权注解功能 fix: 开放平台登录报错问题 新功能截图 新认证终端 新登录方式 手机号/邮箱绑定

优秀的个人博客,低调大师

轻量级开源流程编排引擎

LiteFlow 2.6.2版本发布了!这个版本新增一个特性,重构了底层的parser代码。 如果你是第一次知道LiteFlow这款框架,可以移步以下链接进行了解: LiteFlow官网:https://yomahub.com/liteflow Gitee仓库托管主页:https://gitee.com/dromara/liteFlow Github仓库托管主页:https://github.com/dromara/liteflow 也可以看我之前发布的一篇介绍LiteFlow这个框架的文章 https://mp.weixin.qq.com/s/xyydmtk_a5R1zbg3EeORaw 本次更新点如下: 特性 #I4CRSY 增加了组件标签特性,支持在组件里获取自定义的标签组件 https://gitee.com/dromara/liteFlow/issues/I4CRSY

优秀的个人博客,低调大师

【JVM技术探索】全流程化分析Java对象的创建过程

前言概要 对应过程则是:对象创建、对象内存布局、对象访问定位的三个过程。 对象的创建过程 对象的创建方式 java中对象的创建方式有很多种,常见的是通过new关键字和反射这两种方式来创建。除此之外,还有clone、反序列化等方式创建。 通过new关键字创建 // Person zhangsan = new Person(id, height, weight) Person zhangsan = new Person(); 通过反射创建 反射创建对象,可以通过class.newInstance()调用无参的构造器创建对象,也可以使用构造器来创建constructor.newInstance()。 //Class clz = Class.forName("Person类的全限定类名") Class clz = Person.class; Person zhangsan = clz.newInstance() // 使用构造器创建 Constructor<Person> cons = clz.getConstructor() // 也可以指定参数类型获取有参构造器 Person zhangsan1 = cons.newInstance() 通过clone创建对象 当类实现了Cloneable接口时,可以使用clone()方法复制一个对象。需要留意是clone方法是浅拷贝。 Person libo = new Person(name: "李博", age:12, ...) Person Livonor = new Person(name: "Livorno", age:32, ...) libo.setFather(Livonor) Person zhangsi = libo.clone() // 此时,张四和张三的名字、父亲在内存中都引用了相同的对象 反序列化创建 通过读取IO数据流创建,非本节重点 对象的创建过程 检查类加载(包含是否初始化、是否被加载、是否被解析) 对于new和反射两种创建方式而言,需要检查创建对象所使用的参数是否已完成类加载(比如它的类型和参数类型)。如果没有,要先完成类加载过程。 分配内存空间 虚拟机为对象分配内存,即起始地址和偏移量。 对象所需要的空间在创建前就可以确定,但是起始地址需要在分配时去内存中找到一块足够大的空间。地址的分配有两种方式:指针碰撞和空闲列表。 指针碰撞 指针碰撞的方式是假设内存空间是规整的,被使用的和空闲的内存被分割成了两整块,通过一个指针记录分界点。在给对象分配内存的时候,将指针空闲区域移动一段与对象大小相等的距离即可。 空闲列表 如果内存不规整,那么就需要维护一张表,来记录内存中那些地址是空闲的。分配对象时,通过空闲列表去找到一块足够大的空闲内存分配给对象并更新空闲列表。 多个线程创建的对象内存的冲突 举个例子,线程1和2同时要创建两个对象,指针是同一个。它们各自将指针加载到了cpu缓存,然后去执行分配地址空间的指令。结果就导致,后分配的哪一个,可能将先分配的那个对象的地址给覆盖了。 解决的办法有两种,一种是对分配内存的动作进行同步处理,即采用CAS加失败重试的方式,保证更新操作的原子性。 // 伪代码表示CAS+失败重试 while(true){ oldPtr = ptr //读取共享指针 newPtr = oldPtr + sizeOfInstance if(compareAndSet(oldPtr, ptr, newPtr)){break} } 另一种是使用TLAB的方式将线程的分配空间在堆内存中隔离开,在堆中为每个线程预先分配一小块不同的空间,每个线程创建对象都在自己对应的空间中完成。 即每个线程在 Java堆中预先分配一小块内存(本地线程分配缓冲(Thread Local Allocation Buffer ,TLAB)),哪个线程要分配内存,就在哪个线程的TLAB上分配,只有TLAB用完并分配新的TLAB时才需要同步锁。虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB参数来设定。 分配完内存之后,对象就已经存在于虚拟机的堆中了,此时虚拟机要将分配的内存空间初始化为零值(对象头例外)。 设置对象头 对象头包含了两种信息:MarkWord和类型指针。 MarkWord:存放对象本身的运行时状态数据(如HashCode, GC分代年龄、锁状态、是否偏向信息等) KlassPointer:类型指针指向它的类型的元数据。对象头在对象的内存布局中细讲。 即对象指向它的类元数据的指针 虚拟机通过这个指针来确定这个对象是哪个类的实例 数据长度:如果对象 是 数组,那么在对象头中还必须有一块用于记录数组长度的数据 因为虚拟机可以通过普通Java对象的元数据信息确定对象的大小,但是从数组的元数据中却无法确定数组的大小。 执行对象实例构造函数 首先递归的执行父类的构造函数,然后收集本类中为实例变量赋值的语句并执行,最后执行构造方法中的语句。 public class AddA { public static void main(String[] args) { Father guy = new Son(30); guy.saySomething(); System.out.println(guy.age); } } class Father{ int age = 60; public Father() { saySomething(); } public Father(int age) { this.age = age; } public void saySomething(){ System.out.println("I am the father, " + age + "years old"); } } class Son extends Father{ int age = 20; public Son(int age) { // super(); 不写则隐式调用方法,写则必须在子类构造方法的第一句 saySomething(); this.age = age; saySomething(); } public void saySomething(){ System.out.println("I am the son, " + age + " years old"); } } 因为它涉及到了多态与方法的动态分派。在这里先简单描述一下它的执行过程,用来掌握构造方法的执行还是ok的。 首先,创建一个Son对象,然后调用其有参构造方法Son(int age)。 在有参构造方法中隐式调用了父类的无参构造方法,然后父类的构造方法继续调Object的构造方法。接下来收集为父类成员变量赋值的语句并执行。 由于多态中子类的成员变量会覆盖父类的成员变量,因此子类对象的age仍然是0。 同时无参构造方法中的saySomething()此时是被子类对象调用的,因此打印了第一句I am the son, 0 years old。 然后,super()方法出栈,回到子类构造方法中。此时应该收集为子类成员变量赋值的语句并执行。对象的age=20,saySomething()打印出第二句I am the son, 20 years old。 然后执行构造方法中的赋值语句int age = age;saySomething(); 第三句话被打印I am the son, 30 years old。 子类对象创建完成,回到main方法。此时使用多态,将对象转成Father对象。 由于多态的规则:被重写的方法使用动态分派,查找(vtable)方法表,该方法实际是属于子类对象的。 因此guy.saySomething()实际调用的是子类对象的方法,打印出第四句话,I am the son, 30 years old。 最后,输出guy.age. 成员变量不具备多态性,因此打印出父类对象的age 60. I am the son, 0 years oldI am the son, 20 years oldI am the son, 30 years oldI am the son, 30 years old 对象的内存布局 对象在堆中的存储布局划分为三个部分:对象头、实例数据和对其填充(padding)。 对象的内存布局 对象头 对象头中包含markword(标记字段)和类型指针【数组长度】。 markword markword存储与对象自身定义数据无关的信息,用来表示对象的运行时状态。包括了HashCode,GC年龄,锁状态等信息。在一个32位的虚拟机中,markword用一个32位的bitmap表示,bitmap最后两位存放锁状态信息,如下图。 markword 普通状态下,状态为01,存储hashcode,分代年龄,偏向锁状态为0。 偏向锁状态下,状态为01,存储持有偏向锁的线程和重入次数,分代年龄,偏向锁状态为1。此时hashcode没了,但是,hashcode可以通过Object的hashcode()方法计算出来,只要没有重写该方法,那么得到的哈希码始终是一致的。 轻量级锁,状态为00。通过cas方式将对象的markword信息原子性地交换到了持有该对象锁的线程中,存储在lockRecord内,并同时将lockRecord的指针存放在对象头Markword的前30位。 重量级锁状态下,前30位存放指向锁控制器Monitor的指针,锁状态为10. 对象被标记为待回收状态时,最后两位状态为11. KlassPointer(类型指针) 指向类型元数据,从而可以通过对象来访问到它的类型信息。 数组长度(array length) 主要记录数组的长度信息一般为4字节(根据int的范围来考虑) 实例数据 实例数据中存放了对象的字段信息。无论是从父类继承的,还是在子类中定义的,都保存在实例数据中。 按照一定顺序存放,在满足这个顺序的条件下,父类定义的字段又会出现在子类定义的变量之前。 即代码中定义的字段内容 注:这部分数据的存储顺序会受到虚拟机分配参数(FieldAllocationStyle)和字段在Java源码中定义顺序的影响。 // HotSpot虚拟机默认的分配策略如下: longs/doubles、ints、shorts/chars、bytes/booleans、oop(Ordinary Object Pointers) // 从分配策略中可以看出,相同宽度的字段总是被分配到一起 // 在满足这个前提的条件下,父类中定义的变量会出现在子类之前 CompactFields = true; // 如果 CompactFields 参数值为true,那么子类之中较窄的变量也可能会插入到父类变量的空隙之中。 对齐填充 如果对象的实例数据占用空间不是8的整数倍,则填充0值让对象的占用空间位8的整数倍。 对象的访问定位 常见的有两种方式,句柄访问和直接指针访问。 句柄访问 使用句柄访问的话,对象的引用(如zhangsan),指向的是句柄池中的某个句柄,该句柄存放了指向实际实例对象的指针和指向方法区数据类型的指针。 其好处是,当对象被移动的时候(比如垃圾回收时,整理内存空间需要大量移动对象),不需要频繁的修改引用,只需要修改句柄中实例数据指针。 通过指针访问,则是对象的引用直接指向了该对象。其好处是,通过引用访问对象时,不需要多一次的指针定位,使得访问速度更快。

优秀的个人博客,低调大师

阿里云ECS服务器入门使用流程 新手必看教程

一、阿里云根据个人需要选合适的云服务器,选好cpu、内存、带宽,地域,这四个是主要的。其他可以默认选择。选择服务器之前先领取代金券减少上云成本 二、登陆控制台 输入账号密码,进去看到服务界面,新手可能不容易看懂。点击左侧菜单,点击云服务器,显示界面如图: 点击实例,在左上角选择区域(一定要选对地域才能看到服务器),这时看到服务器信息了,如图: 大家不要看这里这么多信息,对我们有用的其实只有几个而已,别的都不用看。更多参阅云服务器配置帮助文档。 三、连接主机 1、通过控制台连接 阿里云服务器要用到两个密码,一个是远程登录密码,一个是实例密码,就是我们平常登录服务器的root密码(以linux服务器为例)。通过控制台连接服务器需要使用到这两个密码,如果不知道重置即可。注意:修改实例密码需要重启服务器才能生效。 点击远程连接,输入远程连接密码 输入root用户和密码(就是刚才改过的实例密码),开始对服务器进行操作。 登录成功后,可以输入各种命令。点击左侧按钮列表的断开连接,就能够断开与服务器的链接了。 2、通过工具连接 在云控制台的实例页面看到公网IP,通过工具软件连接服务器,和上面的作用一样,可以输入各种命令了。 三、开通安全组同样在实例最右侧点击【更多】>>【网络和安全组】>>【安全组配置】 点击配置规则 入方向看到的就是目前服务器的安全组规则了,你可以在这里添加、修改、删除规则。 比如要开放 80端口,按照下面的例子填写。这块挺重要的,规则添加不对了可能就无法正常访问了。更多参阅安全组帮助文档。 四、网站搭建 做网站的话可以搭配系统镜像使用,阿里云自带一键开通,方法如下图: 点击【确定,更换系统盘】,注意提前保存数据。点击【镜像市场】,从镜像市场选择 搜索【宝塔面板】,选择0/月的,注意看已使用人数,选择人数多的那个。 自定义密码,然后输入符合要求的密码。这里记住登陆名和密码,以后链接服务器都要用。也可以用密钥方式,这里不细说了。 接下来记住宝塔面板的登陆地址,账号密码。去登陆到宝塔面板中,开始建站之旅。记住如果宝塔面板无法登陆,那是因为安全组中没有添加面板的端口,按照上面的办法去添加就行了。更多参阅镜像市场帮助文档。

优秀的个人博客,低调大师

阿里云服务器怎么用APP来备案操作流程

阿里云APP端申请备案是现在比较流行的备案方法,方便快捷,适合新手使用。 阿里云2000券免费领取(阿里云券的作用:购买阿里云产品,最后支付结算的时候,阿里云券可抵扣一部分费用。 要注意的是,目前支持首次备案和新增网站(原备案不在阿里云)两种备案场景。暂时不支持新增网站(原备案在阿里云)、接入备案、变更备案等其他备案场景,其他的备案场景都可在PC端操作。 使用阿里云APP端申请备案时,备案申请操作步骤如下: 1、登录阿里云APP,进入APP备案操作入口。 如果在APP端备案时,系统提示前往PC端进行操作,那么你当前的场景就只能在PC端操作了。 2、填写信息及备案接入产品验证备案类型 填写主办单位信息和网站等信息,根据备案类型上传主办单位的证件材料,并进行真实性核验。 3、选择买好的服务器,进行产品验证。 阿里云2000券免费领取(阿里云券的作用:购买阿里云产品,最后支付结算的时候,阿里云券可抵扣一部分费用。 说明:如果无法选择服务器实例,可能是因为无可用备案服务号,建议更换有可用备案服务号的服务器。更多可能无法选择实例的可能原因及 系统会根据填写信息自动判定要办理的备案类型。 4、填写主体信息和网站信息 填写网站信息以及办理备案的个人或者单位的真实信息。上传主体负责人和网站负责人的证件,并进行网站负责人的真实性核验。 5、上传资料 上传证件照片或证件彩色扫描件。 6、信息核验 在提交备案申请订单前,请您在此步骤中仔细确认您的主体、网站、接入等备案信息是否正确,确认无误后提交备案订单。 说明:如果使用PC端进行备案申请,在移动端完成资料上传和真实性核验后,您可在移动端继续信息核验。如果您的登录账号无法登录阿里云APP,就要去PC端继续操作信息核验。 7、备案初审 提交备案申请后,阿里云备案审核专员会对备案信息初步审核。 8、管局审核初审完成后,阿里云备案审核专员会将备案申请转交至对应管局处做最终的管局审核。管局审核通过后您的备案即已完成,审核结果会发送至短信、邮箱。 9、不管阿里审核,还是管局审核期间,在工作时间内都要保持手机有人接听状态,老魏就是因为审核专员多次打电话无人接听,延误了备案时间。 阿里云2000券免费领取(阿里云券的作用:购买阿里云产品,最后支付结算的时候,阿里云券可抵扣一部分费用。

优秀的个人博客,低调大师

数据安全管理:RSA加密算法,签名验签流程详解

本文源码:GitHub·点这里 || GitEE·点这里 一、RSA算法简介 1、加密解密 RSA加密是一种非对称加密,在公开密钥加密和电子商业中RSA被广泛使用。可以在不直接传递密钥的情况下,完成加解密操作。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。 2、签名验签 数字签名就是信息的来源添加一段无法被伪造的加密字符串,这段数字串作为对信息的来源真实性的一个有效证明。这个过程称为签名和验签。 二、场景描述 消息发送方:甲方,持有公钥 消息接收方:乙方,持有私钥 1、加密解密过程 (1)、乙方生成一对密钥即公钥和私钥,私钥不公开,乙方自己持有,公钥为公开,甲方持有。 (2)、乙方收到甲方加密的消息,使用私钥对消息进行解密,获取明文。 2、签名验签过程 (1)、乙方收到消息后,需要回复甲方,用私钥对回复消息签名,并将消息明文和消息签名回复甲方。 (2)、甲方收到消息后,使用公钥进行验签,如果验签结果是正确的,则证明消息是乙方回复的。 三、源代码实现 1、密钥字符串获取 代码生成 private static HashMap<String, String> getTheKeys() { HashMap<String, String> keyPairMap = new HashMap<String, String>(); KeyPairGenerator keyPairGen = null; try { keyPairGen = KeyPairGenerator.getInstance("RSA"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } // 密钥大小:1024 位 keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); String publicKey = printBase64Binary(keyPair.getPublic().getEncoded()); String privateKey = printBase64Binary(keyPair.getPrivate().getEncoded()); keyPairMap.put("publicKey", publicKey); keyPairMap.put("privateKey", privateKey); return keyPairMap ; } 读取文件 文件位置 public static final String PUB_KEY = "rsaKey/public.key" ; public static final String PRI_KEY = "rsaKey/private.key" ; 文件加载 public static String getKey (String keyPlace) throws Exception { BufferedReader br= null; try { br= new BufferedReader(new InputStreamReader(RsaCryptUtil.class.getClassLoader(). getResourceAsStream(keyPlace))); String readLine= null; StringBuilder keyValue = new StringBuilder(); while((readLine= br.readLine())!=null){ if(!(readLine.charAt(0)=='-')){ keyValue.append(readLine); } } return keyValue.toString(); } catch (Exception e) { throw new Exception("RSA密钥读取错误",e) ; } finally{ if (br != null) { try { br.close(); } catch (Exception e) { System.out.println("密钥读取流关闭异常"); } } } } 2、公钥和私钥 公钥字符串生成公钥 public static RSAPublicKey createPublicKey(String publicKeyValue) throws Exception { try { byte[] buffer = DatatypeConverter.parseBase64Binary(publicKeyValue); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); return (RSAPublicKey) keyFactory.generatePublic(keySpec); } catch (Exception e) { throw new Exception("公钥创建失败", e); } } 私钥字符串生成私钥 public static RSAPrivateKey createPrivateKey(String privateKeyValue) throws Exception { try { byte[] buffer = javax.xml.bind.DatatypeConverter.parseBase64Binary(privateKeyValue); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); } catch (Exception e) { throw new Exception("私钥创建失败", e); } } 3、加密和解密 公钥加密 public static String encrypt(RSAPublicKey publicKey, byte[] clearData) throws Exception { if (publicKey == null) { throw new Exception("加密公钥为空, 无法加密"); } try { Cipher cipher = Cipher.getInstance("RSA") ; cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] output = cipher.doFinal(clearData); return printBase64Binary(output); } catch (Exception e) { throw new Exception("公钥加密失败",e); } } 私钥解密 public static String decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception { if (privateKey == null) { throw new Exception("解密私钥为空, 无法解密"); } try { Cipher cipher = Cipher.getInstance("RSA") ; cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] output = cipher.doFinal(cipherData); return new String(output); } catch (BadPaddingException e) { throw new Exception("私钥解密失败",e); } } 4、签名和验签 私钥签名 public static String sign (String signData, PrivateKey privateKey) throws Exception { byte[] keyBytes = privateKey.getEncoded(); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey key = keyFactory.generatePrivate(keySpec); Signature signature = Signature.getInstance("MD5withRSA"); signature.initSign(key); signature.update(signData.getBytes()); return printBase64Binary(signature.sign()); } 公钥验签 public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception { byte[] keyBytes = publicKey.getEncoded(); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey key = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance("MD5withRSA"); signature.initVerify(key); signature.update(srcData.getBytes()); return signature.verify(parseBase64Binary(sign)); } 5、编码和解码 /** * 字节数组转字符 */ public static String printBase64Binary(byte[] bytes) { return DatatypeConverter.printBase64Binary(bytes); } /** * 字符转字节数组 */ public static byte[] parseBase64Binary(String value) { return DatatypeConverter.parseBase64Binary(value); } 6、测试代码块 密钥生成测试 public static void testCreateKey () throws Exception { HashMap<String, String> map = RsaCryptUtil.getTheKeys(); String privateKeyStr=map.get("privateKey"); String publicKeyStr=map.get("publicKey"); System.out.println("私钥:"+privateKeyStr); System.out.println("公钥:"+publicKeyStr); //消息发送方 String originData="cicada-smile"; System.out.println("原文:"+originData); String encryptData = RsaCryptUtil.encrypt(RsaCryptUtil.createPublicKey(publicKeyStr), originData.getBytes()); System.out.println("加密:"+encryptData); //消息接收方 String decryptData=RsaCryptUtil.decrypt(RsaCryptUtil.createPrivateKey(privateKeyStr), RsaCryptUtil.parseBase64Binary(encryptData)); System.out.println("解密:"+decryptData); } 密钥读取测试 public static void testReadKey () throws Exception { String value = getKey("rsaKey/public.key"); System.out.println(value); String privateKeyStr = getKey(RsaCryptUtil.PRI_KEY) ; String publicKeyStr = getKey(RsaCryptUtil.PUB_KEY) ; //消息发送方 String originData="cicada-smile"; System.out.println("原文:"+originData); String encryptData = RsaCryptUtil.encrypt(RsaCryptUtil.createPublicKey(publicKeyStr), originData.getBytes()); System.out.println("加密:"+encryptData); //消息接收方 String decryptData=RsaCryptUtil.decrypt(RsaCryptUtil.createPrivateKey(privateKeyStr), RsaCryptUtil.parseBase64Binary(encryptData)); System.out.println("解密:"+decryptData); } 签名验签测试 public static void testSignVerify () throws Exception { String signData = "cicada-smile" ; String privateKeyStr = getKey(RsaCryptUtil.PRI_KEY) ; String publicKeyStr = getKey(RsaCryptUtil.PUB_KEY) ; String signValue = sign(signData,RsaCryptUtil.createPrivateKey(privateKeyStr)) ; boolean flag = verify(signData,RsaCryptUtil.createPublicKey(publicKeyStr),signValue); System.out.println("原文:"+signData); System.out.println("签名:"+signValue); System.out.println("验签:"+flag); } 四、源代码地址 GitHub·地址 https://github.com/cicadasmile GitEE·地址 https://gitee.com/cicadasmile

优秀的个人博客,低调大师

阿里云产品 服务器的购买流程(适合新手小白)

阿里ESC服务器购买教程 一:服务器 作为一个开发人员,作为一个程序员,服务器早晚是我们要遇到的一件事对于新人来说,这可能是一件头疼的事情,不要怕.........毕竟现在已经有大神前辈为我们趟好路,服务器的购买不要有什么编程基础你要你会上网,好好看看 Jacob 这篇文章,你将轻松掌握。废话不多,我们开始吧! 创作不容易,如果你学到了知识,请多多分享和支持下 Jacob, 一键领取阿里云优惠券领!优惠券购买阿里所有产品,都会享受最低折扣,还能实物抽奖IPad! 有阿里云账户的直接点击↓ ↓ 点击此处领取----阿里产品优惠券大礼包 (新手必得享超值优惠)https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=iix6mglo平时1核1G优惠过后要300多一年,2核4G性能强劲,足够中小型网站/服务器建设 建议大家直接购买此优惠,很少见优惠力度这么大的活动。 二:拥有阿里云账户 先注册阿里云账户 ----------阿里云官网 随后就是填写个人信息资料; 注册过程相信你一定会的; 三:阿里优惠活动 点击此处领取----阿里产品优惠券大礼包 (新手必得享超值优惠)https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=iix6mglo1, 登陆阿里云账户后,在网页左上角会看到如下图标记字样; 点击最新活动,阿里基本所有的优惠方案都会在这里; 对于有钱的用户可以直接点击产品购买; 四:根据需要,选择方案并购买 1;根据情况,选择要购买的方案 如果你是企业如果是新手且个人使用,这个满足你绰绰有余在阿里的优惠活动中,有很多的优惠方案有新用户专享方案还有针对大学生的学生特惠并且新用户还有免费体验,现如今好像是1个月体验期,前提是需要完成实名认证。企业版用户,是6个月! 2;选择购买的服务器类型 选择好购买的类型后,点击立即购买,会自动生成购物清单 3;查看清单信息,并查看是否使用了优惠券 如果没有领优惠券,一定要先领取才能享受优惠 点击此处领取----阿里产品优惠券大礼包 (新手必得享超值优惠)https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=iix6mglo 2;付款完成订单 五:购买完成,返回控制台 服务器购买完成后,等待返回控制台,如果刚没有设置密码,可在里面设置服务器登陆密码,然后实例化服务器; 六:服务器购买完成,本篇小结 在控制台中,就可以看到自己所购买的服务器,不懂的太多,还需自己去亲自探索探索对于后期的服务器搭建请参阅这位博主的文章-------------服务器搭建.

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册