开发过程中遇到问题

问题导航:

1) http请求参数带有空格,接收端解析后乱码

2) Mybatis传参无效

3)nginx反向代理下载文件失败

4) idea导入多个maven项目到同一目录下

5)MySQL中关于useSSL的警告,导致无法连接数据库

6)HttpClient有三个超时参数:ConnectionRequestTimeout、ConnectTimeout、SocketTimeout

7) springcloudfeign 连接服务Connection time out

8)docker容器自动重启策略

使用portainer后台 ,stop容器后,又自动重启了

9)kafka - consumer处理业务超时,导致无法正常提交Offset,重复消费

10)springboot2.0 + mybatis+clickhouse+mysql 多数据源配置

1:项目启动报错

Unable to determine Dialect to use [name=ClickHouse, majorVersion=20]; user must register resolver or explicitly set 'hibernate.dialect'

Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

2:动态数据源注解 @DateSource 声明在类上,aop无法拦截(不可用)

11)通过druid连接池,连接clickhouse集群

12)mybatis插入mysql,差8小时

与时区有关,utc 坑

13) Feign消费服务时POST/GET请求方式

14)springboot @RestController ,如何返回空json串 {}

15)docker容器中无jvm监控工具(jps、jmap等)

16)mysql链接提示: Access denied for user 'opetester'@'10.31.108.5' (using password: YES)

17)表删除数据时: Cannot delete or update a parent row: a foreign key constraint fails,有外键关联

18)zuul网关请求参数重组,加解密等

19)request获取不到自定义header参数

20)start.sh脚本无法启动,原因是win下编写,unix环境下不可用

21)根据子网掩码过滤ip

22)mysql取消外键关联 SET FOREIGN_KEY_CHECKS=0

23) springboot @ComponentScan 扫描第三方jar(feignclient),提示:

Consider defining a bean of type 'XXX' in your configuration.

24) start.sh 脚本中 JAVA_MEM_OPTS= "-XX:MaxMetaspaceSize=128m -Xms1G -Xmx1G -Djava.ext.dirs=lib" ,导致启动失败 SunTls12MasterSecret KeyGenerator not available

25)集成security后,提示“ The request was rejected because the URL was not normalized

26)springboot中 @Value 获取user.dir

27)使用poi上传超大excel,抛内存溢出

28)springBoot中使用@Value()并设置默认值后,只能获取默认值,并不能获取配置文件中的值

29)mysql表字段是关键字,插入是报语法错误,如何向关键字列插入数据


一。http请求参数带有空格

1。描述:

http请求参数中带有空格,经过urlencode编码后,空格会转成+,这样接收端也会解析成+,而不是空格

2。方案: 带有空格的参数,经过urlencode编码后,将+替换成%20 ,%20是空格的 URL 字符编码,这样服务端解析时,会将%20解析成空格


二。Mybatis传参无效

1。描述:

mybatis向xml中传递参数,字符串0,经过以下判断不生效

< if test="param.intype == ‘0'" >

</if>

2。原因:

传入单字符时,OGNL将会识别为java的char类型,而不是string类型

上面描述中,传入的字符串0,是单字符,但是OGNL将字符串0识别为java的char类型 ‘0’,而不是string类型,char与string类型无法相等,推荐使用解决方案2

3。方案1:

使用数字型判断,直接等于0

< if test="param.intype ==0" > </if>

方案2: 推荐使用

< if test= ' param.intype == " 0 "' > </if>

深层原因:

转: mybatis if标签 test中判断0错误

Interpreting Objects as Booleans
Any object can be used where a boolean is required. OGNL interprets objects as booleans like this:

  • If the object is a Boolean, its value is extracted and returned;
  • If the object is a Number, its double-precision floating-point value is compared with zero; non-zero is treated as true, zero as false;
  • If the object is a Character, its boolean value is true if and only if its char value is non-zero;
  • Otherwise, its boolean value is true if and only if it is non-null.


