java操作linux

文章目录

  • 远程连接服务器
  • 执行linux命令或shell脚本
    • 介绍
      • Process的方法
      • 相关类UML
    • 工具类
      • 基本工具类
      • 依赖第三方的工具类

远程连接服务器

java程序远程linux服务器有两个框架分别是:jsch与ganymed-ssh2框架。推荐使用jsch框架,因为ganymed-ssh2框架不支持麒麟服务器的连接,原因是openssl版本过高,ganymed-ssh框架不维护了所以不支持。

import cn.hutool.core.text.StrSplitter;
import cn.hutool.core.util.StrUtil;
import com.jcraft.jsch.*;import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Properties;/*** 远程连接linux服务并执行命令* 网上查询经过验证可以使用<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.21</version></dependency><dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.55</version></dependency>*/
public class ShellUtils {private static Session session;private ShellUtils() {}public static ShellUtils getInstance() {return new ShellUtils();}/*** 初始化* @throws JSchException JSch异常*/public void init(String ip, Integer port, String username,String password) throws JSchException {JSch jsch = new JSch();jsch.getSession(username, ip, port);session = jsch.getSession(username, ip, port);session.setPassword(password);Properties sshConfig = new Properties();sshConfig.put("StrictHostKeyChecking", "no");session.setConfig(sshConfig);session.connect(1200 * 1000);}// 执行一条命令public String execCmd(String command) throws Exception {// 打开执行shell指令的通道Channel channel = session.openChannel("exec");ChannelExec channelExec = (ChannelExec) channel;String cmd = "source /etc/profile && source ~/.bash_profile " +"&& source ~/.bashrc &&  adb devices";channelExec.setCommand(cmd);channelExec.setCommand(command);channel.setInputStream(null);channelExec.setErrStream(System.err);// channel.setXForwarding();channel.connect();StringBuilder sb = new StringBuilder(16);try (InputStream in = channelExec.getInputStream();InputStreamReader isr = new InputStreamReader(in,StandardCharsets.UTF_8);BufferedReader reader = new BufferedReader(isr)) {String buffer;while ((buffer = reader.readLine()) != null) {sb.append(buffer);}} finally {if (channelExec != null && channelExec.isConnected()) {channelExec.disconnect();}if (channel != null && channel.isConnected()) {channel.disconnect();}}return sb.toString();}// 执行一条命令 获取错误流中的内容public String execCmdErrContent(String command) throws Exception {// 打开执行shell指令的通道Channel channel = session.openChannel("exec");ChannelExec channelExec = (ChannelExec) channel;channelExec.setCommand(command);channel.setInputStream(null);ByteArrayOutputStream err = new ByteArrayOutputStream();channelExec.setErrStream(err);channel.connect();StringBuilder sb = new StringBuilder(16);try (InputStream in = channelExec.getErrStream();InputStreamReader isr = new InputStreamReader(in,StandardCharsets.UTF_8);BufferedReader reader = new BufferedReader(isr)) {String buffer;while ((buffer = reader.readLine()) != null) {sb.append("\n").append(buffer);}if (StrUtil.contains(sb.toString(), "没有那个文件或目录")) {return "";} else {return sb.toString();}} finally {if (channelExec != null && channelExec.isConnected()) {channelExec.disconnect();}if (channel != null && channel.isConnected()) {channel.disconnect();}}}public static void closeConnect() {if (session != null && session.isConnected()) {session.disconnect();}}public static void main(String[] args) {ShellUtils instance = ShellUtils.getInstance();try {instance.init("192.168.81.122", 22, "root", "test1");String cmd = "ps -ef | grep monitor-0.0.1-SNAPSHOT.jar " +"| grep -v xjar|grep -v grep | awk '{print $2}'";String ls = instance.execCmd(cmd);
//            String cmd = "cat /opt/dmdbms/log/dm_DW1_01B_202203.log " +
//                    "| grep -v 'INFO'";
//            String ls = instance.execCmd(cmd);
//            List<String> lineFreedList = StrSplitter.splitByRegex(
//                    StrUtil.trimToEmpty(ls),
//                    "\n", -1, true, true
//            );
//            for (String s : lineFreedList) {
//                List<String> stringList = StrSplitter.split(
//                        StrUtil.trimToEmpty(s),
//                        "=", -1, true, true
//                );
//                System.out.println(stringList);
//            }System.out.println(ls);
//            // 计算内存使用率(已使用内存/总内存)
//            String cmd1 = "free | sed -n '2p'";
//            String freeStr = instance.execCmd(cmd1);
//            List<String> freeInfoList = StrSplitter.splitByRegex(
//                    StrUtil.trimToEmpty(freeStr),
//                    "\\s+", -1, true, true
//            );
//            String allMemory = freeInfoList.get(1);
//            String usedMemory = freeInfoList.get(2);
//            double f1 = new BigDecimal(
//                    Float.valueOf(usedMemory) / Float.valueOf(allMemory)
//            )
//                    .setScale(2, BigDecimal.ROUND_HALF_UP)
//                    .doubleValue() * 100;
//            System.out.println(ls);} catch (Exception e) {System.out.println("error info");e.printStackTrace();} finally {ShellUtils.closeConnect();}}
}

