Java程序猿搬砖笔记(十一)

Hexo博客 Next主题图片防盗链问题

问题场景:打开博客,所有引用外部链接的图片均无法正常加载,但是所有图片复制链接在浏览器请求是可以加载的。
问题原因:目标网站图片设置了防盗链。
解决方案:在 \themes\next\layout_partials\head.swig文件中加一行代码即可。
在这里插入图片描述
参考链接参考链接

Springboot Druid数据库密码加密配置步骤

方式一:

  • 找到druid包的位置,CMD命令行执行下面的命令
1
java -cp druid-1.2.6.jar com.alibaba.druid.filter.config.ConfigTools 数据库密码 > pwd.txt
  • 把项目中的解密公钥和密文改为pwd.txt中的publicKey、password

方式二:

  • 在项目中运行下面的代码:
1
2
3
4
5
6
7
8
public static void main(String[] args) throws Exception {
String password = "a123456";
String[] arr = ConfigTools.genKeyPair(512);
System.out.println("password:" + password);
System.out.println("privateKey:" + arr[0]);
System.out.println("publicKey:" + arr[1]);
System.out.println("password:" + ConfigTools.encrypt(arr[0], password));
}
  • 把项目中的解密公钥、密文分别改为上面代码中输出的publicKey、password

注意:

  • Druid的版本一定要一致
    用druid-1.1.9.jar生成的公钥和密文在druid-1.2.6.jar中项目直接解密失败
  • 公钥和密文一定要同时替换
    同一个Jar包多次生成公钥,前后几个字符串是一样的,但是中间的不一样。

参考链接参考链接

Java统计字符串出现的次数

  • 方法一:使用Java8的流和Lambda表达式
    代码示例:
1
2
3
String str = "你好/454/545/";
long count = str.chars().filter(ch -> ch == '/').count();
System.out.println(count);

返回结果:
3

  • 方法二:使用Spring框架中的StringUtils
1
int count = StringUtils.countOccurrencesOf("你好/454/545/", "/");
  • 方法三:使用commons-lang3工具类中的StringUtils
1
int count = StringUtils.countMatches("你好/454/545/", "/");
  • 方法四:使用HashMap

该方法可以统计字符串中每个字符出现的次数:

1
2
3
4
5
6
7
8
9
10
11
12
private static Map<Character, Integer> countsOfCharacter(String str){
char[] chars = str.toCharArray();
Map<Character, Integer> map = new HashMap();
for (char c : chars) {
if (map.containsKey(c)) {
map.put(c, map.get(c) + 1);
}else{
map.put(c,1);
}
}
return map;
}

调用示例:

1
2
3
String str = "你好/454/545/";
Map<Character, Integer> map = countsOfCharacter(str);
System.out.println(map.get("/".charAt(0)));

返回结果:
3

参考链接

Java获取某个字符在字符串中出现第N次的位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* 获取某个字符在字符串中出现第N次的位置
*
* @param: data 字符串
* @param: str 子字符串
* @param: num 子字符串出现的第N次
* @return int 字符串出现的位置,未匹配到返回-1
* @date 2022/11/1
*/
public static int getIndexOf (String data, String str, int num) {
Pattern pattern = Pattern.compile(str);
Matcher findMatcher = pattern.matcher(data);
// 标记遍历字符串的位置
int indexNum = 0;
while (findMatcher.find()) {
indexNum++;
if(indexNum == num){
break;
}
}
// 未匹配到返回-1
if(!data.contains(str) || indexNum < num || num<0){
return -1;
}
return findMatcher.start();
}

Maven激活指定profile

1
2
mvn package -P 待激活的profile
示例:mvn package -P dev

Maven中resources标签的用法详解

一旦pom当中添加resource,指定某一个文件,就会导致resources其他文件(java文件不会丢)打包的时候丢失。

1
2
3
4
5
6
7
8
9
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>a.properties</include>
</includes>
</resource>
</resources>

打包文件中只有a.properties。

另外,当filtering为false时,配置文件用@@,取不到值。

参考链接

MySQL 字符集不一致报错

Cause: java.sql.SQLException: Incorrect string value: ‘\xE9\x87\x91\xE5\x87\xA1…’ for column ‘username’ at row 1
; uncategorized SQLException for SQL []; SQL state [HY000]

检查建表时字符集:
在这里插入图片描述
在MySQL 8.0版本之前,默认字符集为latin1。

解决方法:
建表时添加默认字符集,示例代码如下:

1
2
COMMENT='用户信息历史表'
ENGINE=InnoDB DEFAULT CHARSET=utf8

EasyExcel日期格式化

添加@DateTimeFormat注解,参考代码如下:

1
2
3
4
5
import com.alibaba.excel.annotation.format.DateTimeFormat;
@ExcelProperty(value="申请日",index = 8)
@ColumnWidth(12)
@DateTimeFormat("yyyy/MM/dd")
private Date applyDate;

参考链接

@Configuration、@Component、@Controller等注解

@Configuration注解:

  • 本质上还是@Component
  • 配置类必须以类的形式提供(不能是工厂方法返回的实例),允许通过生成子类在运行时增强(cglib 动态代理)
  • 配置类不能是 final 类(没法动态代理)
  • 配置类必须是非本地的(即不能在方法中声明,不能是 private)
  • @Bean 方法可能不会反过来创建进一步的配置类(也就是返回的 bean 如果带有 @Configuration,也不会被特殊处理,只会作为普通的 bean)