果然,如果对象是一个Number类型,值为0时将被解析为 false ,否则为 true ,浮点型0.00也是如此。OGNL对于boolean的定义和JavaScript有点像,即 '' == 0 == false 。这也就不难理解 <if test="status != null and status !=''">and status = #{status}</if> 当status=0时出现的问题了,显然 0!='' 是不成立的,导致表达式的值为false。
将表达式修改为 <if test="status != null">and status = #{status}</if> 该问题便迎刃而解。该 问题的根源还是来自编码的不规范 ,只有String类型才需要判断是否 !='' ,其他类型完全没有这个必要,可能是开发人员为了省事直接复制上一行拿过来改一改或是所使用的MyBatis生成工具不严谨导致该问题的发生。
这里有必要再提一个“坑”,如果你有类似于 String str ="A"; <if test="str!= null and str == 'A'"> 这样的写法时,你要小心了。因为单引号内如果为 单个字符 时,OGNL将会识别为Java 中的 char类型,显然String 类型与char类型做 == 运算会返回 false ,从而导致表达式不成立。解决方法很简单,修改为 <if test='str!= null and str == "A"'> 即可。


三。nginx反向代理下载文件失败

1。描述:

nginx在做反向代理,在客户端下载文件时,总是下载到一定的大小,就下载不动,查看后端服务器,表现正常,在绕过前端反向代理,直接从后端下载,也正常。

2。原因:


nginx反向代理下载文件失败处理 - 哈哈呵h - 博客园

配置nginx反向代理时,要注意的权限设置 - itestAndy - 博客园


四。 idea导入多个maven项目到同一目录下

Idea导入多个maven项目到同一目录下 - 东北小狐狸 - 博客园


五。MySQL中关于useSSL的警告,导致无法连接数据库

在本地开发时,本地无SSL相关证书,导致java连接数据库时失败 添加useSSL=false即可

jdbc.url=jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8

通过SHOW VARIABLES LIKE '%ssl%' 查看mysql是否开启SSL认证:

Mysql 开启ssl连接_背锅浩的博客-CSDN博客_mysql ssl


六。HttpClient有三个超时参数:ConnectionRequestTimeout、ConnectTimeout、SocketTimeout

ConnectionRequestTimeout:httpclient使用连接池来管理连接,这个时间就是从连接池获取连接的超时时间,可以想象下数据库连接池

ConnectTimeout:连接建立时间,三次握手完成时间

SocketTimeout:数据传输过程中数据包之间间隔的最大时间


七。springcloudfeign 连接服务Connection time out

问题:本地服务调试,调取了测试环境中docker的服务,发生Connecton time out;通过查看注册中心,本地服务已成功注册到中心,但是注册ip与docker中提供的服务ip不一致

其原因: 服务提供方使用 docker 容器部署,注册ip使用的是容器ip,本地开发的 服务调用方与服务提供方不能够 ping通,导致 connect timed out

解决方案: 1.在同一个docker服务中部署服务调用方

2.测试时,全在本地起服务(包括要调取的服务),使用不同端口

1 、 2 的目的都是保证 本地服务 与 要访问的服务在同一网络内

3.通过url直连微服务:

@FeignClient(value= "微服务", url = "https://{ip}:{port}" )

可通过测试机ip, 测试机与docker服务绑定的端口,访问docker服务

url 用于配置指定服务的地址,相当于直接请求这个服务,不经过 Ribbon

的服务选择。调试可用

其他情况:如果注册中心含有多个命名空间,则需要保证 调用方、提供方的微服务 在同一个命名空间下,即:spring.cloud.discovery.namespace 保持一致,否则也会出现上述问题

参考: Spring Cloud Feign调用异常:feign.RetryableException: connect timed out executing POST http://xxx


通过以上:

假设网关ip 192.168段 ,业务都部署在docker中,其ip时10.0段,网关、业务都注册到eureka中:此时,外部通过网关访问业务时访问不同的(192.168 无法ping通10.0段);反过来,网关部署docker,业务传统部署都是192.168段,若docker中可以ping通192.168段,则通过网关可以方位业务

