Spring boot开发中“积累[鸡肋]”的工具类

StringUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.Date;
import java.util.Formatter;
import java.util.UUID;
import org.springframework.lang.Nullable;
import org.springframework.util.DigestUtils;

public class StringUtils extends org.springframework.util.StringUtils {

public static boolean equals(@Nullable String str1, @Nullable String str2) {
if (str1 == null || str2 == null) {
return (str1 == null && str2 == null);
}
return str1.equals(str2);
}

public static boolean isBlank(@Nullable String string) {
if (isEmpty(string)) {
return true;
}
for (int i = 0; i < string.length(); i++) {
if (!Character.isWhitespace(string.charAt(i))) {
return false;
}
}
return true;
}

public static boolean isNotBlank(@Nullable String string) {
return !StringUtils.isBlank(string);
}

public static boolean isBlank(@Nullable Integer id) {
return id == null || id == 0;
}

public static boolean isNotBlank(@Nullable Integer id) {
return id != null && id != 0;
}

public static String[] split(@Nullable String string, @Nullable String delimiter, int limit) {
if (isEmpty(string) || delimiter == null || limit == 1) {
return new String[]{string};
}
return string.split(delimiter, limit);
}

/* @return uuid string(32) */
public static String uuid() {
return UUID.randomUUID().toString().replace("-", "");
}

private static final String[] chars = new String[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6",
"7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z" };
/* gen short unique id(8 chars) */
public static String unid8() {
return StringUtils.unid8(null);
}
private static String unid8(String uuid32) {
StringBuffer shortBuffer = new StringBuffer();
if (StringUtils.isBlank(uuid32)) {
uuid32 = StringUtils.uuid();
}
for (int i = 0; i < 8; i++) {
String str = uuid32.substring(i * 4, i * 4 + 4);
int x = Integer.parseInt(str, 16);
shortBuffer.append(StringUtils.chars[x % 0x3E]);
}
return shortBuffer.toString();
}
/* gen unique id(20 chars) that has timestamp */
public static String unid20() {
long ts = new Date().getTime();
return String.format("%d_%s", ts, StringUtils.unid8());
}

/* MD5, null as empty str. */
public static String MD5(String str) {
if (str == null) {
str = "";
}
return DigestUtils.md5DigestAsHex(str.getBytes());
}

/* SHA-1, null as empty str. */
public static String SHA1(String str) {
if (str == null) {
return "";
}
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(str.getBytes("UTF-8"));
return byteToHex(crypt.digest());
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}

public static String urlDecode(String raw) {
try {
return URLDecoder.decode(raw, "UTF-8");
} catch (UnsupportedEncodingException uee) {
throw new IllegalStateException(uee); // can't happen
}
}

public static String urlEncode(String str) {
try {
return URLEncoder.encode(str, "UTF-8");
} catch (UnsupportedEncodingException uee) {
throw new IllegalStateException(uee); // can't happen
}
}

public static String urlEncode(String str, String en) {
try {
return URLEncoder.encode(str, en);
} catch (UnsupportedEncodingException uee) {
throw new IllegalStateException(uee); // can't happen
}
}

public static String convert(String str, String from, String to) {
try {
str = new String(str.getBytes(from), to);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return str;
}
}

NumberUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import org.springframework.lang.Nullable;

public class NumberUtils extends org.springframework.util.NumberUtils {
public static <T extends Number> boolean equals(@Nullable T a, @Nullable T b) {
if (a == null || b == null) {
return (a == null && b == null);
}
return a.equals(b);
}

public static <T extends Number> T parse(String text, Class<T> targetClass, T defaultValue) {
if (text == null || text.equals("")) {
return defaultValue;
}
try {
return NumberUtils.parseNumber(text, targetClass);
}catch(Exception e){
e.printStackTrace();
}
return defaultValue;
}
public static <T extends Number> T parse(String text, Class<T> targetClass) {
return NumberUtils.parse(text, targetClass, null);
}
public static Integer parseInt(String text) {
return NumberUtils.parse(text, Integer.class);
}
public static Long parseLong(String text) {
return NumberUtils.parse(text, Long.class);
}
}

DateTimeUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.chrono.ChronoLocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Locale;
import org.springframework.lang.Nullable;

public class DateTimeUtils {
public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

public static int compare(Date theDate, Date anotherDate) {
if (theDate == null) {
theDate = new Date();
}
if (anotherDate == null) {
anotherDate = new Date();
}
return theDate.compareTo(anotherDate);
}

public static int compare(ChronoLocalDateTime<?> theDate, ChronoLocalDateTime<?> anotherDate) {
if (theDate == null) {
theDate = LocalDateTime.now();
}
if (anotherDate == null) {
anotherDate = LocalDateTime.now();
}
return theDate.compareTo(anotherDate);
}

public static Date toDate(LocalDateTime localDateTime) {
if (localDateTime == null) return null;
return Date.from(localDateTime.toInstant(ZoneOffset.of("+8")));
}

public static LocalDateTime toLocalDateTime(Date date) {
if (date == null) return null;
return fromMilli(date.getTime());
}

public static Date parseDate(@Nullable String string) {
SimpleDateFormat format = new SimpleDateFormat(DATETIME_PATTERN, Locale.CHINA);
try {
return format.parse(string);
} catch (Exception e) {
return null;
}
}
public static LocalDateTime parseLocalDateTime(@Nullable String string) {
DateTimeFormatter format = DateTimeFormatter.ofPattern(DATETIME_PATTERN, Locale.CHINA);
try {
return LocalDateTime.parse(string, format);
} catch (Exception e) {
return null;
}
}

public static String formatDateTime(LocalDateTime dt) {
if (dt == null) return null;

DateTimeFormatter format = DateTimeFormatter.ofPattern(DATETIME_PATTERN, Locale.CHINA);
return dt.format(format);
}

public static LocalDateTime fromSecond(long second, ZoneOffset offset) {
if (offset == null) {
offset = ZoneOffset.of("+8");
}
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(second, 0, offset);
return localDateTime;
}
public static LocalDateTime fromSecond(long second) {
return DateTimeUtils.fromSecond(second, null);
}

public static LocalDateTime fromMilli(long ts, ZoneOffset offset) {
if (offset == null) {
offset = ZoneOffset.of("+8");
}
Instant instant = Instant.ofEpochMilli(ts);
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, offset);
return localDateTime;
}
public static LocalDateTime fromMilli(long ts) {
return DateTimeUtils.fromMilli(ts, null);
}

//返回世纪秒
public static long secondsOf(ChronoLocalDateTime<?> ldt, ZoneOffset offset) {
if (ldt == null) {
return 0;
}
if (offset == null) {
offset = ZoneOffset.of("+8");
}
long second = ldt.toEpochSecond(offset);
return second;
}
public static long secondsOf(ChronoLocalDateTime<?> ldt) {
return DateTimeUtils.secondsOf(ldt, null);
}

//返回世纪毫秒
public static long micsecondsOf(ChronoLocalDateTime<?> ldt, ZoneOffset offset) {
if (ldt == null) {
return 0;
}
if (offset == null) {
offset = ZoneOffset.of("+8");
}
long mic = ldt.toInstant(offset).toEpochMilli();
return mic;
}
public static long micsecondsOf(ChronoLocalDateTime<?> ldt) {
return DateTimeUtils.micsecondsOf(ldt, null);
}
}

