Java程序猿搬砖笔记(六)

Java程序猿搬砖笔记(六)

作为码农平时搜集一些小知识点个人认为是个不错的习惯,书上说

好记性不如烂笔头

我想即使是以前忽略或者新get的很简单的东西,自己动手记下来不管如何印象也会更深刻。

@RequestBody注解支持空参数

@RequestBody(required=false),get/post且实体不加无参构造方法都行

windows查看占用端口并杀死对应进程

E:\Documents\MyIdeaProjects\act\target>netstat -ano |findstr "8888"
  TCP    0.0.0.0:8888           0.0.0.0:0              LISTENING       14176
  TCP    [::]:8888              [::]:0                 LISTENING       14176

E:\Documents\MyIdeaProjects\act\target>tasklist |findstr "14176"
javaw.exe                    14176 Console                    2    254,736 K

E:\Documents\MyIdeaProjects\act\target>taskkill /f /t /im "javaw.exe"
成功: 已终止 PID 14176 (属于 PID 13304 子进程)的进程。

E:\Documents\MyIdeaProjects\act\target>netstat -ano |findstr "8888"

MySQL和MyBatis对JSON类型字段的处理

  • MySQL有JSON字段,MyBatis不支持JSON类型字段的处理,需要自己写Handler

  • MySQL存有转义字符的JSON会报错,比如"apiParam":"{orderId:" o r d e r I d 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错误同样是因为数据库版本太高了而对应的驱动器太低了。相关代码如下:

<!-- mysql驱动 -->
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>8.0.23</version>
</dependency>
<!-- dbcp链接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
	<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
	<property name="url" value="jdbc:mysql:///activiti_demo?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false" />
	<property name="username" value="root" />
	<property name="password" value="root" />
	<property name="maxActive" value="3" />
	<property name="maxIdle" value="1" />
</bean>

参考链接

Spring整合Activiti测试时报错

错误如下:

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: 
Error querying database.  Cause: java.sql.SQLSyntaxErrorException: Table 'activiti_spring.act_ge_property' doesn't exist

原因:因为mysql使用schema标识库名而不是catalog,因此mysql会扫描所有的库来找表,如果其他库中有相同名称的表,activiti就以为找到了,本质上这个表在当前数据库中并不存在。设置nullCatalogMeansCurrent=true,表示mysql默认当前数据库操作,在mysql-connector-java 5.xxx该参数默认为true,在6.xxx以上默认为false,因此需要设置nullCatalogMeansCurrent=true。
解决方法:配置mysql连接时加上:nullCatalogMeansCurrent=true。
代码如下:

<property name="url" value="jdbc:mysql://localhost:3306/activiti_spring?nullCatalogMeansCurrent=true"/>

参考链接

Apache CXF客服端调用失败

错误信息如下:

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去掉可以正常访问

方法二

  • 在资源目录新建一个属性文件,内容如下:
pringfox.documentation.swagger.v2.path=/
  • 在SwaggerConfig配置类添加注解
@PropertySource("classpath:swagger.properties")

参考链接

Java实体转Map

  • Web项目推荐使用
BeanMap map = BeanMap.create(noticePageReq);
  • Java项目推荐使用反射

参考链接

mybatis做动态排序的时候,字段打印出字符串解决方法

<select id="queryNoticePageList" resultMap="BaseResultMap" parameterType="Map" >
  select
  <include refid="Base_Column_List" />
  from t_notice
  <if test="prop != null" >
    order by #{prop}
    <if test="order != null" >
      #{order}
    </if>
  </if>
</select>

order by中打印出了字符串,在sql中会语法错误 :

select id, notice_type_id, title, source, description, status, create_time, update_time, create_user, last_update_user, is_show, release_time
 FROM t_notice order by 'title' 'asc';

解决方法:

把上面的#{prop}改为${prop},#{order}改为${order}

SpringBoot接收对象属性的属性时为空

Java实体对象如下:

@Data
public class PageRequest<T>{
    private Integer page; //当前页
    private Integer rows; //每页显示数
    private String prop; //排序字段名
    private String order; //排序方式:asc或desc
    private T data;
}

public class NoticePageReq {
    @ApiModelProperty(value="公告标题")
    private String title;
}

请求接口后:
在这里插入图片描述

解决方法1:在类NoticePageReq上添加@Data注解,这个注解会给属性加Set和get方法,需要添加lombok依赖。
解决方法2:在属性title添加@JsonProperty注解。这个注解的主要作用是把传过来的JSON值转换名称,比如下划线转驼峰,然后注入值。

Spring中的@Transactional(rollbackFor = Exception.class)属性详解

参考链接1参考链接2参考链接3

用了lombok的@Data注解就不要继承关系

如何理解 public static T

这是泛型方法。在方法中出现了泛型的结构,泛型参数与类的泛型参数无关。泛型方法所属的类是不是泛型类都可以。泛型方法可以声明为static。参考代码如下:

public class ValidatorUtil {
    // 获取validator对象
    private static Validator validator = Validation.byProvider(HibernateValidator.class).configure()
                                                   .failFast(false).buildValidatorFactory().getValidator();

    public static <T>  Set<ConstraintViolation<T>>  validateBean(T bean){
        Set<ConstraintViolation<T>> validateResult =  validator.validate(bean);
        return validateResult;
    }

参考链接

Java BigDecimal累加