八。docker容器自动重启策略

no: 不自动重新启动容器(默认)

no-failure: 容器发生error而退出(容器退出状态不为0)重启容器

unless-stopped: 在容器已经stop掉或Docker stoped/restarted的时候才重启容器

always: 如果容器停止,总是重新启动容器。如果手动kill容器,则无法自动重启。

compose文件中设置

condition:值可以为 none 、on-failure 以及 any(默认)

参考: docker 容器 自启动策略 restart policy


九。kafka - consumer处理业务超时,导致无法正常提交Offset,重复消费

主要关注:

max.poll.interval.ms

session.timeout.ms

heartbeat.interval.ms

kafka消费报错 Offset commit cannot be completed since the consumer is not part of an active group for auto partition assignment;

Kafka Consumer配置

kafka故障排查-consumer处理超时导致的异常_走在IT路上的技术博客_51CTO博客

kafka springboot 集成配置+测试


十。springboot2.0 + mybatis+clickhouse+mysql 多数据源配置

Spring Boot:实现MyBatis动态数据源 配置多数据源方式

Spring Boot2.x + Druid动态数据源切换

#mysql
spring.datasource.mysql.jdbcUrl=jdbc:mysql://localhost:3307/test?characterEncoding=UTF-8&useSSL=falsespring.datasource.mysql.username=rootspring.datasource.mysql.password=123spring.datasource.mysql.driver-class-name=com.mysql.jdbc.Driverspring.datasource.mysql.max-active=5spring.datasource.mysql.max-idle=3spring.datasource.mysql.test-on-borrow=truespring.datasource.mysql.test-while-idle=truespring.datasource.mysql.validation-query=SELECT 1;#clickhousespring.datasource.clickhouse.jdbcUrl=jdbc:clickhouse://localhost:8123/testspring.datasource.clickhouse.username=defaultspring.datasource.clickhouse.password=1233spring.datasource.clickhouse.driver-class-name=ru.yandex.clickhouse.ClickHouseDriverspring.datasource.clickhouse.max-active=5spring.datasource.clickhouse.max-idle=3spring.datasource.clickhouse.test-on-borrow=truespring.datasource.clickhouse.test-while-idle=truespring.datasource.clickhouse.validation-query=SELECT 1;

1:项目启动报错-clickhouse

Unable to determine Dialect to use [name=ClickHouse, majorVersion=20]; user must register resolver or explicitly set 'hibernate.dialect'

Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

问题发生原因:

通过日志,在查看pom.xml,发现项目中同时使用了两个orm框架:

一个mybatis, 一个jpa

< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-data-jpa</ artifactId >
</ dependency >

但是: jpa没有提供clickhouse的方言,所已抛出上面异常

解决方案

第一种:项目中继续使用springboot-data-jpa

因为 clickhouse支持mysql的语法,所以可以直接用mysql的方言,方言可以在yml配置文件里面配置,也可以在后面配置类里面配置,我这里选中配置文件中配置:

application.propertise中增加如下:

注: MySQL55Dialect 版本 ,不同版本使用的mysql驱动不一致

启动项目,运行成功

第二种: 纯springboot 是可以集成clickhouse的,我们使用mybatis完全替换掉spring-data-jpa(去除项目中jpa引用) ,项目成功运行

参考: SpringBoot集成JPA和Clickhouse数据库

jpa是否支持clickhouse?-Java-CSDN问答

2:动态数据源注解 @DateSource 声明在类上,aop无法拦截(不可用)

注解作用在类上进不去aop

貌似是@annotation表达式只会在方法上找注解

类上定义的注解找不到

在需要拦截的方法上加注解就可以了!

参考: aop使用注解拦截无效(ElementType.TYPE 不生效)

标注在接口上的注解无效,无法使用aop拦截,即使声明了@Inherited_my_wings的博客-CSDN博客

