文章
fastjson => jackson
Json序列化
//User 类序列化成 { “userName”:”张三”},又要将 { “name”:”张三”} 序列化成 User类。
//gson
class 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.java
AuthInvalidAop.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.965515
System.out.println((float) 20 / (float) 29 * 100);
//68.96551724137932
System.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
*/
@Configuration
public 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
@Deprecated
class HashDemo {
public static HashDemo save = null;
public void isA() {
System.out.println("111-isA");
}
@Override
protected 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-finalize
111-isA
222---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"}
}
@Data
static class User {
private String name;
private LocalDateTime birthday;
@JSONField(format = "HH:mm")
private LocalDateTime time;
private LocalDate date;
}