JSON.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

public class JSON {
@SuppressWarnings("unchecked")
public static Map<String, Object> parse(String jsonStr) {
Map<String, Object> map = new HashMap<>();
try {
map = (Map<String, Object>) JSON.parse(jsonStr, map.getClass());
} catch (Exception e) {
e.printStackTrace();
map = null;
}
return map;
}

public static <T> T parse(String jsonStr, Class<T> toClass) {
try {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(jsonStr, toClass);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

public static <T extends Object> T parse(String jsonStr, TypeReference<T> type) {
try {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
return mapper.readValue(jsonStr, type);
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

public static String stringify(Object obj) {
try {
ObjectMapper mapper = new ObjectMapper();
//https://howtoprogram.xyz/2017/12/30/serialize-java-8-localdate-jackson/
mapper.registerModule(new JavaTimeModule());
//mapper.disable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}

XmlUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

public class XmlUtils {

@SuppressWarnings("unchecked")
public static Map<String, String> parse(String xml){
Map<String, String> map = new HashMap<>();
return (Map<String, String>) XmlUtils.parse(xml, map.getClass());
}

public static <T> T parse(String xml, Class<T> toClass) {
try {
XmlMapper xmlMapper = new XmlMapper();
return xmlMapper.readValue(xml, toClass);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

public static String stringify(Object obj, String root) {
XmlMapper xmlMapper = new XmlMapper();
try {
ObjectWriter writer = xmlMapper.writer();
if (root != null && !"".equals(root)) {
writer = writer.withRootName(root);
}
return writer.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}

BeanUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.beans.PropertyDescriptor;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.StringUtils;

public class BeanUtils extends org.springframework.beans.BeanUtils {
/* copy source properties(not null) to target */
public static void copyPropertiesNotNull(Object source, Object target) {
String[] ignoreProperties = BeanUtils.getNullProperties(source);
BeanUtils.copyProperties(source, target, ignoreProperties);
}

/* copy source properties(not empty) to target */
public static void copyPropertiesNotEmpty(Object source, Object target) {
String[] ignoreProperties = BeanUtils.getEmptyProperties(source);
BeanUtils.copyProperties(source, target, ignoreProperties);
}

/* get object's null properties */
public static String[] getNullProperties(Object obj) {
BeanWrapper bean = new BeanWrapperImpl(obj);
PropertyDescriptor[] descriptors = bean.getPropertyDescriptors();
Set<String> properties = new HashSet<>();
for (PropertyDescriptor property : descriptors) {
String propertyName = property.getName();
Object propertyValue = bean.getPropertyValue(propertyName);
if (propertyValue == null) {
properties.add(propertyName);
}
}
return properties.toArray(new String[0]);
}

/* get object's empty properties */
public static String[] getEmptyProperties(Object obj) {
BeanWrapper bean = new BeanWrapperImpl(obj);
PropertyDescriptor[] descriptors = bean.getPropertyDescriptors();
Set<String> properties = new HashSet<>();
for (PropertyDescriptor property : descriptors) {
String propertyName = property.getName();
Object propertyValue = bean.getPropertyValue(propertyName);
if (StringUtils.isEmpty(propertyValue)) {
properties.add(propertyName);
}
}
return properties.toArray(new String[0]);
}
}

WebUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public class WebUtils extends org.springframework.web.util.WebUtils {
/* 获取request对象 */
public static HttpServletRequest getRequest() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) return null;

return ((ServletRequestAttributes) requestAttributes).getRequest();
}

/* 获取Response对象 */
public static HttpServletResponse getResponse() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) return null;

return ((ServletRequestAttributes) requestAttributes).getResponse();
}

public static boolean isAjaxReq(HttpServletRequest req) {
//使用request.header检测是否为AJAX请求
String contentTypeHeader = req.getHeader("Content-Type");
String acceptHeader = req.getHeader("Accept");
String xRequestedWith = req.getHeader("X-Requested-With");
return ((contentTypeHeader != null && contentTypeHeader.contains("application/json"))
|| (acceptHeader != null && acceptHeader.contains("application/json"))
|| (acceptHeader != null && !acceptHeader.contains("text/html"))
|| "XMLHttpRequest".equalsIgnoreCase(xRequestedWith));
}

// 根据网卡取本机配置的IP
public static String getServerIpAddr() {
try {
InetAddress inet = InetAddress.getLocalHost();
return inet.getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return null;
}

public static String getWebBase() {//Web访问路径
HttpServletRequest request = getRequest();
if (request != null) {
return String.format("%s://%s:%s%s/", request.getScheme(), request.getServerName(), request.getServerPort(), request.getContextPath());
}
return "";
}
}

QRCodeUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public class QRCodeUtils {
private static final String FORMAT_PNG = "JPG";//"PNG";
// 二维码尺寸
private static final int QRCODE_SIZE = 300;

private static final int BLACK = 0xFF000000;//用于设置图案的颜色
private static final int WHITE = 0xFFFFFFFF; //用于背景色

public static byte[] genQRCodeImageBytes(String str) {
return QRCodeUtils.genQRCodeImageBytes(str, null, QRCODE_SIZE, QRCODE_SIZE);
}

public static byte[] genQRCodeImageBytes(String str, String logoPath) {
return QRCodeUtils.genQRCodeImageBytes(str, logoPath, QRCODE_SIZE, QRCODE_SIZE);
}

public static byte[] genQRCodeImageBytes(String str, String logoPath, int width, int height) {
byte[] qrcode = null;
try {
QRCodeWriter qrCodeWriter = new QRCodeWriter();
Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
BitMatrix bitMatrix = qrCodeWriter.encode(str, BarcodeFormat.QR_CODE, width, height, hints);

ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
if (StringUtils.isBlank(logoPath)) {
MatrixToImageWriter.writeToStream(bitMatrix, FORMAT_PNG, pngOutputStream);
} else {
BufferedImage image = QRCodeUtils.toBufferedImage(bitMatrix);
QRCodeUtils.addLogo(image, logoPath);
ImageIO.write(image, FORMAT_PNG, pngOutputStream);
}
qrcode = pngOutputStream.toByteArray();
} catch (WriterException e) {
System.out.println("Could not generate QR Code, WriterException :: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.out.println("Could not generate QR Code, IOException :: " + e.getMessage());
e.printStackTrace();
}
return qrcode;
}

private static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, (matrix.get(x, y) ? BLACK : WHITE));
//image.setRGB(x, y, (matrix.get(x, y) ? Color.YELLOW.getRGB() : Color.CYAN.getRGB()));
}
}
return image;
}

// 二维码加 logo
private static BufferedImage addLogo(BufferedImage matrixImage, String logoPath) {
int matrixWidth = matrixImage.getWidth();
int matrixHeigh = matrixImage.getHeight();

//读取二维码图片,并构建绘图对象
Graphics2D g2 = matrixImage.createGraphics();
BufferedImage logoImage;
try {
logoImage = ImageIO.read(new File(logoPath));//读取Logo图片
// 开始绘制图片
g2.drawImage(logoImage, matrixWidth / 5 * 2, matrixHeigh / 5 * 2, matrixWidth / 5, matrixHeigh / 5, null);// 绘制
BasicStroke stroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g2.setStroke(stroke);// 设置笔画对象
RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth / 5 * 2, matrixHeigh / 5 * 2, matrixWidth / 5, matrixHeigh / 5, 20, 20);//指定弧度的圆角矩形
g2.setColor(Color.white);
g2.draw(round);// 绘制圆弧矩形

// 设置logo 有一道灰色边框
BasicStroke stroke2 = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g2.setStroke(stroke2);// 设置笔画对象
RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth / 5 * 2 + 2, matrixHeigh / 5 * 2 + 2, matrixWidth / 5 - 4, matrixHeigh / 5 - 4, 20, 20);
g2.setColor(new Color(128, 128, 128));
g2.draw(round2);// 绘制圆弧矩形

} catch (IOException e) {
e.printStackTrace();
}

g2.dispose();
matrixImage.flush();
return matrixImage;
}
}