十一。通过druid连接池,连接clickhouse集群

1)增加druid的引用(1.2.5以上)

2)由于项目采用动态数据源,所以配置如下

支持一下 clickhouse的 BalancedClickhouseDataSource · Issue #3984 · alibaba/druid

JDBC连接clickhouse cluster


十二。mybatis插入mysql,差8小时

发生情况:升级mysql驱动包到8.0.22

原因:与时区有关,utc 坑 ,与中国东八区差8个小时

解决方案:jdbcurl后边拼接参数 serverTimezone=Asia/Shanghai

serverTimezone=UTC的那些坑_baidu_38837718的博客-CSDN博客_servertimezone=utc

十三。Feign消费服务时POST/GET请求方式

什么时候post,什么时候get

Feign消费服务时POST/GET请求方式_JustryDeng-CSDN博客_feign post

十四。springboot@RestController ,如何返回空json串 {}

问题:如下图,当p为null时,返回方法返回值并未显示空json串{},而是显示一个未初始化的Person对象(json格式)

上图,当p=null时,返回结果如下:我们期待返回空字符串

解决:如果返回空json串,代码修改如下:

return new ResponseEntity<>(HttpStatus. NO_CONTENT );


十五。docker容器中无jvm监控工具(jps、jmap等)

dx3088:Docker容器中无jvm监控工具(jps、jstack、jmap)

十六。 mysql链接提示: Access denied for user 'opetester'@'10.31.108.5' (using password: YES)

1)通过查询 user表,发现 opetester 已经授权

2)为不影响业务,现在mysql配置文件my.ini中增加 skip-grant-tables,该命令跳过授权表,就是说谁都能进入MySQL看到所有数据表,输入任意字符账号密码都可以,当忘记账号密码时可以使用改命令修改密码,但是要随用随关,重启mysql,不然服务器上会有很大的风险。

MySQL的skip-grant-tables_bisal的专栏-CSDN博客

3) 授权问题

解决mysql"Access denied for user'root'@'IP地址'"问题

深入分析MySQL ERROR 1045 (28000)

十七。表删除数据时: Cannot delete or update a parent row: a foreign key constraint fails,有外键关联

SET foreign_key_checks = 0; // 关闭外键检查约束

删除表数据

SET foreign_key_checks = 1;//恢复外键检查约束

通过 show VARIABLES like "foreign%",查看外键约束是否正常

十八。zuul网关请求参数重组,加解密等

Zuul网关之解析重组GET\POST\PUT请求并支持contentType=“multipart/form-data”

zuul转发请求之重组参数_leebin_20的博客-CSDN博客

十九 。request获取不到自定义header参数

例如header中自定义参数is_decode ,后台request获取不到该参数,与nginx的配置有关系,nginx会默认去除属性名包含下划线“_”的属性

解决方案: 修改nginx配置 ,或者header参数去除“_”

二十。start.sh脚本无法启动,原因是win下编写,unix环境下不可用

执行sed -i "s/\r//" start.sh ,确保文件在unix环境可用

二十一。根据子网掩码过滤ip

Validate an IP Address (with Mask)

二十三。 springboot @Compo nentScan({"com.my.test1","com.eversec.my.test2"}) 扫 描第三方jar(feignclient),提示: Consider defining a bean of type 'XXX' in your configuration.

解决:

当使用的feignClients 来自引用别的工程时,需要指定包名,如果不指定就算使用ComponentScan 扫描也不行

如果不写包名默认找启动类包下面的feignClient ,如果引用第三方jar,需要指定第三方jar的路径(将本工程路径、第三方jar路径都要写进去)

@EnableFeignClients({"com.my.test1","com.eversec.my.test2"})

二十四。 start.sh 脚本中 JAVA_MEM_OPTS= "-XX:MaxMetaspaceSize=128m -Xms1G -Xmx1G -Djava.ext.dirs=lib" ,导致启动失败 SunTls12MasterSecret KeyGenerator not available