 BigDecimal awardMoney = new BigDecimal(0);
 for(ImportDoubleAwardsField field: entrySet.getValue()){
       awardMoney = awardMoney.add(field.getMoney());
  }

注意BigDecimal的add()方法返回的是相加后的数据

利用BeanMap进行对象与Map的相互转换

不过项目中使用BeanMap.create()方法个别地方会报异常,可能是用了热部署工具dev-tools,但是我去掉这个也报错,索性改为了反射方法
参考链接

使用reflect反射对象与Map的相互转换

package edu.hrbeu.platform.modeling.common.util;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
/**
 * 使用reflect进行转换
 */
public class MapTransformUtils1 {
 
    public static <T> T mapToObject(Map<String, Object> map, Class<T> beanClass) throws Exception {
        if (map == null)
            return null;
 
        T obj = beanClass.newInstance();
 
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            int mod = field.getModifiers();
            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                continue;
            }
 
            field.setAccessible(true);
            field.set(obj, map.get(field.getName()));
        }
 
        return obj;
    }
 
    public static Map<String, Object> objectToMap(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }
 
        Map<String, Object> map = new HashMap<String, Object>();
 
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            map.put(field.getName(), field.get(obj));
        }
 
        return map;
    }
}

参考链接

Linux 脚本 sh 和 ./ 的区别

参考链接

git分支相关操作命令

查看当前分支

git branch

查看所有分支(本地和远程)

git branch -a

查看所有分支(远程)

git branch -r

切换分支

git checkout 分支名

创建分支

git branch 分支名

删除分支

删除前需要先切换到其他分支,然后执行下面的命令
git branch -D 分支名 

合并master分支代码到dev

先切换到dev分支然后执行git merge master

SpringBoot 定义全局日期响应格式

方法一(消息转换器):

/**
 * 设置全局响应日期格式
 *
 * @author liquanhong
 * @createTime 2021/09/07
 */

@Configuration
public class Json2MessageConventerConfig {
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        objectMapper.setDateFormat(sdf);
        converter.setObjectMapper(objectMapper);
        return converter;
    }
}

这种方法如果前端传递接口未定义的参数会报JSON参数转换错误:

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\"])

方法二(配置文件 推荐):

#在application.properties文件中配置
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

#在application.yml文件中配置
spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

方法三(在指定的Bean属性中添加注解):

@JsonFormat(timezone = "GMT+8", pattern = "yyyyMMddHHmmss")
private Date createTime; 

需要有下面的依赖
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
</dependency>

注意如果有用到Fastjson ,注解可能会失效可以用@JSONField注解解决。

@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date updatedDate;

方法四(用于解决配置文件不生效的问题)

/**
 * WebMvc配置
 *
 * @author liquanhong
 * @createTime 2021/10/25
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    /**
     * 使用此方法, 以下 spring-boot: jackson时间格式化 配置 将会失效
     * spring.jackson.time-zone=GMT+8
     * spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
     * 原因: 会覆盖 @EnableAutoConfiguration 关于 WebMvcAutoConfiguration 的配置
     * */
    @Override
    public void extendMessageConverters(List converters) {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = converter.getObjectMapper();
        // 生成JSON时,将所有Long转换成String
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        // 时间格式化
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 设置格式化内容
        converter.setObjectMapper(objectMapper);
        converters.add(0, converter);
    }
}

SpringBoot对多模块包扫描问题

方法一:

@SpringBootApplication(scanBasePackages = {"com.xx.xx.xx.A", "com.xx.xx.B"})

方法二:

https://blog.csdn.net/lintiyan/article/details/94362640

方法三(SpringBoot默认会扫描本模块下面的包):

@SpringBootApplication
@ComponentScan("com.xx.xx.B")

SpringBoot包扫描排除指定类

@ComponentScan(basePackages={"com.aspirecn.core.common","com.aspirecn.kjcgkyg"},
		       excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = DruidConfig.class))	     

参考链接

Spring的@RequestBody注解接收参数时如果实体类属性以if和k开头,那么传参会接收不到

前端入参:

{
  "kBB": "kBB123",
  "isBB": "isBB123",
  "ifBB": "ifBB123"
} 

后端接收不到,如下图所示:
在这里插入图片描述

isBB可以接收到。 接收ifBB、kBB需要在实体类的属性中加上注解。,如下面的代码所示:

@JsonProperty(value = "kBB")
private String kBB;
@JsonProperty(value = "ifBB")
private String ifBB;

mysql bigint类型和datetime类型的转换

1、bigint类型转换为datetime类型

select from_unixtime(1164691264437/1000);

2、datetime类型转换为bigint类型

select UNIX_TIMESTAMP('2021-09-13 11:24:59');

使用EasyExcel导入问题

  • 如果在注解中添加index属性,value的名称可以和Excel的列名不一样;
  • 如果没有添加index属性,value的名称必须和Excel的列名一样
   @ExcelProperty(value = "研发能力类型名称",index = 6)
   private String capabilityTypeName;

校验导入的Excel数据是否重复

比如要求同一类型成果同一年份同一成果名称不能相同,如下图所示:
在这里插入图片描述

1、先去数据库查询类型、年份和成果名拼接字符串列表得到List recordList

SELECT concat(type,'@',which_year,'@',name)
        FROM t_achievement
        WHERE type not in(1,2)

2、循环读到的Excel行,每读一条拼取一个key去recordList中匹配,然后把该条数据也放到recordList

String productKey = achievementDto.getType()+AchievementConstant.SEPARATOR_A+achievementDto.getWhichYear()+AchievementConstant.SEPARATOR_A+achievementDto.getName();
if(recordList.contains(productKey)){
                    errorBuilder.append(AchievementConstant.PRODUCT_NAME_REPEAT);
                }
recordList.add(productKey);

这样把填写和数据库查询的数据都放到了一起,好处是不用再去单独校验用户填写的数据相互之间是否有问题。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值