Springboot 开发必备的工具类 - zhouted/zhouted.github.io GitHub Wiki

标签: java spring


StringUtils.java

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

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

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

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

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

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

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

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;
	}
}
⚠️ **GitHub.com Fallback** ⚠️