执行linux命令或shell脚本

在Java中,调用runtime线程执行脚本是非常消耗资源的,所以切记不要频繁使用!
在调用runtime去执行脚本的时候,其实就是JVM开了一个子线程去调用JVM所在系统的命令,其中开了三个通道:输入流、输出流、错误流,其中输出流就是子线程走调用的通道。
大家都知道,waitFor是等待子线程执行命令结束后才访问,但是在runtime中,打开程序的命令如果不关闭,就不算子线程结束,比如如下代码。

private static Process p = null;
p = Runtime.getRuntime().exec("notepad.exe");
p.waitFor();
System.out.println("---------------我被执行了");

以上代码中,打开windows中记事本,如果我们不手动关闭记事本,那么输出语句就不会执行,这点是需要理解的。

介绍

// 在单独的进程中执行指定的字符串命令
public Process exec(String command)
// 在单独的进程中执行指定命令和变量
public Process exec(String[] cmdArray)
// 在指定环境的独立进程中执行指定命令和变量
public Process exec(String command,String[] envp)
// 在指定环境的独立进程中执行指定命令和变量
public Process exec(String[] cmdArray,String[] envp)
// 在有指定的环境和工作目录的独立进程中执行指定的字符串命令
public Process exec(String command,String[] encp,File dir)
// 在指定环境和工作目录的独立进程中执行指定的命令和变量
public Process exec(String[] cmdarray,String[] envp,File dir)
  • cmdArray: 包含所调用命令及其参数的数组。
    • 如果把命令放到一个String[]中时,必须把命令中每个部分作为一个元素存在String[]中,或者是把命令按照空格符分割得到的String[]。
//right
String[] cmdArray = {"tar", "-cf", tarName, fileName};
//error
String[] cmdArray = {"tar -cf", tarName, fileName};
  • command: 一条指定的系统命令。
  • envp: 字符串数组,其中每个元素的环境变量的设置格式为name=value;如果子进程应该继承当前进程的环境,则该参数为 null。
    • 模拟环境变量
val=2
call=Bash Shell
  • 测试shell脚本
#!/usr/bin/env bashargs=1
if [ $# -eq 1 ];thenargs=$1echo "The argument is: $args"
fiecho "This is a $call"
start=`date +%s`
sleep 3s
end=`date +%s`
cost=$((($end - $start) * $args * $val))
echo "Cost Time: $cost"
  • 调用
String cmd = "sh " + script + " " + args;
String[] evnp = {"val=2", "call=Bash Shell"};
process = Runtime.getRuntime().exec(cmd, evnp);
BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())
);
String line = "";
while ((line = input.readLine()) != null) {System.out.println(line);
}
input.close();
  • 返回结果
