lombok中@Data问题和elasticSearch连接问题

403 阅读6分钟

每天一个小知识

知识点一

最近开发项目时发现一件神奇的事情,使用@Data注解,也就是lombok下的

import lombok.Data

我们知道,这个注解是包含了setter、getter的,会自动帮助我们生成实体类中的所有setter、getter方法,使得代码简洁、优雅,但是问题出现了,

image.png

找不到符号,找不到我的getId、getter的其它方法,还有setter的方法也找不到,去它启动生成的target可以查看得到,确实是没有生成setter和getter的任何方法,甚至可能有的大佬,连实体类在target都没有生成出来。

查看网上,有以下几种情况:

1.Lombok插件是否安装,并且启用了注解解析器

image.png

image.png

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)其它依赖

其它的依赖就不展开说了,如果大佬们在开发过程中添加了新的依赖,出现了这种问题,就说明依赖可能冲突了

其实前面的我都有做,但是我的问题还是没有解决

image.png

好了重头戏来了,你在编译代码的过程中,代码没有问题,但是运行之后,欸,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服务,类似于:

image.png

都会知道,刚刚安装好的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 证书。

问了一下大佬原因是什么,是这样子说的:

image.png

甚至大佬还告诉我解决办法:

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文件,在这个文件下修改为如下再重启即可:

d9d348cbb4f88535ec0592f90cd5b6d.png

关于端口,你喜欢就好,没有写一般默认是9200的

好了,如果你使用了第二种方法,那从此请求es服务器看看是否启动了,就不用写多一个https了,直接localhost:9200即可。

当然,一般如果部署在生产环境中,一般建议是使用https协议,毕竟https协议更加安全一点嘛。

希望对大佬们有用,如果有哪里说的不太好的,欢迎各位大佬指正哦,或者有更好的办法的,大家也可以在评论区积极发言讨论哦!!!