kotlin springboot的配置类报错No default constructor found——不要给bean的构造器里写默认值
源码: (详细代码请查看正文) 运行时报错 Failed to instantiate ... MailConfig$$SpringCGLIB$$0: No default constructor found ,原因是当有默认值时,编译出来的java会生成多个构造器,而spring不知道该用哪个构造器,于是回退尝试调用无参构造器,结果发现不存在,就抛出异常了。 (编译后的java) 解决办法就是不要在bean的构造器上写默认值。此外如果没有引用到其他bean,写成 @Configuration(proxyBeanMethods = false) 禁用bean方法代理的同时提升点性能。 (详细代码请查看正文)
RestTemplate请求aws s3下载文件报错Error parsing the X-Amz-Credential parameter; the Credential is mal-formed
使用RestTemplate请求请求aws s3下载文件时,如果传递的url字符串已经经过编码(例如斜杠为 %2F ),aws会返回报错 Error parsing the X-Amz-Credential parameter; the Credential is mal-formed。 原因是字符串直接传给 RestTemplate.exchange() ( getForObject() 等其他方法也都一样,都是在背后都是调用了 execute() 方法)的话就会导致二次编码。具体可以看源码: (详细代码请查看正文) (详细代码请查看正文) (详细代码请查看正文) 可以看到最终来到了 build() 这里,而其中 encodeUriVariables 就是做了编码的操作。 解决办法也很简单,调用 exchange() 时不要传字符串,而是传 URI : (详细代码请查看正文) 源码中,首个参数为 URI 的 execute() 重载是不会发生编码操作,而是直接进行底层的 doExecute() : (详细代码请查看正文)...
kotlin spring项目中校验非空基本类型时@NotNull无效的问题
由于kotlin的基本类型(以下以Int为例)在非空时编译后的java类型为java基本类型,可空时则为包装类型(例如 Int 变为 int ,而 Int? 变为 Integer ),这导致了spring校验基本类型时如果使用 @NotNull ,前端又传了个null或者没传值,jackson会默认转换成基本类型的默认值,从而逃过了 @NotNull 。 可以看看jackson的源码(jackson-databind-3.0.2): (详细代码请查看正文) _parseIntPrimitive 调用的地方在 tools.jackson.databind.deser.jdk.NumberDeserializers.IntegerDeserializer.deserialize ,也就是jackson对于json number 类型的预设解析器中(其他类型同理) 可以看出到来,对于 int ,当 FAIL_ON_NULL_FOR_PRIMITIVES 没开启时jackson就直接返回 0...
记一次UnexpectedRollbackException解决过程
项目内有一个api方法(称之为 ServiceA.methodA() )需要调用一个共通service里的方法(称之为 CommonService.methodB() ),然后由于业务需求需要catch住 CommonService.methodB() 的异常并返回response。 由于项目在config里通过切面配置了对于所有的 @Service 都设置了默认事务为REQUIRED,并且设置了对所有异常都回滚(通过 TransactionInterceptor 和 NameMatchTransactionAttributeSource ),导致如果直接使用 CommonService.methodB() 的话就会因为spring的机制导致抛出UnexpectedRollbackException。 这个机制具体来说,抛出异常时spring会检测到并将当前事务内部的 rollbackOnly...
记录搭建博客的过程(Hexo+Butterfly+Github Actions+Github Pages)
契机很久以前曾经搭过一次个人博客,但后来觉得自己写的东西太小儿科了太羞耻于是删掉了。然而最近偶然看到一个人的博客刷新了我对博客的看法:他的博客里东西很多,既有“小儿科”的简单内容(例如学习某个语言基本用法),也有高级复杂的内容(例如k8s集群)。整个博客给人的感觉就像是见证了他的学习成长历程一样,那些简单的内容也变得值得敬佩。 所以想了想把自己私藏许久的笔记也拿出来晒晒,其中有些确实是我当时网上找了好久研究了很长时间才解决的问题,值得分享。 需求&选择理由我不想在博客上花一分钱(图床除外),也不想买个域名,因此github pages是最好的选择。 另外因为我的github pages已经用于展示字幕组文档了(docsify),所以这次需要同时保留docsify作为子路径能够访问得到。 此外考虑到重复的在本地 hexo clean && hexo g && hexo s 后还要commit也挺麻烦的,但又觉得写个本地脚本不够优雅,所以这次采用Github...
解决Goland换主题但代码看起来五颜六色太乱的问题
在设置里编辑器→配色方案→Go→语义高亮显示里把“值继承自”关掉,同时还要把“语义高亮显示”关掉。(“语言默认值”里的“语义高亮显示”关掉可能没用,下次打开Goland时又会恢复原样,不知道是不是bug,但在这里关掉,下次打开Goland能够保持设定) 如它所述,他会为每个参数或变量分配各种颜色,但显然实际看起来不仅没起到区分的作用,还更乱了,因此建议关掉。
Typescript使用ts-node报错Could not find a declaration file for module
ts要用js的第三方modules时,会提示你Could not find a declaration file for module,然后让你install @types/对应的模块名,或者自己写.d.ts文件。后者的话,随便在哪新建个xxx.d.ts文件,xxx自己取。然后文件里写上: (详细代码请查看正文) 你可以多个模块声明写在一个文件里,也可以分开。 但是如果你用ts-node的话,写了.d.ts文件还不行,还是会报错找不到。这时候需要你新建个文件夹,里面再新建个文件夹,然后里面放上.d.ts文件。例如: ┏ node_modules┣ src┗ index.ts┣ types┗ package┗ alltypes.d.ts┣ tsconfig.json┗ package.json 然后在tsconfig.json里添加: (详细代码请查看正文)...
Could not read source map for xxx
在launch.json中添加: (详细代码请查看正文) 参考:[node-debugger] Debugger spams “Could not read sourcemaps” messages · Issue #102042 · microsoft/vscode · GitHub
go通过github action自动部署到服务器
我的最终的配置文件 deploy.yml ,主要做了以下几件事: 先配置go环境; go build; 先终止在伪终端里跑的程序(否则无法成功上传); 上传构建后的文件; 让程序在伪终端里跑起来。 (详细代码请查看正文) 期间经历了很多坎坷,接二连三遇到问题: 先出现了 remote open("/home/ubuntu/app/rabbitool/rabbitool") failure ,解决办法是先把正在运行的程序停了,然后再上传。因此才用ssh-scp-ssh-pipelines。 然后出现了 open terminal failed: not a terminal,解决办法是ssh启动时加上 -t 。但是ssh-scp-ssh-pipelines没法在连接ssh时传入参数,因此最后再用个单独的ssh action。 shell - tmux open terminal failed: not a terminal - Stack Overflow 又出现了 Pseudo-terminal will not be allocated...
go regexp不支持unicode
(详细代码请查看正文) 会报错 error parsing regexp: invalid escape sequence: `\u` 因为go的regexp不支持 \u 。改用 \x 或者 \p{class}。 参考:regex for Chinese · Issue #257 · google/mtail · GitHub