每天一个小知识
知识点一
最近开发项目时发现一件神奇的事情,使用@Data注解,也就是lombok下的
import lombok.Data
我们知道,这个注解是包含了setter、getter的,会自动帮助我们生成实体类中的所有setter、getter方法,使得代码简洁、优雅,但是问题出现了,
找不到符号,找不到我的getId、getter的其它方法,还有setter的方法也找不到,去它启动生成的target可以查看得到,确实是没有生成setter和getter的任何方法,甚至可能有的大佬,连实体类在target都没有生成出来。
查看网上,有以下几种情况:
1.Lombok插件是否安装,并且启用了注解解析器
2.第二种,就是有没有添加依赖,我觉得这是废话来的,没有依赖,我在编译的时候就出错了,准确来讲应该叫做有没有添加符合你jdk版本的lombok依赖,因为jdk17需要最低的lombok版本是1.8.22,其它的jdk可以自己去查一下
3.与lombok依赖冲突的其它依赖
1)MapStruct(代码生成库):MapStruct 和 Lombok 都是通过注解处理器生成代码,如果配置不当会导致 Lombok 未优先执行,无法生成 getter/setter。 因此在项目执行解析代码的时候,需要优先lombok执行
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<annotationProcessorPaths>
<!-- 先处理 Lombok -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</path>
<!-- 再处理 MapStruct -->
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
2)JPA/Hibernate(实体类注解)
JPA 的 @Entity 或 Hibernate 的注解可能依赖手动编写 getter/setter,而 Lombok 生成的代码未被正确识别。也就是启动项目的时候,jpa依赖先执行了,导致jpa出错,因此要么在实体类中显式添加 @Getter 和 @Setter,要么在编译配置中确保 Lombok 先执行
3)其它依赖
其它的依赖就不展开说了,如果大佬们在开发过程中添加了新的依赖,出现了这种问题,就说明依赖可能冲突了
其实前面的我都有做,但是我的问题还是没有解决
好了重头戏来了,你在编译代码的过程中,代码没有问题,但是运行之后,欸,bug就来了,是不是经常有遇到这种事情?关于这种事情,一般都是因为如果你没有特别指定,Java会选择它默认的配置去运行项目,而lombok也是
我查了一下这个Maven依赖管理中的版本解析机制,是这样子说的:
在Maven项目中,依赖的版本可以通过父POM、依赖管理(dependencyManagement)部分或者直接声明在依赖项中。如果用户的项目中使用了父POM(比如Spring Boot Starter Parent),父POM可能已经指定了Lombok的默认版本。如果父POM中的Lombok版本较旧,可能不支持JDK 17或存在其他兼容性问题,导致注解处理器无法正确生成代码。
因此我们要自己指定lombok版本,有的大佬会说了,我在dependencies中不是已经指定了吗?请注意,你是运行才出现报错的,运行的时候会先构建项目的,那就应该找build,而不是dependencies。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!--指定版本-->
<version>1.18.34</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
还有一个问题,一定跟你编译时的版本一致,不然也是会报错的,毕竟版本不一样,肯定是有东西是不一样的。也就是dependencies中的依赖版本与build中的版本一致才可以。
因为在我们开发的过程中,可能不仅只有一个项目,有可能一会jdk8,一会是jdk17,甚至就连lombok可能在不同的项目中,版本全都不一样,这是因为如果你之前运行成功过lombok,idea会把这个版本的设为默认的也是有可能的,因此要正确配置好lombok,一定要与你编译时的dependencies依赖的版本一致。
知识点二
这天,你刚刚下载安装并部署好elasticSearch服务器,心里还是非常高兴的,感觉自己终于控制住了代码,这个时候你要进行最后一步了,在自己的springboot项目中,连接es服务,突然:
[avax.net](https://avax.net/).ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at......
脑子嗡嗡的,非常感慨:做开发,最简单的事情其实是打代码,根本没有搞配置痛苦,由于做开发,每一个环节都是要很缜密的,稍微不慎,就会配置出错报错
好了,关于这个问题,我们要重新认识一下es服务器。es服务器刚刚安装部署的时候,不需要改动什么,就可以运行了,但是在启动es服务器的时候只要尝试过请求es服务,类似于:
都会知道,刚刚安装好的es服务器,默认的是https协议,而不是http,所以在springboot项目中连接es服务器的时候,是以下代码,https
httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "https");
但是由于是https,说明es是需要进行SSL认证的,出现上面的问题,就说明一个问题:es服务器与Java客户端在进行 SSL 握手时出现的问题,Java 客户端无法验证 Elasticsearch 服务器所提供的 SSL 证书。
问了一下大佬原因是什么,是这样子说的:
甚至大佬还告诉我解决办法:
1.导入服务器证书到 Java 信任库
1)导出服务器证书:运用 openssl 命令从 Elasticsearch 服务器导出证书
openssl s_client -showcerts -connect localhost:9200 </dev/null 2>/dev/null|openssl x509 -outform PEM > elasticsearch.crt
这里假设 Elasticsearch 服务器监听在 localhost:9200 ,你需要根据实际情况进行修改
2)导入证书到 Java 信任库:使用 keytool 命令将导出的证书导入到 Java 的信任库中
keytool -import -alias elasticsearch -file elasticsearch.crt -keystore $JAVA_HOME/jre/lib/security/cacerts
执行该命令后,会提示你输入信任库的密码,默认密码是 changeit。
由于我不搞这个方法,我就偷懒一点,直接复制大佬的方法了。
2.禁用证书验证(即修改为http)
当然改为http协议,那就在连接代码中也要修改:
httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
然后我们要到你es服务器中的文件夹中,找到config目录下的elasticsearch.yml文件,在这个文件下修改为如下再重启即可:
关于端口,你喜欢就好,没有写一般默认是9200的
好了,如果你使用了第二种方法,那从此请求es服务器看看是否启动了,就不用写多一个https了,直接localhost:9200即可。
当然,一般如果部署在生产环境中,一般建议是使用https协议,毕竟https协议更加安全一点嘛。
希望对大佬们有用,如果有哪里说的不太好的,欢迎各位大佬指正哦,或者有更好的办法的,大家也可以在评论区积极发言讨论哦!!!