文章
fastjson => jackson
Json序列化
//User 类序列化成 { “userName”:”张三”},又要将 { “name”:”张三”} 序列化成 User类。
//gsonclass User{@SerializedName(value="userName",alternate={"name"})private String userName;}//fastjson@JSONField(name = "project")
1.fastjson List转JSONArrayList list = new ArrayList();JSONArray array= JSONArray.parseArray(JSON.toJSONString(list));
2.fastjson JSONArray转ListJSONArray array = new JSONArray();List list = JSONObject.parseArray(array.toJSONString(), EventColAttr.class);
3.fastjson 字符串转ListString str = "";List list = JSONObject.parseArray(str,T.class);
切面表达式:
https://cloud.tencent.com/developer/article/1497814
通过切面解决认证问题:
1.认证失效(账号被顶/过期);捕获到认证失效异常后,调用认证逻辑,携带最新Token再次执行业务逻辑并返回;
iotAuthImpl.javaAuthInvalidAop.java
Swagger
Swagger自动转驼峰 问题(Action ==> swagger ==> action)
不可取、待确认是否是该原因: mapStruct 貌似也是通过 get,set方法去识别;
1.通过FastJson的@JSONField注解解决/
2.仅返回对应的泛型类,实际可返回new JSONArray();
DateMath
import cn.hutool.core.date.LocalDateTimeUtil;import cn.hutool.core.math.MathUtil;import cn.hutool.core.util.NumberUtil;import java.time.LocalDate;import java.time.LocalDateTime;import java.time.ZoneId;import java.util.Locale;public class test{public static void main(String[] args) {double v = DateTimeMathUtil.todayInMothPercent();System.out.println("v = " + v);double div = NumberUtil.div(20, 29, 4);System.out.println("div = " + div);//68.965515System.out.println((float) 20 / (float) 29 * 100);//68.96551724137932System.out.println((double) 20 / (double) 29 * 100);String time = LocalDateTimeUtil.format(LocalDateTime.now(ZoneId.of("Asia/Shanghai")), "yyyyMMddHHmmss");System.out.println(time.toUpperCase(Locale.ROOT));int dayOfMonth = LocalDateTimeUtil.now().getDayOfMonth();System.out.println("dayOfMonth = " + dayOfMonth);LocalDate date = LocalDate.of(2020, 2, 20);System.out.println("============");//第20天System.out.println(date.getDayOfMonth());//最多29天System.out.println(date.getMonth().maxLength());//至少28天System.out.println(date.getMonth().minLength());//当前月有29天System.out.println(date.getMonth().length(date.isLeapYear()));// DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");// LocalDateTime parse = LocalDateTime.parse("2020-08-08 00:00:00",df);// int dayOfMonth1 = parse.getDayOfMonth();// int length = parse.getMonth().length(LocalDate.now().isLeapYear());// System.out.println("length = " + length);// System.out.println("dayOfMonth1 = " + dayOfMonth1);// System.out.println("time = " + time);}}
工具类
package com.time.common.utils.date;import cn.hutool.core.util.NumberUtil;import java.time.LocalDate;/*** @author yx.Jiang* @desc 日期/时间计算工具类* @date 2021-09-01 16:18*/public class DateTimeMathUtil {/*** 已过日期占比(Percentage of elapsed time)** @return 默认保留四位小数【四舍五入】*/public static double todayInMothPercent() {return dayInMothPercent(LocalDate.now(), 4);}/*** 已过日期占比(Percentage of elapsed time)** @param scale 小数位* @return 默认保留四位小数【四舍五入】*/public static double todayInMothPercent(int scale) {return dayInMothPercent(LocalDate.now(), scale);}/*** 已过日期占比(Percentage of elapsed time)** @param localDate 日期* @return 默认保留四位小数【四舍五入】*/public static double dayInMothPercent(LocalDate localDate) {return dayInMothPercent(localDate, 4);}/*** 已过日期占比(Percentage of elapsed time)** @param localDateTime 日期* @param scale 小数位* @return 默认保留四位小数【四舍五入】*/public static double dayInMothPercent(LocalDate localDateTime, int scale) {int today = localDateTime.getDayOfMonth();int maxDays = localDateTime.getMonth().maxLength();return NumberUtil.div(today, maxDays, scale);}}
并行流
Arrays.stream(values())
👍 Stream.of(values()).parallel()
非并行流
1927
1238
1212
1173
1009
并行流
1755
947
975
1013
999
878
[2021-09-02 17:29:18.259 http-nio-8088-exec-10
[2021-09-02 17:29:18.261 http-nio-8088-exec-10
[2021-09-02 17:29:18.263 ForkJoinPool.commonPool-worker-1
[2021-09-02 17:29:18.264 ForkJoinPool.commonPool-worker-1
[2021-09-02 17:29:18.265 ForkJoinPool.commonPool-worker-1
[2021-09-02 17:29:18.265 ForkJoinPool.commonPool-worker-1
[2021-09-02 17:29:18.266 ForkJoinPool.commonPool-worker-0
[2021-09-02 17:29:18.266 ForkJoinPool.commonPool-worker-0
[2021-09-02 17:29:18.266 ForkJoinPool.commonPool-worker-0
[2021-09-02 17:29:18.265 http-nio-8088-exec-10
[2021-09-02 17:29:18.268 ForkJoinPool.commonPool-worker-3
[2021-09-02 17:29:18.268 ForkJoinPool.commonPool-worker-0
[2021-09-02 17:29:18.269 http-nio-8088-exec-10
[2021-09-02 17:29:18.271 http-nio-8088-exec-10
[2021-09-02 17:29:18.332 ForkJoinPool.commonPool-worker-0
[2021-09-02 17:29:18.332 ForkJoinPool.commonPool-worker-0
[2021-09-02 17:29:18.665 http-nio-8088-exec-10
[2021-09-02 17:29:18.666 http-nio-8088-exec-10
[2021-09-02 17:29:19.134 ForkJoinPool.commonPool-worker-1
[2021-09-02 17:29:19.136 ForkJoinPool.commonPool-worker-1
[2021-09-02 17:29:19.138 http-nio-8088-exec-10
[2021-09-02 17:29:19.139 http-nio-8088-exec-10
日期
计算当前日期的一周前:
LocalDate today = LocalDate.now();
LocalDate aWeekAgo= today.minus(1, ChronoUnit.WEEKS);
String format = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println(“format = “ + format);
输出:
format = 2021-09-02
RestTemplate
自动URLEncode
import cn.hutool.crypto.digest.DigestUtil;import cn.hutool.crypto.digest.HMac;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Configuration;import org.springframework.stereotype.Component;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import java.nio.charset.StandardCharsets;import java.time.Instant;import java.util.*;import java.util.stream.Collectors;import static cn.hutool.crypto.digest.HmacAlgorithm.HmacSHA1;/*** @author yx.Jiang* @desc 天氣API* @date 2021-09-03 15:40*/@Configurationpublic class WeatherSignUtil {/*** 新知天气公钥* https://docs.seniverse.com/api/start/key.html*/private static String publicKey;@Value("${weather.publicKey}")public void setPublicKey(String publicKey) {WeatherSignUtil.publicKey = publicKey;}/*** 新知天气私钥* https://docs.seniverse.com/api/start/key.html*/private static String privateKey;@Value("${weather.privateKey}")public void setPrivateKey(String privateKey) {WeatherSignUtil.privateKey = privateKey;}/*** 生成签名** @return sign*/public static String genSign() {HashMap<String, Object> map = new HashMap<>();//时间戳map.put("ts", Instant.now().getEpochSecond());//sign有效期map.put("ttl", 1_800);//公钥map.put("uid", publicKey);String rawStr = map.keySet().stream().sorted(String::compareTo).map(key -> key + "=" + map.get(key)).collect(Collectors.joining("&", "", ""));String sign = genSign(rawStr);System.out.println("sign1 = " + sign);try {sign = URLEncoder.encode(sign, StandardCharsets.UTF_8.name());} catch (UnsupportedEncodingException e) {e.printStackTrace();}System.out.println("sign2 = " + sign);return rawStr + "&sig=" + sign;}/*** 生成签名** @param rawStr 原始串* @return sign*/private static String genSign(String rawStr) {//HMAC-SHA1 —— 私钥加密HMac hmac = DigestUtil.hmac(HmacSHA1, privateKey.getBytes(StandardCharsets.UTF_8));return hmac.digestBase64(rawStr, Boolean.FALSE);}}
restTemplate请求接口 响应 403 异常;org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden
以为是生成的sign有问题,再三确认后(单独拿生成的sign自行拼接URL在浏览器请求无问题后);
debug中的实际请求URL为(URLEncode后的结果):
https://api.seniverse.com/v3/weather/hourly.json?ts%3D1630664408%26ttl%3D1800%26uid%3DPOOzALiQ_Pcb1qPPM%26sig%3DZw7gxWoLf629a0OIuCq16p5%252FF%252F4%253D&language%3Dzh-Hans%26location%3D%E4%B8%8A%E6%B5%B7%26unit%3Dc&start=0&hours=24
将其decode后
http://tool.chinaz.com/tools/urlencode.aspx
这是
结果如上图所示:
https://api.seniverse.com/v3/weather/hourly.json?ts=1630664408&ttl=1800&uid=POOzALiQ_Pcb1qPPM&sig=Zw7gxWoLf629a0OIuCq16p5%2FF%2F4%3D&language=zh-Hans&location=上海&unit=c&start=0&hours=24
j将解码后的URL输入浏览器,可正常返回结果:
接下来就是要:避免RestTemplate的UrlEncode, 参考链接https://blog.csdn.net/wangooo/article/details/117161950
仅urlEncode请求中的特殊字符(如:汉字、sign(28bit—base64));
finalize
@Deprecatedclass HashDemo {public static HashDemo save = null;public void isA() {System.out.println("111-isA");}@Overrideprotected void finalize() throws Throwable {super.finalize();System.out.println("ddd-finalize");HashDemo.save = this;}public static void main(String[] args) throws InterruptedException {save = new HashDemo();save = null;System.gc();Thread.sleep(500);if (save != null) {save.isA();} else {System.out.println("222---111");}save = null;System.gc();Thread.sleep(500);if (save != null) {save.isA();} else {System.out.println("222---222");}}}//输出结果ddd-finalize111-isA222---222
FastJson
import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.annotation.JSONField;import lombok.Data;import java.time.LocalDate;import java.time.LocalDateTime;public static void main(String[] args) {User user = new User();user.setName("测试序列化");user.setBirthday(LocalDateTime.now());user.setTime(LocalDateTime.now());user.setDate(LocalDate.now());String s = JSON.toJSONStringWithDateFormat(user, "yyyy-MM-dd HH:mm:ss");System.out.println(s);//{"birthday":"2021-09-24 19:31:23","date":"2021-09-24","name":"测试序列化","time":"19:31"}}@Datastatic class User {private String name;private LocalDateTime birthday;@JSONField(format = "HH:mm")private LocalDateTime time;private LocalDate date;}
