常用api总结
XXXTemplate 是 Spring 的一大设计特色,其中,RedisTemplate 功能是提供对 Redis 的支持。
RedisTemplate 是 Spring Boot 访问 Redis 的核心组件,是 SpringBoot 集成 Redis 的客户端方式。它的底层通过 RedisConnectionFactory 对多种 Redis 驱动进行集成,上层通过 XXXOperations 提供丰富的 API,并结合 Spring 基于泛型的 bean 注入,未开发提供了极大的便利。
一、Redis 常用的数据类型String:字符串类型,可以存储多种类型,如:字符串,JSON 串,二进制,序列化对象等;Hash:key-value 结构,就像 Java 里的 Map,特别适合存储对象;List:双端链表的结构,即可以作为栈,又可以作为队列,可以进行集合的头部或者尾部添加删除元素;Set:Set 集合是 String 类型的无序集合,通过 hashtable 实现,可以对集合取交集,并集,差集;Sorted set:是 String 类型的有序集合,并且,每个元素都会关联一个 ...
关于消费的同步异步问题,以及多个方法监听同一个topic
@KafkaListener(topics = "test")public void consumerTest1(String msg) throws InterruptedException { log.info("收到消息1:" + msg); TimeUnit.MILLISECONDS.sleep(10);}@KafkaListener(topics = "test")public void consumerTest2(String msg) throws InterruptedException { log.info("收到消息2:" + msg); TimeUnit.MILLISECONDS.sleep(10);}
如上所示多个方法消费同一个 topic那么,只会在一个方法中消费,不会两个方法都消费消息,即不会重复消费
同时当只有consumerTest1()方法时,如果手动阻塞线程,那么消息的消费也会变慢即如果向 test 发送 5 ...
Kafka生产者、消费者的消息可靠性方案实现
以下代码基于 SpringKafka 2.3.13.RELEASE + Boot 2.2.9.RELEASE 实现
Producer 消息的可靠性实现方案:ack 模式调整 + 重试机制 + 规避重试机制下带来的问题
spring.kafka: producer: #这个参数可以是任意字符串,它是broker用来识别消息是来自哪个客户端的。在broker进行打印日志、衡量指标或者配额限制时会用到。 clientId: ${spring.application.name} #方便kafkaserver打印日志定位请求来源 bootstrap-servers: 127.0.0.1:8080 #kafka服务器地址,多个以逗号隔开 #acks=0:生产者把消息发送到broker即认为成功,不等待broker的处理结果。这种方式的吞吐最高,但也是最容易丢失消息的。 #acks=1:生产者会在该分区的leader写入消息并返回成功后,认为消息发送成功。如果群首写入消息失败,生产者会收到错误响应并进行重试。这种方式能够一定程度避 ...
stream用法整理
stream 流处理将用,拼接的字符串转为 Double 集合// 将用','拼接的字符串转为Double集合List<Double> singlePoint = Arrays.asList(pointStr.split(",")) .stream() .map(str -> Double.parseDouble(str.trim())) .collect(Collectors.toList());
过滤枚举
枚举类
/** * 用户角色的枚举类 * */public enum RoleEnum { // 仓储角色 LABORATORY_PERSON("LABORATORY_PERSON", "实验室人员", "365ef7b96870d8acdd4a016866193278", "laboratoryPersonIndex.html", "goods"), EQUIPMENT_MANAGEMENT_PERSON("EQUIPMENT_MANAGEMENT_PERSON", "设备管理员", "34ea46 ...
lambda用法整理
使用 lambda 表达式建立子线程任务并阻塞主线程// 阻塞主线程的计数器 CountDownLatch countDownLanch = new CountDownLatch(cycleNum); // 局部的线程池 ExecutorService executor = Executors.newFixedThreadPool(cycleNum > 4 ? 4 : cycleNum); // cycleNum是要执行子线程的次数 for (int i = 0; i < cycleNum; i++) { int start = i * 10000; int num = 10000; executor.execute(new Runnable() { @Override public void run() { try ...
word转pdf
poi(慢,格式回出问题)
openOffice(单线程,不支持并发)
jacob(效果好,但是不支持 linux)
docx4j(没试过)
asposeword(效果好,块,但是付费)
业务开发时,接口不能对外暴露的解决办法
业务开发时,接口不能对外暴露怎么办?内外网接口微服务隔离
网关 + redis 实现白名单机制
方案三 网关 + AOP
具体实操
在业务开发的时候,经常会遇到某一个接口不能对外暴露,只能内网服务间调用的实际需求。面对这样的情况,我们该如何实现呢?今天,我们就来理一理这个问题,从几个可行的方案中,挑选一个来实现。
1. 内外网接口微服务隔离将对外暴露的接口和对内暴露的接口分别放到两个微服务上,一个服务里所有的接口均对外暴露,另一个服务的接口只能内网服务间调用。
该方案需要额外编写一个只对内部暴露接口的微服务,将所有只能对内暴露的业务接口聚合到这个微服务里,通过这个聚合的微服务,分别去各个业务侧获取资源。
该方案,新增一个微服务做请求转发,增加了系统的复杂性,增大了调用耗时以及后期的维护成本。
2. 网关 + redis 实现白名单机制在 redis 里维护一套接口白名单列表,外部请求到达网关时,从 redis 获取接口白名单,在白名单内的接口放行,反之拒绝掉。
该方案的好处是,对业务代码零侵入,只需要维护好白名单列表即可;
不足之处在于,白名单的维护是一个持续性投入的工作,在很多 ...
以特定的编码读取文件,以特定的编码写入文件
以下代码是针对 BufferedReader 和 BufferedWriter 的
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(inF),"GB2312"));// 以GB2312的编码读文件BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), StandardCharsets.UTF_8));// 以utf-8写文件
判断访问设备的方法
java 版// \b 是单词边界(连着的两个(字母字符 与 非字母字符) 之间的逻辑上的间隔),// 字符串在编译时会被转码一次,所以是 "\\b"// \B 是单词内部逻辑间隔(连着的两个字母字符之间的逻辑上的间隔)private static final String PHONE_REG = "\\b(ip(hone|od)|android|opera m(ob|in)i" + "|windows (phone|ce)|blackberry" + "|s(ymbian|eries60|amsung)|p(laybook|alm|rofile/midp" + "|laystation portable)|nokia|fennec|htc[-_]" + "|mobile|up.browser|[1-4][0-9]{2}x[1-4][0-9]{2})\\b";// 手记的正则表达式private stat ...
告别非空判断
1 Objects 工具类既然要解决空指针,自然就是提前对对象进行判空校验;通常情况下,会使用if( null != obj )进行对象校验;在 Java 7 中,专门提供工具类java.util.Objects,让对象的判空校验更加简单;
特点
Java 7 自带,不需要额外的依赖
静态方法,使用简单
仅支持对象判空
示例
Objects.isNull
判断对象是否为空,为null返回true,否则返回false
Object obj = null; System.out.println(Objects.isNull(obj)); // true obj = new Object(); System.out.println(Objects.isNull(obj)); // false
Objects.nonNull
和Objects.isNull相反;判断对象不为空,为null返回false,否则返回true
Object obj = null; System.out.println(Objects.nonNull(obj)); // false ...
常用的工具包
预览 word 或者 pdf 的内容:TiKa
数学运算:joinery
执行简单的定时任务之ScheduledExecutorService
ScheduledExecutorService有线程池的特性,也可以实现任务循环执行,可以看作是一个简单地定时任务组件,因为有线程池特性,所以任务之间可以多线程并发执行,互不影响,当任务来的时候,才会真正创建线程去执行我们在做一些普通定时循环任务时可以用它,比如定时刷新字典常量,只需要不断重复执行即可,这篇文章讲解一下它的用法以及注意事项,不涉及底层原理
注意:我们都知道,在使用线程池的时候,如果我们的任务出现异常没有捕获,那么线程会销毁被回收,不会影响其他任务继续提交并执行,但是在这里,如果你的任务出现异常没有捕获,会导致后续的任务不再执行,所以一定要try...catch
1. 延迟不循环任务schedule方法schedule(Runnable command, long delay, TimeUnit unit)参数 1:任务参数 2:方法第一次执行的延迟时间参数 3:延迟单位说明:延迟任务,只执行一次(不会再次执行),参数 2 为延迟时间
案例说明:
@Component@Slf4jpublic class MineExecutors { private f ...
常用的返回体封装工具类
/** * 返回体工具 */public class DtoResult<T> implements Serializable { public static final int STATUS_CODE_SUCCESS = 0; public static final int STATUS_CODE_ERROR = 500; private int code; private String message; private T data; public DtoResult() { this.setCode(0); } public DtoResult(T data) { this(); this.data = data; } public DtoResult(Integer code, String message, T data) { this.setCode(code); this. ...
时间日期整理
Java 中的 Timestamp 对应 mysql 中的 dateTime 类型比如:java 的 bean 类型是 Timestamp插入的时候这么写,这样插入完成后。mysql 数据库里就是 datatime 类型的数据了。
setUpdateTime(new Timestamp(new Date().getTime()));
也可以分开写如下:
java.util.Date date = new java.util.Date(); // 获取一个Date对象Timestamp timeStamp = new Timestamp(date.getTime()); // 给对象赋值该值插入就行了
Java:String 和 Date、Timestamp 之间的转换
String 与 Date(java.util.Date)互转String -> Date
String dateStr = "2010/05/04 12:34:23";Date date = new Date();//注意format的格式要与日期String的格式相匹配DateForm ...
获得文件路径三种方法以及区别
File file = new File(".\\test.txt");// 返回构造File对象时的路径// 因此,如果File对象是使用相对路径创建的,则返回的值也将是相对路径。如果是绝对路径就返回绝对路径。System.out.println(file.getPath());// 该方法返回文件的绝对路径。请注意!这里是有大坑的。如果你的文件在Java工程内,路径是按照编译后的路径计算的。// 该方法只解析当前目录(代码所在的目录)的相对路径,如果初始化中的路径包含了速记符,速记符将不会被解析。System.out.println(file.getAbsolutePath());// 速记符不被解析有时候是很痛苦的事,我们可能需要知道具体的路径。getCanonicalPath()方法解决了这个问题。由于getCanonicalPath()读取的是文件系统,因此会降低性能。// 如果我们确定没有使用速记符,并且驱动器号大小写已标准化(如果使用Windows OS),我们应该首选使用getAbsoultePath(),除非你的项目中必须使用getCanonica ...
数字处理
1.double 的向上,向下,四舍五入,以及转为 int1.向输出上取整public static void mathCeil() { Double number = 5.3; // Double 向上取整 double ceil = Math.ceil(number); System.out.println("number:" + number); System.out.println("ceil:" + ceil); int ceilRes = new Double(ceil).intValue(); System.out.println("ceilRes:" + ceilRes);}
输出:
number:5.3ceil:6.0ceilRes:6
2.向下取整public static void mathFloor () { Double number = 5.9; // Double 向下取整 double floor = Ma ...
Date类型
两个日期之间相差的天数,日期为单位(比如相差两秒,可能就相差一天,12:23:59:59 和 13:01:00:00 就相差一天)/** * date2比date1多的天数 * @param date1 * @param date2 * @return */private static int differentDays(Date date1,Date date2) { Calendar cal1 = Calendar.getInstance(); cal1.setTime(date1); Calendar cal2 = Calendar.getInstance(); cal2.setTime(date2); int day1= cal1.get(Calendar.DAY_OF_YEAR); int day2 = cal2.get(Calendar.DAY_OF_YEAR); int year1 = cal1.get(Calendar.YEAR); int year2 = cal2.get(Calendar.YEAR); ...
获取当前系统的文件分隔符
String outPath = parentFile.getCanonicalPath() + File.separator + "temp-" + fileName;// File.separator会根据当前的系统自动获得'/'或者'\\'
删除文件
删除单个文件/** * 删除单个文件 * * @param fileName 被删除文件的文件名 * @return 单个文件删除成功返回true, 否则返回false */ public static boolean deleteFile(String fileName) { File file = new File(fileName); if (file.isFile() && file.exists()) { file.delete(); System.out.println("删除单个文件" + fileName + "成功!"); return true; } else { System.out.println("删除单个文件" + fileName + "失败!"); return false; } } ...