/root/experiment/
The argument is: 4
This is a Bash Shell
Cost Time: 24
  • dir: 子进程的工作目录;如果子进程应该继承当前进程的工作目录,则该参数为 null。

Process的方法

  • destroy():杀掉子进程
  • exitValue():返回子进程的出口值,值0表示正常终止
  • getErrorStream():获取子进程的错误流
  • getInputStream():获取子进程的输入流
  • getOutputStream():获取子进程的输出流
  • waitFor():导致当前线程等待,如有必要,一直要等到由该Process对象表示的进程已经终止。如果已终止该子进程,此方法立即返回。如果没有终止该子进程,调用的线程将被阻塞,直到退出子进程,0表示正常终止。

相关类UML

java.lang.Runtime
在这里插入图片描述
java.lang.Process
在这里插入图片描述

工具类

基本工具类

package utils;import java.io.BufferedReader;
import java.io.InputStreamReader;public class ShellUtils {//执行shell命令并获取输出结果public static String execAndResult(String cmd){System.out.println("cmd: " + cmd);String result = "";try {Runtime runtime = Runtime.getRuntime();Process ps = runtime.exec(cmd);//获取执行结果的输入BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));StringBuffer sb = new StringBuffer();String line;while ((line = br.readLine()) != null) {//执行结果加上回车sb.append(line);}result = sb.toString();br.close();System.out.println("waitFor:" + ps.waitFor());} catch (Exception e) {e.printStackTrace();}return result;}public static void main(String[] args) {//执行普通命令execAndResult("shutdown -r");//执行脚本execAndResult("sh /data/jqxt/script/bak_pz.sh");}
}

依赖第三方的工具类