@Component、@Controller、@Service、@Repository这四个注解实际上没有任何本质区别,只是后三者只是涉及一些命名规范而已,四者的注解效果确实一致。关于这里的命名规范就好比苹果叫苹果,你不会说苹果是菠萝。这样的好处显然易见,听到别人说苹果,你就知道是苹果,不会想到菠萝。
实际上这四个注解实际上没有任何本质区别,如果你喜欢,你完全可以把这四个注解当成一个注解用,当然这样的话老板可能就不喜欢你了。
参考链接参考链接

Java泛型方法

在方法中出现了泛型的结构,这样的方法叫做泛型方法。
泛型参数与类的泛型参数没有任何关系,换句话说,泛型方法所属的类是不是泛型类都没有关系
泛型方法可以声明为static。 方法使用类的泛型不能声明为static。

Java泛型-类型通配符:<?>

1
2
3
4
List<?>是List<String>、List<Object>等各种泛型List的父类。
<?>不能用在泛型方法、泛型类的声明上
不能在List<?>中添加元素(除了null)。
可以读取List<?>中的元素,类型为Object。

Java泛型-有限制的通配符(上下界)

  • 上界extends
    使用时指定的类型必须是继承某个类(或者实现某个接口),即**<=**
  • 下界super
    使用时指定的类型不能小于操作的类(或接口),即**>=**

示例代码如下:

定义类:

1
2
3
4
5
6
7
public class Order {

}

public class SubOrder extends Order{

}

测试通配符初始化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Test {
public static void main(String[] args) {
List<? extends Order> list1 = null;
List<? super Order> list2 = null;

List<Order> list3 = new ArrayList<>();
List<SubOrder> list4 = new ArrayList<>();
List<Object> list5 = new ArrayList<>();

list1 = list3;
list1 = list4;
// list1 = list5; // 编译报错

list2 = list3;
// list2 = list4;// 编译报错
list2 = list5;
}
}

测试通配符取值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Test {
public static void main(String[] args) {
List<? extends Order> list1 = null;
List<? super Order> list2 = null;

List<Order> list3 = new ArrayList<>();
List<SubOrder> list4 = new ArrayList<>();
List<Object> list5 = new ArrayList<>();

list1 = list4;
Order order = list1.get(0);
// SubOrder subOrder = list1.get(0); 编译报错

list2 = list3;
Object object = list2.get(0);
// Order order = list2.get(0); 编译错误
}
}

测试通配符添加值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Test {
public static void main(String[] args) {
List<? extends Order> list1 = null;
List<? super Order> list2 = null;

List<Order> list3 = new ArrayList<>();
List<SubOrder> list4 = new ArrayList<>();
List<Object> list5 = new ArrayList<>();

list1 = list4;
// list1.add(new SubOrder()); 编译错误
// list1.add(new Order()); 编译错误:因为?可能小于Order甚至比SubOrder都小。这儿不可以,根据多态上面也就不可以

list2 = list3;
list2.add(new Order());
list2.add(new SubOrder());// 多态
}
}

SpringBoot下mybatis-plus如何打印sql日志和参数到日志文件

参考链接(很详细)

Maven的mirror镜像和仓库

mirror简介

说明:

  • Maven优先从镜像中下载,找不到再从中央仓库(默认配置)下载
    默认中央仓库地址:https://repo.maven.apache.org/maven2
  • 可以配置多个
  • id可以随便写,不重复就行
  • name对仓库进行一些描述

如果配置多个mirror,首先按照搜索顺序优先级搜索,相同优先级的repository根据配置顺序搜索。

mirrorOf的不同类型

1
2
3
4
5
6
7
8
// 对所有仓库id镜像,你配置的所有仓库都不起作用了
mirrorOf=*?
// 镜像my-repo-id,你配置的my-repo-id仓库不起作用了
mirrorOf=my-repo-id
// !表示非运算,排除你配置的my-repo-id仓库,其他仓库都被镜像了。就是请求下载my-repo-id的仓库的jar不使用mirror的url下载,其他都是用mirror配置的url下载
mirrorOf=*,!my-repo-id?
// 如果本地库存在就用本地库的,如果本地没有所有下载就用mirror配置的url下载
mirrorOf=external:*?

仓库jar包下载顺序

1
本地仓库 -> settings_profile_repo -> pom_profile_repo -> pom_repositories -> settings_mirror -> central

仓库分类

在这里插入图片描述
(简书)Maven中配置mirrorOf和仓库
(CSDN)深入理解Maven的私服(Nexus)和仓库(Repository)以及settings中的mirror和mirrorOf

在windows环境下,后台运行jar包并打印后台日志

run.bat脚本如下:

1
2
3
4
@echo off
%1 mshta vbscript:CreateObject("WScript.Shell").Run("%~s0 ::",0,FALSE)(window.close)&&exit
java -jar reward-portal-2023-02-02.jar >StartupLog.log 2>&1 &
exit

注意:run.bat放在和jar包同一个目录

参考链接参考链接

停止Windows环境下的Java服务

1
2
3
4
5
6
// 查看进程号
// 下面两种方法都可以,端口号为SpringBoot项目的server.port
jps -l
netstat -aon|findstr "端口号"
// 停止服务
taskkill -f -pid 进程号