首页
统计
留言板
友接
推荐
免费图床
服务监控
Search
1
immich开源相册部署教程
235 阅读
2
GraalVM将Java打包原生Native应用
222 阅读
3
将旧手机改造成Linux服务器
168 阅读
4
Java函数式编程
128 阅读
5
FRP内网穿透教程
120 阅读
编程语言
Java
Python
Go
单片机
Arduino
ESP8266
ESP32
STM32
51单片机
树莓派
运维
Docker容器
随身小记
登录
Search
标签搜索
Spring
SpringMVC
Java
docker
DSM
群晖
iptables
ssh
spring
mybaits
redis
SpringBoot
消息队列
科长
累计撰写
30
篇文章
累计收到
4
条评论
首页
栏目
编程语言
Java
Python
Go
单片机
Arduino
ESP8266
ESP32
STM32
51单片机
树莓派
运维
Docker容器
随身小记
页面
统计
留言板
友接
推荐
免费图床
服务监控
搜索到
30
篇与
科长
的结果
2023-12-26
ssh命令使用教程
SSH(Secure Shell)是一种网络协议,用于在不安全的网络上安全地进行远程登录和传输数据。SSH命令是用于在终端中执行SSH协议操作的命令行工具。参数解析-p 参数:指定SSH服务器的端口号。默认情况下,SSH使用22号端口。例如:ssh -p 2222 user@example.com-i 参数:指定用于身份验证的私钥文件。私钥文件通常是以RSA或DSA格式存储的。例如:ssh -i ~/.ssh/id_rsa user@example.com # 将使用id_rsa文件进行身份验证-l 参数:指定要登录的用户名。如果不指定该参数,SSH将使用当前用户名。例如:ssh -l user example.com # 将使用用户名user连接到example.com-X 参数:启用X11转发,允许在远程主机上显示图形应用程序。例如:ssh -X user@example.com # 将允许在本地主机上显示远程主机上的图形界面应用程序-L 参数:进行本地端口转发。本地端口转发将本地主机的一个端口转发到远程主机的一个指定地址和端口上。例如:ssh -L 8080:localhost:80 user@example.com # 将本地主机的8080端口转发到example.com的80端口-R 参数:进行远程端口转发。远程端口转发将远程主机的一个端口转发到本地主机的一个指定地址和端口上。例如:ssh -R 8080:localhost:80 user@example.com # 将example.com的8080端口转发到本地主机的80端口-N 参数:仅进行连接,而不启动远程shell。这在只需要建立SSH连接而不需要执行命令时很有用。例如:ssh -N user@example.com # 将仅建立到example.com的SSH连接这些只是SSH命令的一些常见参数,还有其他更多参数和用法。SSH命令在以下场景中非常有用:远程登录:使用SSH命令可以安全地远程登录到远程服务器或主机,以执行命令和管理系统文件传输:SSH命令可以通过SCP(Secure Copy)或SFTP(SSH File Transfer Protocol)在本地主机和远程主机之间进行安全的文件传输端口转发:通过SSH的端口转发功能,可以在安全的连接中将本地端口转发到远程主机或将远程端口转发到本地主机,以实现网络服务的访问和共享远程执行命令:可以使用SSH命令在远程主机上执行命令,例如运行脚本或执行系统管理任务
2023年12月26日
28 阅读
0 评论
0 点赞
2023-12-22
Rsync+Sersync 目录双向同步
服务器1:192.168.5.131 监听(同步)目录:/root/data/upload服务器2:192.168.5.132 监听(同步)目录:/root/data/upload安装步骤1、两台机器安装rsyncyum install rsync -y sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config2、修改机器1的配置修改 /etc/rsyncd.conf 配置文件# /etc/rsyncd: configuration file for rsync daemon mode # See rsyncd.conf man page for more options. # configuration example: uid = root gid = root use chroot = no address = 192.168.5.131 port = 873 max connections = 0 pid file = /var/run/rsyncd.pid log file = /var/log/rsyncd.log exclude = lost+found/ ignore errors [update] path = /root/data/upload comment = test rsync + sersync read only = no list = no auth users = root secrets file = /etc/rsync_update.passwd hosts allow = *3、修改机器2的配置修改 /etc/rsyncd.conf 配置文件# /etc/rsyncd: configuration file for rsync daemon mode # See rsyncd.conf man page for more options. # configuration example: uid = root gid = root use chroot = no address = 192.168.5.132 port = 873 max connections = 0 pid file = /var/run/rsyncd.pid log file = /var/log/rsyncd.log exclude = lost+found/ ignore errors [update] path = /root/data/upload comment = test rsync + sersync read only = no list = no auth users = root secrets file = /etc/rsync_update.passwd hosts allow = 192.168.5.131 4、创建虚拟用户在两台机器上同时执行#用户名:密码 用户名需要跟 rsyncd.conf 中的 auth users 一致 echo "root:123456789" > /etc/rsync_update.passwd chmod 600 /etc/rsync_update.passwd5、启动服务在两台机器上同时执行systemctl enable rsyncd systemctl start rsyncd6、测试文件同步在第一台服务器中执行cd ~/data/upload/ touch 1.txt # 192.168.5.132 为第二台机器的ip rsync -av /root/data/upload/ root@192.168.5.132::update # 输入/etc/rsync_update.passwd 中配置的密码 # 查看第二台指定目录中是否存在文件在第二台服务器中执行cd ~/data/upload/ touch 2.txt # 192.168.5.131 为第一台机器的ip rsync -av /root/data/upload/ root@192.168.5.131::update # 输入/etc/rsync_update.passwd 中配置的密码 # 查看第一台指定目录中是否存在文件7、rsync 启动命令systemctl statr rsyncd # 启动服务 systemctl stop rsyncd # 停止服务 systemctl restart rsyncd # 重启服务8、安装监听器两台机器都要执行安装 不同之处在于confxml.xml的配置wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/sersync/sersync2.5.4_64bit_binary_stable_final.tar.gz tar -zxvf sersync2.5.4_64bit_binary_stable_final.tar.gz cd GNU-Linux-x86 修改第一台机器的confxml.xml<!-- 找到这个节点 --> <localpath watch="/root/data/upload"> <remote ip="192.168.5.132" name="update"/> </localpath>watch:监听的目录remote:要同步的远程服务器<!-- 找到这个节点 --> <auth start="true" users="root" passwordfile="/etc/rsync.pas"/>start:远程rsync开启了密码访问users:访问的虚拟用户的用户名passwordfile:密码文件(存放虚拟用户的密码)修改第二台机器的confxml.xml<!-- 找到这个节点 --> <localpath watch="/root/data/upload"> <remote ip="192.168.5.131" name="update"/> </localpath>9、创建密码文件两台服务均要执行echo 123456789 > /etc/rsync.pas chmod 600 /etc/rsync.pas10、开启监听/root/GNU-Linux-x86/sersync2 -d -r -o /root/GNU-Linux-x86/confxml.xml-d 以后台daemon的方式运行-r 第一次启动时,使用rsync将本地文件全部同步至远程服务器。-o 加载配置文件
2023年12月22日
50 阅读
0 评论
0 点赞
2023-12-19
树莓派搭建软路由
本文使用的是树莓派来进行的部署,拥有docker的主机均可食用本教程开启网卡混用ip link set eth0 promisc on创建网络docker network create -d macvlan --subnet=192.168.123.0/24 --gateway=192.168.123.1 -o parent=eth0 macnet这一条命令需要根据树莓派所处的网络环境来做修改,可以使用 sudo ifconfig命令来查看树莓派 eth0 网卡获得的 IP 地址,如果树莓派获得的 IP 地址为 192.168.2.154,那么说明树莓派处在 192.168.2.x网段,相应的,命令中的192.168.123.0和192.168.123.1需要被替换成 192.168.2.0和192.168.2.1:docker network create -d macvlan --subnet=192.168.2.0/24 --gateway=192.168.2.1 -o parent=eth0 macnet拉取镜像docker pull registry.cn-shanghai.aliyuncs.com/suling/openwrt:latest or docker pull sulinggg/openwrt:latest or docker pull docker.m.daocloud.io/nonnichen/nonniwrt:latest创建并启动docker run --restart always --name openwrt -d --network macnet --privileged registry.cn-shanghai.aliyuncs.com/suling/openwrt:latest /sbin/init 其中: --restart always参数表示容器退出时始终重启,使服务尽量保持始终可用; --name openwrt参数定义了容器的名称; -d参数定义使容器运行在 Daemon 模式; --network macnet参数定义将容器加入 maxnet网络; --privileged 参数定义容器运行在特权模式下; registry.cn-shanghai.aliyuncs.com/suling/openwrt:latest为 Docker 镜像名,因容器托管在阿里云 Docker 镜像仓库内,所以在镜像名中含有阿里云仓库信息; /sbin/init定义容器启动后执行的命令。进入容器并修改相关参数docker exec -it openwrt bash 其中: openwrt为容器名称; bash为进入容器后执行的命令。执行此命令后我们便进入 OpenWrt 的命令行界面,首先,我们需要编辑 OpenWrt 的网络配置文件:vim /etc/config/network我们需要更改 Lan 口设置config interface 'lan' option type 'bridge' option ifname 'eth0' option proto 'static' option ipaddr '192.168.123.100' option netmask '255.255.255.0' option ip6assign '60' option gateway '192.168.123.1' option broadcast '192.168.123.255' option dns '192.168.123.1'其中:所有的 192.168.123.x 需要根据树莓派所处网段修改,option gateway和option dns填写路由器的 IP,若树莓派获得的 IP 为 192.168.2.154,路由器 IP 为192.168.2.1,则需要这样修改:config interface 'lan' option type 'bridge' option ifname 'eth0' option proto 'static' option ipaddr '192.168.2.100' option netmask '255.255.255.0' option ip6assign '60' option gateway '192.168.2.1' option broadcast '192.168.2.255' option dns '192.168.2.1'重启网络/etc/init.d/network restart进入控制面板在浏览器中输入第 5 步option ipaddr 项目中的 IP 进入 Luci 控制面板,若option ipaddr 的参数为 192.168.123.100,则可以在浏览器输入 http://192.168.123.100进入控制面板。 用户名:root 密码:password关闭 DHCP 服务在 “网络 - 接口 - Lan - 修改” 界面中,勾选下方的 “忽略此接口(不在此接口提供 DHCP 服务)”,并“保存&应用”。其他修复1.关闭 WLAN 硬件加速设置旁路路由后,若出现访问国内网站网速慢,不稳定的情况(多见于 Pandavan 及其改版固件,如华硕老毛子固件),请在路由器的控制面板中关闭有关 WLAN 的硬件加速,比如选择“Offload TCP/UDP for LAN”(若未出现此现象请忽略):2.宿主机网络修复OpenWrt 容器运行后,宿主机内可能无法正常连接外部网络,需要修改宿主机的/etc/network/interfaces文件以修复:(须结合实际网络情况,不能照抄配置)cp /etc/network/interfaces /etc/network/interfaces.bak # 备份文件 vim /etc/network/interfaces # 使用 vim 编辑文件以“树莓派爱好者基地”64 位 Debian 为例,向文件末尾添加:auto eth0 iface eth0 inet manual auto macvlan iface macvlan inet static address 192.168.123.200 netmask 255.255.255.0 gateway 192.168.123.1 dns-nameservers 192.168.123.1 pre-up ip link add macvlan link eth0 type macvlan mode bridge post-down ip link del macvlan link eth0 type macvlan mode bridge其中,所有的 192.168.123.x都需要按照树莓派所处网段更改,gateway和dns-nameservers填写路由器的 IP,若树莓派获得的 IP 为 192.168.2.154,路由器 IP 为192.168.2.1,则需要这样修改:auto eth0 iface eth0 inet manual auto macvlan iface macvlan inet static address 192.168.2.200 netmask 255.255.255.0 gateway 192.168.2.1 dns-nameservers 192.168.2.1 pre-up ip link add macvlan link eth0 type macvlan mode bridge post-down ip link del macvlan link eth0 type macvlan mode bridge修改后重启树莓派,之后树莓派的局域网 IP 地址将会固定为/etc/network/interfaces文件中address参数中的地址。
2023年12月19日
42 阅读
0 评论
0 点赞
2023-12-19
immich开源相册部署教程
immich 是一个开源的相册服务,支持 ios/android 客户端,支持相册自动备份,可选择备份哪些相册分类或者排除该分类进行备份开源仓库地址 immich-app/immich(github.com)使用脚本进行安装在shell中选择一个目录并执行curl -o- https://raw.githubusercontent.com/immich-app/immich/main/install.sh | bash此方法是实验性的,目前不建议用于生产该脚本将执行以下操作:从存储库的 main 分支下载 docker-compose.yml 和 .env 文件。根据当前目录路径使用必要的信息填充文件。.env启动容器。Web 应用程序将在 上提供,移动应用程序的服务器 URL 将为http://<machine-ip-address>:2283 http://<machine-ip-address>:2283/api用于存储库文件的目录是相对于当前目录的。./immich-data使用Docker Compose部署Docker Compose 是在生产环境中运行 Immich 的推荐方法。以下是使用 Docker Compose 部署 Immich 的步骤。下载所需的文件创建一个您选择的目录(例如 )来保存 和 文件。./immich-app docker-compose.yml.env创建并移动到目录mkdir ./immich-app cd ./immich-app通过运行以下命令下载 docker-compose.yml和 example.env:wget https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env或者从浏览器下载并将文件移动到您创建的目录。注意:如果您从浏览器下载了文件,还要确保重命名为 .example.env`.env`修改env文件参数# You can find documentation for all the supported env variables at https://immich.app/docs/install/environment-variables # The location where your uploaded files are stored UPLOAD_LOCATION=./library # The Immich version to use. You can pin this to a specific version like "v1.71.0" IMMICH_VERSION=release # Connection secret for postgres. You should change it to a random password DB_PASSWORD=postgres # The values below this line do not need to be changed ################################################################################### DB_HOSTNAME=immich_postgres DB_USERNAME=postgres DB_DATABASE_NAME=immich REDIS_HOSTNAME=immich_redis如有必要,请填充自定义数据库信息。填充用于存储备份资产的首选位置。UPLOAD_LOCATION考虑更改为随机生成的内容DB_PASSWORD启动容器docker compose up -d升级immichdocker compose pull && docker compose up -d
2023年12月19日
235 阅读
0 评论
0 点赞
2023-07-10
Java函数式编程
在程序开发中使用函数式编程,可以减少冗杂的代码,加快开发速度等。接下来,我将给大家讲讲在 Java 8 中的三种函数式编程的方法,lambda 表达式、:: 符号和 Optional 类,下面是详细内容。1、函数式编程函数式编程(Functional Programming)属于编程范式(Programming Paradigm)中的用语,此外还有命令式编程(Imperative Programing)等,有兴趣的同学可以自行了解,我们这里大概解释一下函数式编程,在函数式编程中,输入一旦确定了,输出都确定了,函数调用的结果只依赖于传入的输入变量和内部逻辑,不依赖于外部,这样的写出的函数没有副作用。举个例子:public class Test { private int a = 1; public int add(int b) { return a + b; } public int pow(int c) { return c * c; } public static void main(String[] args) { Test t = new Test(); t.add(1); t.pow(2); } }上面代码中add(int b)这个方法就不符合函数式编程,这个函数调用后的结果不确定,它的结果不仅取决于b还取决于字段a。而pow(int c)这函数就是符合函数式编程的典范,只要调用它,输入的值c确定了返回值就肯定确定了。 在函数式编程中,函数也是一等公民,可以被当做参数传递,可以被赋值,被引用,可以把它当做一种数据类型来对待,如果你会使用javascript之类的语言就可以有更深的体会。如果要深入了解这种编程范式可以自行网上搜素资料了解。2、lambda表达式lambda表达式是jdk8中的新特性,上面讲函数式编程就是引入这个,oracle在jdk8中引入了lambda,从此Java中开始对函数式编程的部分支持。 Java中lambda表达式的语法结构:(params) -> expression由三部分构成,第一部分是括号以及括号内部的形式参数,第二部分是->箭头符号,第三部分是expression方法体,方法体可以是代码块也可以是执行表达式。// lambda 表达式 完整状态 有入参 有返回 有代码块 (int a, int b) -> { int c = a + b; return c; } // 当代码不需要返回值 则可省去 return (int a, int b) -> { int c = a + b; } // 当代码只有一句话的时候可以省去 大括号 (int a, int b) -> a + b; // 同样可以省略形参类型 (a, b) -> a + b; // 当只有一个参数时, 可以省去形参的小括号 a -> a * a;接下来使用lambda表达式来定义和实现一个函数式接口:@FunctionalInterface public interface ITest { int add(int a, int b); }内部匿名类实现方式:public static void main(String[] args) { ITest iTest = new ITest() { @Override public int add(int a, int b) { return a + b; } }; iTest.add(1, 1); }Lambda实现方式: public static void main(String[] args) { ITest t = (a, b) -> a + b; t.add(1, 1); }使用lambda表达式会使代码更加的优雅3、使用双冒号::符号对上面的Lambda实现方式进行进步一步的优化:public static void main(String[] args) { ITest t = Integer::sum; t.add(1, 1); }双冒号的使用方式:类名::静态方法名或者 类的实例::实例方法4、Optional类Optional也是jdk8中的一个新的类的,它给予我们更加优雅的方式来处理Java语言中的NPE异常。可以从一定程度上代替if判断, 介绍相关接口:empty 创建一个空的Optional对象of 和ofNullableof创建一个Optional对象, 如果传入的参数为空则跑出NPE异常.ofNullable和上面一样, 但是当传入参数为空的时候会调用empty方法创建一个空Optional对象.Optional<String> of = Optional.of("waxxd"); // 传入空参数会抛出NullPointerException异常 Optional<String> ofNull = Optional.of(null); // 以下两句都正常执行 Optional<String> ofNullable = Optional.ofNullable("waxxd"); // 参数为空的时候相当调用Optional.empty() Optional<String> ofNullableNull = Optional.ofNullable(null); get/orElse/orElseGet/orElseThrow// get 获取Option包裹的值如果值为null则抛出NoSuchElementException异常 String aa = Optional.of("aa").get(); // orElse 获取值如果值为空则返回orElse设置的默认值 String aa1 = Optional.of("aa").orElse("bb"); // orElseGet 获取值如果值为空则内部可以是一个实现Supplier接口的匿名内部类调用提供返回结果 String aa2 = Optional.of("aa").orElseGet( () -> "aaa".toUpperCase()); // orElseThrow获取值如果不存在则抛出后面的异常 Optional.empty().orElseThrow(IllegalArgumentException::new); // 实际的应用, 也就是上文所说的如何优化if // 比如你有个接口, 用户传入参数Integer type, 用户也可以选择不传, 不传我们为它设置默认值1 public void f(Integer type){ if(type = null) { type = 1; } Optional.ofNullable(type).orElse(1); }
2023年07月10日
128 阅读
0 评论
0 点赞
GraalVM将Java打包原生Native应用
2023年07月10日
222 阅读
0 评论
0 点赞
2023-07-10
GraalVM 是一种高性能 JDK,旨在加速 Java 应用程序性能,同时消耗更少的资源。 它提供了 Graal 编译器,它可以用作即时编译器,在 HotSpot JVM 上运行 Java 应用程序或提前将它们编译为本机可执行文件。除了Java,它还为JavaScript,Ruby,Python和其他几种具有多语言功能的流行语言提供了运行时。Graalvm下载地址 Releases · graalvm/graalvm-ce-builds (github.com))安装Graalvm环境由于本人电脑是macos则此处演示macos的安装和使用方法。在其他系统中安装方式大同小异,都是相当于添加一个新的jdk环境首先去官网下载对应自己平台和版本的包。我是MacOS M1,使用Java11环境,所所以此处我选择的是 macOS(aarch64)的包。下载完成后进行解压,移动到指定位置sudo mv graalvm-ce-java11-22.3.1 /Library/Java/JavaVirtualMachines/然后删除隔离属性 sudo xattr -r -d com.apple.quarantine /Library/Java/JavaVirtualMachines/graalvm-ce-java11-22.3.1添加环境变量添加完环境变量后使其生效如果输入java -version 输出 OpenJDK Runtime Environment GraalVM CE 22.3.1 (build 11.0.18+10-jvmci-22.3-b13)则表示环境已经添加成功了,整个步骤就是在添加一个新的Java环境IDEA集成Graalvm在IDEA新增项目,并在新增界面添加新的JDKAdd JDK,新建项目并编写一个main方法在mavenpom.xml中增加graalvm的打包插件<build> <plugins> <plugin> <groupId>org.graalvm.buildtools</groupId> <artifactId>native-maven-plugin</artifactId> <configuration> <!-- imageName用于设置生成的二进制文件名称 --> <imageName>${project.artifactId}</imageName> <!-- mainClass用于指定main方法类路径 --> <mainClass>com.bystart.Main</mainClass> <buildArgs> --no-fallback </buildArgs> </configuration> </plugin> </plugins> </build>打包测试输入打包命令进行打包mvn -Pnative native:compile或者使用IDEA的maven工具打包运行测试
2023-07-07
SpringBoot集成Redis发布订阅模式
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。Redis 客户端可以订阅任意数量的频道。新建SpringBoot项目POM添加依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>添加配置在application.yml中配置redis连接信息:server: port: 8888 spring: datasource: redis: host: 127.0.0.1 port: 6379 cache: type: redis创建redis配置类package com.bystart.redis.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; public class RedisConfig { @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(mapper); template.setValueSerializer(jackson2JsonRedisSerializer); //使用StringRedisSerializer来序列化和反序列化redis的key值 template.setKeySerializer(new StringRedisSerializer()); template.afterPropertiesSet(); return template; } }监听主题处理监听到的消息package com.bystart.redis.listener; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import javax.annotation.Resource; @Component public class RedisMessageListener implements MessageListener { @Resource private RedisTemplate redisTemplate; @Override public void onMessage(Message message, byte[] pattern) { // 解析消息体 byte[] messageBody = message.getBody(); // 使用值序列化器转换 Object msg = redisTemplate.getValueSerializer().deserialize(messageBody); // 获取监听的主题 byte[] channelByte = message.getChannel(); // 使用字符串序列化器转换 Object channel = redisTemplate.getStringSerializer().deserialize(channelByte); // 主题名称转换 String patternStr = new String(pattern); System.out.println(patternStr); System.out.println("---主题---: " + channel); System.out.println("---消息内容---: " + msg); } }配置监听主题和消费者package com.bystart.redis.config; import com.bystart.redis.listener.RedisMessageListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; @Configuration public class RedisSubConfig { @Bean public RedisMessageListenerContainer container(RedisConnectionFactory factory, RedisMessageListener listener){ RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(factory); // 监听指定主题,将收到的消息移交给 RedisMessageListener 处理 container.addMessageListener(listener, new ChannelTopic("login.notice")); return container; } }推送测试新增一个controller:package com.bystart.redis.controller; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class TestController { @Resource private RedisTemplate redisTemplate; @GetMapping public String test(@RequestParam String message) { redisTemplate.convertAndSend("login.notice", message); return "ok: " + message; } }访问http://127.0.0.1:8888?message=hello返回login.notice ---频道---: login.notice ---消息内容---: hello
2023年07月07日
71 阅读
0 评论
0 点赞
2023-07-07
将旧手机改造成Linux服务器
AidLux 是什么AidLux是一个构建在ARM硬件上,基于创新性跨Android/鸿蒙 + Linux融合系统环境的智能物联网 (AIoT) 应用开发和部署平台点我进入官网下载安装AidLuxAidLux 在各大手机的app应用商店均可下载到,下载安装后会进行初始化使用web端访问桌面打开桌面上的Cloud_ip应用会得到一个访问地址访问http://192.168.0.181:8000会要求输入密码,密码则是aidlux使用ssh远程登录我们可以通过ssh访问该系统:ssh root@192.168.0.181 -p 9022密码是aidlux
2023年07月07日
168 阅读
0 评论
0 点赞
IDEA整合SSM框架
2023年07月06日
85 阅读
0 评论
0 点赞
2023-07-06
创建项目打开IDEA-File-Project项目大致目录项目目录类型修改pom.xml添加maven依赖 <properties> <!-- 设置项目编码编码 --> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- spring版本号 --> <spring.version>4.3.5.RELEASE</spring.version> <!-- mybatis版本号 --> <mybatis.version>3.4.1</mybatis.version> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-impl</artifactId> <version>1.2.5</version> </dependency> <!-- 实现slf4j接口并整合 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.30</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <!-- JSON --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.7</version> </dependency> <!-- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> <scope>runtime</scope> </dependency> <!-- 数据源 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <!-- MyBatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!-- mybatis/spring整合包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>spring-ssm</finalName> </build>配置DispatcherServlet有关DispatcherServlet前端控制器的文章可以查看SpringMVC之DispatcherServlet前置控制器编辑web.xml<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>ssm</display-name> <!--添加防止乱码的过滤器--> <filter> <!--过滤器名称--> <filter-name>SetCharacterEncoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <!--设置CharacterEncodingFilter属性--> <!--encoding属性--> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <!--forceEncoding属性--> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <!--映射过滤器--> <filter-mapping> <!--使用哪个过滤器--> <filter-name>SetCharacterEncoding</filter-name> <!--配置全局路由需要使用这个过滤器--> <url-pattern>/*</url-pattern> </filter-mapping> <!--配置 DispatcherServlet 调度器--> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--初始化 DispatcherServlet--> <!-- SpringMVC通过web.xml文件中servlet标签下的DispatcherServlet类完成自身的初始化--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-*.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!--映射所有请求到 DispatcherServlet 调度器--> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 默认首页 --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> 在这里提一嘴,很多同学不太明白拦截器和过滤器的区别,现在跟大家解释一下两者的区别:拦截器是基于Java的反射机制的,而过滤器则是基于函数的回调拦截器是实现HandleInterceptor,过滤器则是实现Filter接口拦截器不依赖于Servlet容器,过滤器依赖于Servlet容器拦截器使用来验证请求,能截断请求。过滤器用来设置request,response参数、属性,侧重对数据的过滤过滤器在拦截器之前执行过滤器是tomcat服务器创建的对象,拦截器是springmvc容器创建的对象过滤器可以处理jsp、js、html等;拦截器是侧重拦截Controller的对象,如果你的请求不能被DispatcherServlet接收,这个请求不会执行拦截器的内容拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑配置SpringMVC在classpath目录下也就是resources目录下新增spring-mvc.xml配置文件,写入:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd "> <!--扫描控制器的包路径--> <context:component-scan base-package="com.bystart.ssm.controller"/> <!--开启springmvc模式--> <mvc:annotation-driven/> <!--静态资源默认servlet配置--> <mvc:default-servlet-handler/> <!--配置jsp 显示viewResolver --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> </beans>集成MySQL、MyBatis同样是是在resources目录下,首先先创建mysql的连接配置文件jdbc.propertiesjdbc.driver=com.mysql.jdbc.Driver #数据库地址 jdbc.url=jdbc:mysql://127.0.0.1:3306/ssmdb?useUnicode=true&characterEncoding=utf8&useSSL=false #用户名 jdbc.username=root #密码 jdbc.password=123456 #最大连接数 c3p0.maxPoolSize=30 #最小连接数 c3p0.minPoolSize=10 #关闭连接后不自动commit c3p0.autoCommitOnClose=false #获取连接超时时间 c3p0.checkoutTimeout=10000 #当获取连接失败重试次数 c3p0.acquireRetryAttempts=2继续添加spring-mybatis.xml:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--配置数据库相关信息--> <!--读取数据库的连接配置信息--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--构建数据库连接池--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxPoolSize" value="${c3p0.maxPoolSize}"/> <property name="minPoolSize" value="${c3p0.minPoolSize}"/> <property name="autoCommitOnClose" value="${c3p0.autoCommitOnClose}"/> <property name="checkoutTimeout" value="${c3p0.checkoutTimeout}"/> <property name="acquireRetryAttempts" value="${c3p0.acquireRetryAttempts}"/> </bean> <!--配置SqlSessionFactory对象--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--注入数据连接池--> <property name="dataSource" ref="dataSource"/> <!--扫描entity包 使用别名--> <property name="typeAliasesPackage" value="com.bystart.ssm.model"/> <!--扫描mapper文件--> <property name="mapperLocations" value="classpath:mapper/*.xml"/> </bean> <!--配置事务管理--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--注入数据连接池--> <property name="dataSource" ref="dataSource"/> </bean> <!--配置使用注解声明式事务--> <tx:annotation-driven transaction-manager="transactionManager"/> <!--扫描Dao接口包 自动注入到spring容器--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--注入sqlSessionFactory--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!--dao接口包路径--> <property name="basePackage" value="com.bystart.ssm.dao"/> </bean> <!--扫描dao包下所有使用注解的类型--> <context:component-scan base-package="com.bystart.ssm.dao"/> <!--扫描service包下所有使用注解的类型--> <context:component-scan base-package="com.bystart.ssm.service"/> </beans> 添加日志输出新增logback-spring.xml同样是在resources目录下<?xml version="1.0" encoding="UTF-8"?> <configuration debug="true"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="STDOUT"/> </root> </configuration>实战从数据库查询数据数据库表结构:CREATE TABLE `sys_user` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', `username` varchar(32) NOT NULL COMMENT '用户名', `password` varchar(32) NOT NULL COMMENT '密码', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;插入数据:INSERT INTO `sys_user` (`id`, `username`, `password`) VALUES (1, 'sysadmin', '123456');编写数据表对应的JavaBean在包路径com.bystart.ssm.model下创建数据库表对应的Java类实体package com.bystart.ssm.model; public class SysUserEntity { /** * 自增id */ private Long id; /** * 用户名 */ private String username; /** * 密码 */ private String password; public SysUserEntity() { } public SysUserEntity(Long id, String username, String password) { this.id = id; this.username = username; this.password = password; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "SysUserEntity{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + '}'; } }编写数据交互层DAO在包com.bystart.ssm.dao路径下添加接口package com.bystart.ssm.dao; import com.bystart.ssm.model.SysUserEntity; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.List; public interface SysUserDao{ /** * 查询所有的用户 * */ List<SysUserEntity> getUserList(); /** * 根据用户名查询指定用户 * */ SysUserEntity getUserByUsername(@Param("username") String username); }编写SysUserDao.xml在resources-mapper目录下新增SysUserDao.xml<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.bystart.ssm.dao.SysUserDao"> <select id="getUserList" resultType="com.bystart.ssm.model.SysUserEntity"> select * from sys_user </select> <select id="getUserByUsername" resultType="com.bystart.ssm.model.SysUserEntity"> select * from sys_user where username = #{username} </select> </mapper>编写业务层接口在com.bystart.ssm.service新增SysUserService接口,并提供两个方法package com.bystart.ssm.service; import com.bystart.ssm.model.SysUserEntity; import java.util.List; public interface SysUserService { /** * 查询所有的用户 * */ List<SysUserEntity> getUserList(); /** * 根据用户名查询用户的信息 * @param username 用户名查询条件 * */ SysUserEntity getUserByUsername(String username); }添加service的实现类,在com.bystart.ssm.service.impl包下新增SysUserServiceImpl实现类package com.bystart.ssm.service.impl; import com.bystart.ssm.dao.SysUserDao; import com.bystart.ssm.model.SysUserEntity; import com.bystart.ssm.service.SysUserService; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; @Service public class SysUserServiceImpl implements SysUserService { @Resource private SysUserDao dao; @Override public List<SysUserEntity> getUserList() { return dao.getUserList(); } @Override public SysUserEntity getUserByUsername(String username) { return dao.getUserByUsername(username); } }编写controllercom.bystart.ssm.controller包下新增SysUserControllerpackage com.bystart.ssm.controller; import com.bystart.ssm.model.SysUserEntity; import com.bystart.ssm.service.SysUserService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import java.util.List; @Controller public class SysUserController { @Resource private SysUserService service; /** * 查询用户列表并返回到JSP进行数据渲染 */ @RequestMapping("/getUserList") public String getUserList(Model model) { List<SysUserEntity> userList = service.getUserList(); model.addAttribute("userList", userList); // 返回到 webapp目录下的 WEB-INF > views > userList.jsp return "userList"; } /** * 根据用户名查询指定用户 * 将查询到的数据以json形式返回到页面 * * @param username 用户名 */ @RequestMapping("/getUserByUsername") @ResponseBody public SysUserEntity getUserByUsername(@RequestParam String username) { SysUserEntity user = service.getUserByUsername(username); return user; } }编写JSP页面在webapp -> WEB-INF -> views目录下新增userList.jsp:<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%-- Created by IntelliJ IDEA. User: bystart Date: 2023/7/6 Time: 15:32 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>Title</title> </head> <body> <table border=1> <thead> <tr> <th>序号</th> <th>用户名</th> <th>密码</th> </tr> </thead> <tbody> <c:forEach items="${userList}" var="user"> <tr> <th>${user.id}</th> <th>${user.username}</th> <th>${user.password}</th> </tr> </c:forEach> </tbody> </table> </body> </html>配置tomcat配置好tomcat后即可运行起来测试发起请求获得数据我们编写的SysUserController中有两个接口,一个会返回页面,一个会返回json数据我们在浏览器中请求http://localhost:8080/ssm/此处的地址可以在这里查看在浏览器访问http://localhost:8080/ssm/getUserList再去访问http://localhost:8080/ssm/getUserByUsername?username=sysadmin如果能跟我一样正常显示,说明ssm框架搭建完成,并且可以跟数据库进行交互
2023-07-05
使用SSH在终端畅聊
Devzat 是一个自定义 SSH 服务器,可带您进行聊天而不是 shell 提示。因为所有平台(甚至手机)上都有 SSH 应用程序,所以您可以在任何设备上连接到 Devzat项目仓库Devzat利用SSH进入聊天室:ssh devzat.hackclub.com使用自定义昵称进入聊天室:ssh nickname@devzat.hackclub.com如果无法顺利进入聊天室可以尝试:ssh devzat.hackclub.com -p 443如果您将其添加到~/.ssh/config:Host chat HostName devzat.hackclub.com您只需以下方式即可加入:ssh chat
2023年07月05日
92 阅读
0 评论
0 点赞
1
2
3