Java程序猿搬砖笔记(六)
作为码农平时搜集一些小知识点个人认为是个不错的习惯,书上说
好记性不如烂笔头
我想即使是以前忽略或者新get的很简单的东西,自己动手记下来不管如何印象也会更深刻。
@RequestBody注解支持空参数
@RequestBody(required=false),get/post且实体不加无参构造方法都行
windows查看占用端口并杀死对应进程
1 | E:\Documents\MyIdeaProjects\act\target>netstat -ano |findstr "8888" |
MySQL和MyBatis对JSON类型字段的处理
-
MySQL有JSON字段,MyBatis不支持JSON类型字段的处理,需要自己写Handler
-
MySQL存有转义字符的JSON会报错,比如"apiParam":"{orderId:"$orderId$"}"
Java连接8.0版本的MySQL
Java连接的8.0版MySQL时需要把mysql-connector-java包换成8.X版本的,把链接换成com.mysql.cj.jdbc.Driver。com.mysql.cj.jdbc.Driver是6.x版本的新功能,需要指定时区serverTimezone和useSSL报com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server错误同样是因为数据库版本太高了而对应的驱动器太低了。相关代码如下:
1 | <!-- mysql驱动 --> |
Spring整合Activiti测试时报错
错误如下:
1 | Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'processEngine': FactoryBean threw exception on object creation; nested exception is org.apache.ibatis.exceptions.PersistenceException: |
原因:因为mysql使用schema标识库名而不是catalog,因此mysql会扫描所有的库来找表,如果其他库中有相同名称的表,activiti就以为找到了,本质上这个表在当前数据库中并不存在。设置nullCatalogMeansCurrent=true,表示mysql默认当前数据库操作,在mysql-connector-java 5.xxx该参数默认为true,在6.xxx以上默认为false,因此需要设置nullCatalogMeansCurrent=true。
解决方法:配置mysql连接时加上:nullCatalogMeansCurrent=true。
代码如下:
1 | <property name="url" value="jdbc:mysql://localhost:3306/activiti_spring?nullCatalogMeansCurrent=true"/> |
Apache CXF客服端调用失败
错误信息如下:
1 | Caused by: org.apache.cxf.binding.soap.SoapFault: Unexpected wrapper element |
解决方法:
- 客户端接口头部的@WebService加上服务端的命名空间(可以通过wsdl文档查看)
比如@WebService(targetNamespace=“http://service.ws.myapp.com/”) - 客户端和服务端包名改成一致的(不推荐)
IDEA几个常用快捷键
ctrl+home 跳到文件头
ctrl+end 跳到文件尾
ctrl+f1+1 定位到文件位置
ctrl+shift+u 大小写转换
jps -l命令
jps -l命令可以查看本地启动的java进程,这是Jdk提供的命令
IDEA配置svn
- 需要按照SVN的时候选择命令行,否则在svn客户端安装路径bin目录下找不到svn.exe。
- 重新安装SVN后,右键->settings(设置)->icon overlays(图标覆盖)->选择shell(windows外壳),如果无效需要修改注册表后重启。
参考链接
参考链接
IDEA更新svn项目提示authentication required解决方法
- File->Settings->Version Control->Subversion->Clear Auth Cache 这个时候IDEA拉取代码会报No appropriate protocol (protocol is disabled or cipher suites are inappropriate)错,需要进行第二步
- 本地拉取代码,提示框选择永久接受证书;再回到IDEA 成功拉取代码。
引入Swagger后前端访问路径默认加了/v2/api-docs
方法一、把属性文件的server.servlet.context-path=/portal去掉可以正常访问
方法二、
- 在资源目录新建一个属性文件,内容如下:
1 | pringfox.documentation.swagger.v2.path=/ |
- 在SwaggerConfig配置类添加注解
1 |
Java实体转Map
- Web项目推荐使用
1 | BeanMap map = BeanMap.create(noticePageReq); |
- Java项目推荐使用反射
mybatis做动态排序的时候,字段打印出字符串解决方法
1 | <select id="queryNoticePageList" resultMap="BaseResultMap" parameterType="Map" > |
order by中打印出了字符串,在sql中会语法错误 :
1 | select id, notice_type_id, title, source, description, status, create_time, update_time, create_user, last_update_user, is_show, release_time |
解决方法:
1 | 把上面的#{prop}改为${prop},#{order}改为${order} |
SpringBoot接收对象属性的属性时为空
Java实体对象如下:
1 |
|
请求接口后:
解决方法1:在类NoticePageReq上添加@Data注解,这个注解会给属性加Set和get方法,需要添加lombok依赖。
解决方法2:在属性title添加@JsonProperty注解。这个注解的主要作用是把传过来的JSON值转换名称,比如下划线转驼峰,然后注入值。
Spring中的@Transactional(rollbackFor = Exception.class)属性详解
用了lombok的@Data注解就不要继承关系
如何理解 public static T
这是泛型方法。在方法中出现了泛型的结构,泛型参数与类的泛型参数无关。泛型方法所属的类是不是泛型类都可以。泛型方法可以声明为static。参考代码如下:
1 | public class ValidatorUtil { |
Java BigDecimal累加
1 | BigDecimal awardMoney = new BigDecimal(0); |
注意BigDecimal的add()方法返回的是相加后的数据
利用BeanMap进行对象与Map的相互转换
不过项目中使用BeanMap.create()方法个别地方会报异常,可能是用了热部署工具dev-tools,但是我去掉这个也报错,索性改为了反射方法
参考链接
使用reflect反射对象与Map的相互转换
1 | package edu.hrbeu.platform.modeling.common.util; |
Linux 脚本 sh 和 ./ 的区别
git分支相关操作命令
查看当前分支
1 | git branch |
查看所有分支(本地和远程)
1 | git branch -a |
查看所有分支(远程)
1 | git branch -r |
切换分支
1 | git checkout 分支名 |
创建分支
1 | git branch 分支名 |
删除分支
1 | 删除前需要先切换到其他分支,然后执行下面的命令 |
合并master分支代码到dev
1 | 先切换到dev分支然后执行git merge master |
SpringBoot 定义全局日期响应格式
方法一(消息转换器):
1 | /** |
这种方法如果前端传递接口未定义的参数会报JSON参数转换错误:
1 | JSON parse error: Unrecognized field \"a\" (class com.aspirecn.rewardportal.common.entity.PageRequest), not marked as ignorable; nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field \"a\" (class com.aspirecn.rewardportal.common.entity.PageRequest), not marked as ignorable (5 known properties: \"rows\", \"data\", \"prop\", \"order\", \"page\"])\n at [Source: (PushbackInputStream); line: 4, column: 9] (through reference chain: com.aspirecn.rewardportal.common.entity.PageRequest[\"a\"]) |
方法二(配置文件 推荐):
1 | #在application.properties文件中配置 |
方法三(在指定的Bean属性中添加注解):
1 |
|
注意如果有用到Fastjson ,注解可能会失效可以用@JSONField注解解决。
1 |
|
方法四(用于解决配置文件不生效的问题)
1 | /** |
SpringBoot对多模块包扫描问题
方法一:
1 |
方法二:
1 | https://blog.csdn.net/lintiyan/article/details/94362640 |
方法三(SpringBoot默认会扫描本模块下面的包):
1 |
SpringBoot包扫描排除指定类
1 |
Spring的@RequestBody注解接收参数时如果实体类属性以if和k开头,那么传参会接收不到
前端入参:
1 | { |
后端接收不到,如下图所示:
isBB可以接收到。 接收ifBB、kBB需要在实体类的属性中加上注解。,如下面的代码所示:
1 |
|
mysql bigint类型和datetime类型的转换
1、bigint类型转换为datetime类型
1 | select from_unixtime(1164691264437/1000); |
2、datetime类型转换为bigint类型
1 | select UNIX_TIMESTAMP('2021-09-13 11:24:59'); |
使用EasyExcel导入问题
- 如果在注解中添加index属性,value的名称可以和Excel的列名不一样;
- 如果没有添加index属性,value的名称必须和Excel的列名一样
1 |
|
校验导入的Excel数据是否重复
比如要求同一类型成果同一年份同一成果名称不能相同,如下图所示:
1、先去数据库查询类型、年份和成果名拼接字符串列表得到List
1 | SELECT concat(type,'@',which_year,'@',name) |
2、循环读到的Excel行,每读一条拼取一个key去recordList中匹配,然后把该条数据也放到recordList
1 | String productKey = achievementDto.getType()+AchievementConstant.SEPARATOR_A+achievementDto.getWhichYear()+AchievementConstant.SEPARATOR_A+achievementDto.getName(); |
这样把填写和数据库查询的数据都放到了一起,好处是不用再去单独校验用户填写的数据相互之间是否有问题。