import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.StaticLog;import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;/**<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.21</version></dependency>*/
public class MyRuntimeUtil {/*** 执行系统命令,使用系统默认编码** @param cmds 命令列表,每个元素代表一条命令* @return 执行结果* @throws IORuntimeException IO异常*/public static String execForStr(String... cmds)throws IORuntimeException {return execForStr(CharsetUtil.systemCharset(), cmds);}/*** 执行系统命令,使用系统默认编码** @param charset 编码* @param cmds    命令列表,每个元素代表一条命令* @return 执行结果* @throws IORuntimeException IO异常* @since 3.1.2*/public static String execForStr(Charset charset, String... cmds)throws IORuntimeException {return getResult(exec(cmds), charset);}public static String execForErrStr(Charset charset, String cmd)throws IORuntimeException {return getResultErr(exec(cmd), charset);}/*** 执行系统命令,使用系统默认编码*/public static String execForStr(Charset charset, String cmds)throws IORuntimeException {return getResult(exec(cmds), charset);}/*** 执行系统命令,使用系统默认编码** @param cmds 命令列表,每个元素代表一条命令* @return 执行结果,按行区分* @throws IORuntimeException IO异常*/public static List<String> execForLines(String... cmds)throws IORuntimeException {return execForLines(CharsetUtil.systemCharset(), cmds);}/*** 执行系统命令,使用系统默认编码** @param charset 编码* @param cmds    命令列表,每个元素代表一条命令* @return 执行结果,按行区分* @throws IORuntimeException IO异常* @since 3.1.2*/public static List<String> execForLines(Charset charset, String... cmds)throws IORuntimeException {return getResultLines(exec(cmds), charset);}/*** 执行命令<br>* 命令带参数时参数可作为其中一个参数,也可以将命令和参数组合为一个字符串传入** @param cmds 命令* @return {@link Process}*/public static Process exec(String... cmds) {Process process;try {process = new ProcessBuilder(handleCmds(cmds)).redirectErrorStream(true).start();} catch (IOException e) {throw new IORuntimeException(e);}return process;}/*** 执行命令<br>* 命令带参数时参数可作为其中一个参数,也可以将命令和参数组合为一个字符串传入** @param cmd 命令* @return {@link Process}*/public static Process exec(String cmd) {Process process;try {// 得到Java进程的相关Runtime运行对象Runtime runtime = Runtime.getRuntime();if (cmd.indexOf("|") > 0) {String[] cmdArr = {"sh", "-c", cmd};process = runtime.exec(cmdArr);} else {process = runtime.exec(cmd);}} catch (IOException e) {throw new IORuntimeException(e);}return process;}/*** 执行命令<br>* 命令带参数时参数可作为其中一个参数,也可以将命令和参数组合为一个字符串传入** @param envp 环境变量参数,传入形式为key=value,null表示继承系统环境变量* @param cmds 命令* @return {@link Process}* @since 4.1.6*/public static Process exec(String[] envp, String... cmds) {return exec(envp, null, cmds);}/*** 执行命令<br>* 命令带参数时参数可作为其中一个参数,也可以将命令和参数组合为一个字符串传入** @param envp 环境变量参数,传入形式为key=value,null表示继承系统环境变量* @param dir  执行命令所在目录(用于相对路径命令执行),null表示使用当前进程执行的目录* @param cmds 命令* @return {@link Process}* @since 4.1.6*/public static Process exec(String[] envp, File dir, String... cmds) {try {return Runtime.getRuntime().exec(handleCmds(cmds), envp, dir);} catch (IOException e) {throw new IORuntimeException(e);}}// ------------------------------------ result/*** 获取命令执行结果,使用系统默认编码,获取后销毁进程** @param process {@link Process} 进程* @return 命令执行结果列表*/public static List<String> getResultLines(Process process) {return getResultLines(process, CharsetUtil.systemCharset());}/*** 获取命令执行结果,使用系统默认编码,获取后销毁进程** @param process {@link Process} 进程* @param charset 编码* @return 命令执行结果列表* @since 3.1.2*/public static List<String> getResultLines(Process process, Charset charset) {InputStream in = null;try {in = process.getInputStream();return IoUtil.readLines(in, charset, new ArrayList<>());} finally {IoUtil.close(in);destroy(process);}}/*** 获取命令执行结果,使用系统默认编码,,获取后销毁进程** @param process {@link Process} 进程* @return 命令执行结果列表* @since 3.1.2*/public static String getResult(Process process) {return getResult(process, CharsetUtil.systemCharset());}/*** 获取命令执行结果,获取后销毁进程** @param process {@link Process} 进程* @param charset 编码* @return 命令执行结果列表* @since 3.1.2*/public static String getResult(Process process, Charset charset) {InputStream in = null;InputStream errorStream = null;try {in = process.getInputStream();errorStream = process.getErrorStream();String errorResult = IoUtil.read(errorStream, charset);if (StrUtil.isNotBlank(errorResult)) {StaticLog.warn("Shell command execution error, because {}", errorResult);}return IoUtil.read(in, charset);} finally {IoUtil.close(in);IoUtil.close(errorStream);destroy(process);}}/*** 获取错误的执行结果,获取后销毁进程** @param process {@link Process} 进程* @param charset 编码* @return 命令执行结果列表* @since 3.1.2*/public static String getResultErr(Process process, Charset charset) {InputStream in = null;InputStream errorStream = null;try {in = process.getInputStream();errorStream = process.getErrorStream();// System.out.println("252"+IoUtil.read(errorStream, charset));return IoUtil.read(errorStream, charset);} finally {IoUtil.close(in);IoUtil.close(errorStream);destroy(process);}}/*** 获取命令执行异常结果,使用系统默认编码,,获取后销毁进程** @param process {@link Process} 进程* @return 命令执行结果列表* @since 4.1.21*/public static String getErrorResult(Process process) {return getErrorResult(process, CharsetUtil.systemCharset());}/*** 获取命令执行异常结果,获取后销毁进程** @param process {@link Process} 进程* @param charset 编码* @return 命令执行结果列表* @since 4.1.21*/public static String getErrorResult(Process process, Charset charset) {InputStream in = null;try {in = process.getErrorStream();return IoUtil.read(in, charset);} finally {IoUtil.close(in);destroy(process);}}/*** 销毁进程** @param process 进程* @since 3.1.2*/public static void destroy(Process process) {if (null != process) {process.destroy();}}/*** 增加一个JVM关闭后的钩子,用于在JVM关闭时执行某些操作** @param hook 钩子* @since 4.0.5*/public static void addShutdownHook(Runnable hook) {Runtime.getRuntime().addShutdownHook((hook instanceof Thread) ?(Thread) hook :new Thread(hook));}/*** 获得JVM可用的处理器数量(一般为CPU核心数)** @return 可用的处理器数量* @since 5.3.0*/public static int getProcessorCount() {return Runtime.getRuntime().availableProcessors();}/*** 获得JVM中剩余的内存数,单位byte** @return JVM中剩余的内存数,单位byte* @since 5.3.0*/public static long getFreeMemory() {return Runtime.getRuntime().freeMemory();}/*** 获得JVM已经从系统中获取到的总共的内存数,单位byte** @return JVM中剩余的内存数,单位byte* @since 5.3.0*/public static long getTotalMemory() {return Runtime.getRuntime().totalMemory();}/*** 获得JVM中可以从系统中获取的最大的内存数,单位byte,以-Xmx参数为准** @return JVM中剩余的内存数,单位byte* @since 5.3.0*/public static long getMaxMemory() {return Runtime.getRuntime().maxMemory();}/*** 获得JVM最大可用内存,计算方法为:<br>* 最大内存-总内存+剩余内存** @return 最大可用内存*/public static long getUsableMemory() {return getMaxMemory() - getTotalMemory() + getFreeMemory();}/*** 获取当前进程ID,首先获取进程名称,读取@前的ID值,如果不存在,则读取进程名的hash值** @return 进程ID* @throws UtilException 进程名称为空* @since 5.7.3*/public static int getPid() throws UtilException {final String processName = ManagementFactory.getRuntimeMXBean().getName();if (StrUtil.isBlank(processName)) {throw new UtilException("Process name is blank!");}final int atIndex = processName.indexOf('@');if (atIndex > 0) {return Integer.parseInt(processName.substring(0, atIndex));} else {return processName.hashCode();}}/*** 处理命令,多行命令原样返回,单行命令拆分处理** @param cmds 命令* @return 处理后的命令*/private static String[] handleCmds(String... cmds) {if (ArrayUtil.isEmpty(cmds)) {throw new NullPointerException("Command is empty !");}// 单条命令的情况if (1 == cmds.length) {final String cmd = cmds[0];if (StrUtil.isBlank(cmd)) {throw new NullPointerException("Command is blank !");}cmds = cmdSplit(cmd);}return cmds;}/*** 命令分割,使用空格分割,考虑双引号和单引号的情况** @param cmd 命令,如 git commit -m 'test commit'* @return 分割后的命令*/private static String[] cmdSplit(String cmd) {final List<String> cmds = new ArrayList<>();final int length = cmd.length();final Stack<Character> stack = new Stack<>();boolean inWrap = false;final StrBuilder cache = StrUtil.strBuilder();char c;for (int i = 0; i < length; i++) {c = cmd.charAt(i);switch (c) {case CharUtil.SINGLE_QUOTE:case CharUtil.DOUBLE_QUOTES:if (inWrap) {if (c == stack.peek()) {//结束包装stack.pop();inWrap = false;}cache.append(c);} else {stack.push(c);cache.append(c);inWrap = true;}break;case CharUtil.SPACE:if (inWrap) {// 处于包装内cache.append(c);} else {cmds.add(cache.toString());cache.reset();}break;default:cache.append(c);break;}}if (cache.hasContent()) {cmds.add(cache.toString());}return cmds.toArray(new String[0]);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/804375.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百度驾驶证C++离线SDK V1.1 C#接入

百度驾驶证C离线SDK V1.1 C#接入 目录 说明 效果 项目 代码 下载 说明 自己根据SDK封装了动态库&#xff0c;然后C#调用。 SDK包结构 效果 项目 代码 using Newtonsoft.Json; using OpenCvSharp; using System; using System.Collections.Generic; using System.D…

C++矩阵库Armadillo出现warning solve() system is singular错误的解决

本文介绍使用C 语言的矩阵库Armadillo时&#xff0c;出现报错system is singular; attempting approx solution的解决方法。 在之前的文章中&#xff0c;我们介绍过Armadillo矩阵库在Visual Studio软件C环境中的配置方法&#xff08;https://blog.csdn.net/zhebushibiaoshifu/a…

使用midjourney搞出一套三国人物画像!

当下已进入如火如荼的全民AI时代&#xff0c;最近体验了下midjourney&#xff0c;使用它的以图生图功能生成出来一套三国人物画像&#xff0c;和大家分享下使用心得。 使用midjourney的准备工作 下载工具 使用midjourney生产图片依赖的工具和流程&#xff0c;大致如下&#…

vue3移动端H5 瀑布流显示列表

以上效果 是之前发送的改进版 waterList <template><view class"pro-cons" v-if"data.length"><view class"cons-left"><template v-for"(item, index) in data"><template v-if"(index 1) % 2 1…

NLP在搜索召回领域中的应用场景

自然语言处理&#xff08;NLP&#xff09;在搜索召回领域中的应用场景非常广泛&#xff0c;它通过理解和分析人类语言&#xff0c;提高了信息检索的准确性和效率。以下是一些具体的应用场景&#xff1a; 1. 搜索引擎优化 NLP技术可以用于优化搜索引擎的查询处理&#xff0c;通…

【DM8】外部表

外部表是指不存在于数据库中的表。 通过向达梦数据库定义描述外部表的元数据&#xff0c;可以把一个操作系统文件当成一个只读的数据库表&#xff0c;对外部表将像普通定义的表一样访问。 外部表的数据存储在操作系统文件中&#xff0c;建立外部表的时候&#xff0c;不会产生…

下载安装JDK17(windows)

官网地址 Oracle | Cloud Applications and Cloud Platform 点击Products拉倒最下面点击java 点击右下角Download Java 选择JDK17 点击Windows&#xff0c;下载第二个 下载完成点击一下步安装就好了 认真看这段话 ​ JDK 17 binaries are free to use in production and free…

代码整洁之道【2】--函数

关于函数部分的总结 一、函数只做一件事 函数应该只做一件事、做好这件事、只做这件事。 判断函数是否不止做了一件事&#xff0c;还有一个方法&#xff0c;就是看是否能再拆出一个函数&#xff0c;该函数不仅只是单纯地重新 二、函数尽量不要太长 按照作者的理论&#xff…

【算法】双指针算法

个人主页 &#xff1a; zxctscl 如有转载请先通知 题目 1. 283. 移动零1.1 分析1.2 代码 2. 1089. 复写零2.1 分析2.2 代码 3. 202. 快乐数3.1 分析3.2 代码 4. 11. 盛最多水的容器4.1 分析4.2 代码 5. LCR 179. 查找总价格为目标值的两个商品5.1 分析5.2 代码 6. 15. 三数之和…

大语言模型开源数据集

本文目标&#xff1a;汇聚目前大语言模型预训练、微调、RM/RL、评测等全流程所需的常见数据集&#xff0c;方便大家使用&#xff0c;本文持续更新。文章篇幅较长&#xff0c;建议收藏后使用。 一、按语料类型分类 1、维基百科类 No.1 Identifying Machine-Paraphrased Plagia…

企业微信认证后可以修改主体吗?

企业微信变更主体有什么作用&#xff1f;如果原有的公司注销了&#xff0c;或者要更换一家公司主体来运营企业微信&#xff0c;那么就可以进行变更主体&#xff0c;变更主体后才可以保留原来企业微信上的所有用户&#xff0c;否则就只能重新申请重新积累用户了。企业微信变更主…

【资源分享】MAC上最好用的截图软件-Snipaste

::: block-1 “时问桫椤“是一个关注本科生到研究生教育阶段的不严肃的公众号&#xff0c;希望能在大家迷茫、难受、困难之时帮助到大家。用广大研究生的经验总结&#xff0c;让大家能尽早的适应研究生生活&#xff0c;尽快的看透科研本质。祝好&#xff01;&#xff01;&#…

vue通过echarts实现数据可视化

1、安装echarts cnpm install echarts -Sechart官方图表示例大全&#xff1a;https://echarts.apache.org/examples/zh/index.html#chart-type-line 2、代码实现 <template><div><div class"box" ref"zhu"></div><div class&…

注解式 WebSocket - 构建 群聊、单聊 系统

目录 前言 注解式 WebSocket 构建聊天系统 群聊系统&#xff08;基本框架&#xff09; 群聊系统&#xff08;添加昵称&#xff09; 单聊系统 WebSocket 作用域下无法注入 Spring Bean 对象&#xff1f; 考虑离线消息 前言 很久之前&#xff0c;咱们聊过 WebSocket 编程式…

掌握网络抓取技术:利用RobotRules库的Perl下载器一览小红书的世界

引言 在信息时代的浪潮下&#xff0c;人们对于获取和分析海量网络数据的需求与日俱增。网络抓取技术作为满足这一需求的关键工具&#xff0c;正在成为越来越多开发者的首选。而Perl语言&#xff0c;以其卓越的文本处理能力和灵活的特性&#xff0c;脱颖而出&#xff0c;成为了…

Android 属性动画及自定义3D旋转动画

Android 动画框架 其中包括&#xff0c;帧动画、视图动画&#xff08;补间动画&#xff09;、属性动画。 在Android3.0之前&#xff0c;视图动画一家独大&#xff0c;之后属性动画框架被推出。属性动画框架&#xff0c;基本可以实现所有的视图动画效果。 视图动画的效率较高…

【第七篇】使用BurpSuite进行主动、被动扫描和主动、被动爬虫

文章目录 前言主动扫描被动扫描主动爬虫被动爬虫前言 Burp Scanner 既可以用作全自动扫描仪,也可以用作增强手动测试工作流程的强大手段。 扫描网站涉及两个阶段: 抓取内容和功能: Burp Scanner 首先在目标站点周围导航,密切反映真实用户的行为。它对站点的结构和内容以及…

数字社会下的智慧公厕:构筑智慧城市的重要组成部分

智慧城市已经成为现代城市发展的趋势&#xff0c;而其中的数字化转型更是推动未来社会治理体系和治理能力现代化的必然要求。在智慧城市建设中&#xff0c;智慧公厕作为一种新形态的信息化公共厕所&#xff0c;扮演着重要角色。本文智慧公厕源头实力厂家广州中期科技有限公司&a…

【攻防世界】web2(逆向解密)

进入题目环境&#xff0c;查看页面信息&#xff1a; <?php $miwen"a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";function encode($str){$_ostrrev($str);// echo $_o;for($_00;$_0<strlen($_o);$_0){$_csubstr($_o,$_0,1);$__ord($_c)1;…

龙蜥社区「人人都可以参与开源」——体验开源成为“开源人“

龙蜥社区「人人都可以参与开源」体验开源——让更多的人了解开源&#xff01; 龙蜥社区开源概述&#xff1a;龙蜥社区开源的探索过程:龙蜥社区收获总结:AtomGit评测:服务设计上:功能结构上:安全设计上: AtomGit测评总结: 龙蜥社区开源概述&#xff1a; 在追求技术的路上少不了…