问题原因:参考 java djava_Java -Djava.ext.dirs启动的坑

java.security.NoSuchAlgorithmException: SunTlsRsaPremasterSecret KeyGenerator not available · Issue #2 · softprops/nescala-rsvps

-Djava.ext.dirs是通过设置系统属性的方式也加载jar包的,这个级别就有点高,和-classpath的区别在于-Djava.ext.dirs会覆盖Java本身的ext设置,java.ext.dirs指定的目录由ExtClassLoader加载器加载,如果您的程序没有指定该系统属性(-Djava.ext.dirs=d:\libs)那么该加载器默认加载$JAVA_HOME/lib/ext目录下的所有jar文件。但如果你手动指定系统属性且忘了把$JAVA_HOME/lib/ext路径给加上,那么ExtClassLoader不会去加载$JAVA_HOME/lib/ext下面的jar文件,这意味着你将失去一些功能,例如java自带的加解密算法实现。


解决方案: 第一种:删除-Djava.ext.dirs=lib ,使用系统默认的$JAVA_HOME/lib/ext

第二种:将ext下相关jar包复制到新的ext director。

第三中:在-D.java.ext.dirs中配置多个目录。可以使用冒号分隔(windows下使用分号)。

二十五 。集成security后,提示“ The request was rejected because the URL was not normalized

转自: The request was rejected because the URL was not normalized

二十六。springboot中 @Value 获取user.dir

核心技术之SpEL

@value("#{'${file.path:}'?:systemProperties['user.dir']+'/config/upload.txt'}")

$(file.path) 是配置application.properties中内容,当其为空时,使用默认值systemProperties['user.dir']+'/config/upload.txt

二十七。使用poi上传超大excel,抛内存溢出

原因是poi会一次性将excel加载到内存。

解决方案: 可将excel转成csv格式上传,然后通过一行一行读取csv,来处理数据

解析csv隐申的问题:

1.csv内容中带有特殊字符,比如“,”,在使用分割是会出现错误

解决:1)使用正则处理,网上自行查找

2)使用第三方组件 javacsv,会自动处理特殊字符

< dependency >
< groupId >net.sourceforge.javacsv</ groupId >
< artifactId >javacsv</ artifactId >
< version >2.1</ version >
</ dependency >

2.读取csv文件时,由于csv编码格式,会导致读取的数据乱码,所以在读取csv文件时,要知道文件的编码格式:

解决:1)可自行网上查询一个“判断文件编码格式的方法”,然后根据不同编码进行解析文件

2)程序中固定csv编码格式为“GBK”,要求一切上传的csv必须是GBK编码

csv文件->记事本打开->另存为,选择编码格式 ,即可保存想要的编码格式的文件


二十八。springBoot中使用@Value()并设置默认值后,只能获取默认值,并不能获取配置文件中的值

原因是:有多个解析器,通过调试查看spring 源码中解析@Value的方法: AbstractBeanFactory中的resolveEmbeddedValue,其中发现“swaggerPropertiest”

问题说明及解决方案:

项目使用swagger的2.6.0版本,升级swagger版本到2.7.0吧,2.7.0删掉了这个配置,问题解决

参考:

SprintBoot中使用@value注解获取不到配置值 - 掘金

Spring Boot Nacos配置无法覆盖@Value定义的默认值 最终解决


二十九.mysql表字段是关键字,插入是报语法错误,如何向关键字列插入数据

问题描述:mysql向表插入数据 INSERT INTO XXX(id,KEY,NAME)VALUES(7,111,'test') ;

提示:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server

原因:KEY NAME都属于关键字

解决:1.修改表字段名称,将key name修改为非关键字

2.关键字列在修改更新时,添加 ` ,排除mysql影响,例如sql修改为

INSERT INTO XXX(id,`key`,`name`)VALUES(7,111,'test') ;

编辑于 2022-08-12 11:05