Java笔记(2020)
1. 复杂JSON字符串转模型
1 import com.fasterxml.jackson.core.type.TypeReference; 2 import com.fasterxml.jackson.databind.ObjectMapper;
1 ObjectMapper mapper = new ObjectMapper(); 2 List<CustomModel> list = mapper.readValue(json, new TypeReference<List<CustomModel>>() { });
2. 在非Bean对象调用Spring Bean管理的对象
1 package com.wunaozai.demo 2 3 import org.springframework.beans.BeansException; 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.context.ApplicationContextAware; 6 import org.springframework.stereotype.Component; 7 8 /** 9 * 为不是spring所管理的对象,需要引用spring管理对象的时候所用的工具类 10 * @author wunaozai 11 * 12 */ 13 @Component 14 public class SpringApplicationContext implements ApplicationContextAware { 15 16 protected static ApplicationContext context; 17 18 @Override 19 public void setApplicationContext(ApplicationContext ctx) throws BeansException { 20 context = (ApplicationContext) ctx; 21 } 22 23 public static ApplicationContext getContext(){ 24 return context; 25 } 26 27 }
调用
1 CustomerService influxdbconnectService = SpringApplicationContext.getContext().getBean(CustomerService.class);
3. Spring Boot 项目出现 pom.xml 第一行莫名的错误,在pom.xml 的 properties段下增加
1 <maven-jar-plugin.version>3.0.0</maven-jar-plugin.version>
4. eclipse maven 更换 阿里源, 需要配置 settings.xml 文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <settings> 3 <mirrors> 4 <mirror> 5 <id>alimaven</id> 6 <name>aliyun maven</name> 7 <url>http://maven.aliyun.com/nexus/content/groups/public/</url> 8 <mirrorOf>central</mirrorOf> 9 </mirror> 10 </mirrors> 11 <profiles> 12 <profile> 13 <id>nexus</id> 14 <repositories> 15 <repository> 16 <id>nexus</id> 17 <name>local private nexus</name> 18 <url>http://maven.oschina.net/content/groups/public/</url> 19 <releases> 20 <enabled>true</enabled> 21 </releases> 22 <snapshots> 23 <enabled>false</enabled> 24 </snapshots> 25 </repository> 26 </repositories> 27 28 <pluginRepositories> 29 <pluginRepository> 30 <id>nexus</id> 31 <name>local private nexus</name> 32 <url>http://maven.oschina.net/content/groups/public/</url> 33 <releases> 34 <enabled>true</enabled> 35 </releases> 36 <snapshots> 37 <enabled>false</enabled> 38 </snapshots> 39 </pluginRepository> 40 </pluginRepositories> 41 </profile></profiles> 42 </settings>
5. spring boot 项目,用maven编译打包时,使用wrapper时遇到下载apache-maven失败,可以到 .m2/wrapper/dists/apache-maven-** 目录下,将离线包放到该目录下。或者修改wrapper目录下的maven-wrapper.properties文件里面的distributionUrl 为本地离线地址,都是可以的。
6. mybatis-plus 打印SQL详细日志,在application配置文件中增加
1 #mybatis-plus 2 mybatis-plus.mapper-locations=classpath:com/wunaozai/demo/mapper/*.xml 3 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
7. springboot中默认使用jackson做json序列化和反序列化,后台接收数据时将上述日期字符串转成LocalDateTime时,会报如下错误
JSON parse error: Cannot deserialize value of type java.time.LocalDateTime from String “2018-09-20 08:01:00”: Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text ‘2018-09-20 08:01:00’ could not be parsed at index 10; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.time.LocalDateTime from String “2018-09-20 08:01:00”: Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text ‘2018-09-20 08:01:00’ could not be parsed at index 10
解决办法:
导入jackson-datatype
1 <dependency> 2 <groupId>com.fasterxml.jackson.datatype</groupId> 3 <artifactId>jackson-datatype-jsr310</artifactId> 4 </dependency>
配置bean
1 @Bean 2 public ObjectMapper serializingObjectMapper() { 3 JavaTimeModule module = new JavaTimeModule(); 4 LocalDateTimeDeserializer deserializer = 5 new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 6 module.addDeserializer(LocalDateTime.class, deserializer); 7 ObjectMapper object = Jackson2ObjectMapperBuilder.json() 8 .modules(module) 9 .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) 10 .build(); 11 return object; 12 }
8. PCM 转 WAV 格式
PcmToWav.java
1 package com.wunaozai.demo.pcm2wav; 2 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 7 /** 8 * PCM 转 WAV 9 * @author wunaozai 10 * @Date 2020-11-03 11 */ 12 public class PcmToWav { 13 public static void main(String[] args) throws Exception { 14 convertAudioFiles("F:\\voice\\1311458187862568961.pcm", "F:\\voice\\1311458187862568961.pcm.mp3"); 15 } 16 17 public static void convertAudioFiles(String src, String dest) throws IOException { 18 FileInputStream fis = new FileInputStream(src); 19 FileOutputStream fos = new FileOutputStream(dest); 20 //计算长度 21 byte[] buf = new byte[1024 * 4]; 22 int size = fis.read(buf); 23 int PCMSize = 0; 24 while (size != -1) { 25 PCMSize += size; 26 size = fis.read(buf); 27 } 28 fis.close(); 29 30 //填入参数,比特率等等。这里用的是16位单声道 8000 hz 31 WaveHeader header = new WaveHeader(); 32 //长度字段 = 内容的大小(PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节) 33 header.fileLength = PCMSize + (44 - 8); 34 header.FmtHdrLeth = 16; 35 header.BitsPerSample = 16; 36 header.Channels = 1; 37 header.FormatTag = 0x0001; 38 header.SamplesPerSec = 16000; 39 header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8); 40 header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec; 41 header.DataHdrLeth = PCMSize; 42 43 byte[] h = header.getHeader(); 44 45 assert h.length == 44; //WAV标准,头部应该是44字节 46 // write header 47 fos.write(h, 0, h.length); 48 // write data stream 49 fis = new FileInputStream(src); 50 size = fis.read(buf); 51 while (size != -1) { 52 fos.write(buf, 0, size); 53 size = fis.read(buf); 54 } 55 fis.close(); 56 fos.close(); 57 System.out.println("Convert OK!"); 58 } 59 }
WaveHeader.java
1 package com.wunaozai.demo.pcm2wav; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 6 /** 7 * Wav头 8 * @author wunaozai 9 * @Date 2020-11-03 10 */ 11 public class WaveHeader { 12 public final char fileID[] = {'R', 'I', 'F', 'F'}; 13 public int fileLength; 14 public char wavTag[] = {'W', 'A', 'V', 'E'}; 15 public char FmtHdrID[] = {'f', 'm', 't', ' '}; 16 public int FmtHdrLeth; 17 public short FormatTag; 18 public short Channels; 19 public int SamplesPerSec; 20 public int AvgBytesPerSec; 21 public short BlockAlign; 22 public short BitsPerSample; 23 public char DataHdrID[] = {'d', 'a', 't', 'a'}; 24 public int DataHdrLeth; 25 26 public byte[] getHeader() throws IOException { 27 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 28 WriteChar(bos, fileID); 29 WriteInt(bos, fileLength); 30 WriteChar(bos, wavTag); 31 WriteChar(bos, FmtHdrID); 32 WriteInt(bos, FmtHdrLeth); 33 WriteShort(bos, FormatTag); 34 WriteShort(bos, Channels); 35 WriteInt(bos, SamplesPerSec); 36 WriteInt(bos, AvgBytesPerSec); 37 WriteShort(bos, BlockAlign); 38 WriteShort(bos, BitsPerSample); 39 WriteChar(bos, DataHdrID); 40 WriteInt(bos, DataHdrLeth); 41 bos.flush(); 42 byte[] r = bos.toByteArray(); 43 bos.close(); 44 return r; 45 } 46 private void WriteShort(ByteArrayOutputStream bos, int s) throws IOException { 47 byte[] mybyte = new byte[2]; 48 mybyte[1] = (byte) ((s << 16) >> 24); 49 mybyte[0] = (byte) ((s << 24) >> 24); 50 bos.write(mybyte); 51 } 52 private void WriteInt(ByteArrayOutputStream bos, int n) throws IOException { 53 byte[] buf = new byte[4]; 54 buf[3] = (byte) (n >> 24); 55 buf[2] = (byte) ((n << 8) >> 24); 56 buf[1] = (byte) ((n << 16) >> 24); 57 buf[0] = (byte) ((n << 24) >> 24); 58 bos.write(buf); 59 } 60 private void WriteChar(ByteArrayOutputStream bos, char[] id) { 61 for (char c : id) { 62 bos.write(c); 63 } 64 } 65 }
9. Java 线程池简单使用
1 package com.wunaozai.demo.testdemo; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.concurrent.Callable; 6 import java.util.concurrent.ExecutionException; 7 import java.util.concurrent.ExecutorService; 8 import java.util.concurrent.Executors; 9 import java.util.concurrent.Future; 10 import java.util.concurrent.ScheduledExecutorService; 11 import java.util.concurrent.ThreadPoolExecutor; 12 import java.util.concurrent.TimeUnit; 13 14 /** 15 * 测试线程池 16 * @author wunaozai 17 * @Date 2020-12-09 18 */ 19 public class TestThreadPoolExecutor { 20 21 public static void main(String[] args) { 22 //testSingleThreadPool(); 23 //testFixedThreadPool(); 24 //testCachedThreadPool(); 25 //testScheduledThreadPool(); 26 //testAwaitTermination(); 27 testThreadPoolResult(); 28 } 29 30 //创建单个线程的线程池 31 public static void testSingleThreadPool() { 32 ExecutorService service = Executors.newSingleThreadExecutor(); 33 for(int i=0; i<10; i++) { 34 service.submit(newRunnable()); 35 } 36 service.shutdown(); //禁止再继续提交任务,等所有任务都执行完成后,关闭当前线程池 37 //service.shutdownNow(); //禁止再提交任务,不等所有任务执行完,立即关闭当前线程池 38 System.out.println("结束"); 39 } 40 //创建使用固定线程数的线程池 41 public static void testFixedThreadPool() { 42 ExecutorService service = Executors.newFixedThreadPool(3); 43 for(int i=0; i<10; i++) { 44 service.submit(newRunnable()); 45 } 46 service.shutdown(); 47 System.out.println("结束"); 48 } 49 //创建一个根据需要动态创建新线程的线程池 50 public static void testCachedThreadPool() { 51 ExecutorService service = Executors.newCachedThreadPool(); 52 for(int i=0; i<200; i++) { 53 service.submit(newRunnable()); 54 } 55 service.shutdown(); 56 System.out.println("结束"); 57 } 58 //创建使用固定线程数的定时任务线程池 59 public static void testScheduledThreadPool() { 60 ScheduledExecutorService service = Executors.newScheduledThreadPool(5); 61 for(int i=0; i<20; i++) { 62 service.schedule(newRunnable(), 3, TimeUnit.SECONDS); 63 } 64 service.shutdown(); 65 System.out.println("结束"); 66 } 67 //阻塞式,等待线程池关闭 68 public static void testAwaitTermination() { 69 ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); 70 service.schedule(newRunnable(), 2, TimeUnit.SECONDS); 71 try { 72 boolean flag = service.awaitTermination(4, TimeUnit.SECONDS); 73 if(flag == false) { 74 service.shutdown(); 75 } 76 } catch (InterruptedException e) { 77 e.printStackTrace(); 78 } 79 System.out.println("结束"); 80 } 81 82 private static Runnable newRunnable() { 83 return new Runnable() { 84 @Override 85 public void run() { 86 try { 87 Thread.sleep(200); 88 } catch (InterruptedException e) { 89 e.printStackTrace(); 90 } 91 System.out.println(Thread.currentThread().getName() + "正在执行"); 92 } 93 }; 94 } 95 96 //测试带返回值的线程池 97 public static void testThreadPoolResult() { 98 ThreadPoolExecutor service = (ThreadPoolExecutor) Executors.newFixedThreadPool(3); 99 100 List<Future<String>> resultList = new ArrayList<>(); 101 for(int i=0; i<10; i++) { 102 Future<String> ret = service.submit(newCallable("val: " + i)); //异步提交 103 resultList.add(ret); 104 } 105 106 //同步取值 107 while(service.getCompletedTaskCount() < resultList.size()) { 108 System.out.println("当前完成数: " + service.getCompletedTaskCount()); 109 for(int i=0; i<resultList.size(); i++) { 110 Future<String> ret = resultList.get(i); 111 System.out.printf("Task %d: %s\n", i, ret.isDone()); 112 } 113 try { 114 Thread.sleep(50); 115 } catch (InterruptedException e) { 116 e.printStackTrace(); 117 } 118 } 119 //所有线程都返回结果 120 for(int i=0; i<resultList.size(); i++) { 121 Future<String> result = resultList.get(i); 122 String ret = "Err"; 123 try { 124 ret = result.get(); //阻塞读取 125 } catch (InterruptedException | ExecutionException e) { 126 e.printStackTrace(); 127 } 128 System.out.printf("Task: %d, result %s\n", i, ret); 129 } 130 service.shutdown(); 131 System.out.println("结束"); 132 } 133 134 public static Callable<String> newCallable(String txt) { 135 return new Callable<String>() { 136 @Override 137 public String call() throws Exception { 138 System.out.println(Thread.currentThread().getName() + "正在执行"); 139 Thread.sleep(200); 140 return txt; 141 } 142 }; 143 } 144 145 }
10. Mybatis-Plus 自定义SQL
1 @EnableTransactionManagement(proxyTargetClass = true) //开启事务
Mapper.java
1 public interface Mapper { 2 3 public List<Model> selectList(@Param(value=Constants.WRAPPER) Wrapper<?> wrapper); 4 5 public IPage<Model> selectPage(@Param(value="page") IPage<?> page, 6 @Param(value=Constants.WRAPPER) Wrapper<?> wrapper); 7 }
Mapper.xml
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <mapper namespace="com.wunaozai.mapper.Mapper"> 4 5 <select id="selectList" resultType="com.wunaozai.model.Model"> 6 SELECT * FROM tbl ${ew.customSqlSegment} 7 </select> 8 9 <select id="selectPage" resultType="com.wunaozai.model.Model"> 10 SELECT * FROM tbl ${ew.customSqlSegment} 11 </select> 12 </mapper>
11. 清理Postgres表空间
1 # 查询所有表占用空间 2 select relname, pg_size_pretty(pg_relation_size(relid)) as size from pg_stat_user_tables; 3 # 针对已经delete的表进行vacuum full 4 vacuum FULL device_event_log ;
持续更新...
作者:无脑仔的小明 出处:http://www.cnblogs.com/wunaozai/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果文中有什么错误,欢迎指出。以免更多的人被误导。有需要沟通的,可以站内私信,文章留言,或者关注“无脑仔的小明”公众号私信我。一定尽力回答。 |