目錄
一、編寫目的
二、映射工具類
2.1 依賴
2.2 代碼
三、日期格式
3.1 依賴
3.2 代碼
四、加密
4.1 代碼
五、Http請求
5.1 依賴
5.2 代碼
六、金額
6.1?代碼
七、二維碼
7.1 依賴
7.2 代碼
八、坐標轉換
8.1 代碼
九、樹結構
9.1?代碼
9.1.1 節點
?9.1.2 工具類
十、結語
Welcome to Code Block’s blog
本篇文章主要介紹了
[Springboot應用開發:工具類整理]
博主廣交技術好友,喜歡文章的可以關注一下
一、編寫目的
在實際的Springboot應用開發中,有很多類可作為工具類,這些類將實際開發中可能用到的重復性代碼進行提取,方便在后續的開發中使用,在這里我對在開發中經常用到的工具類進行整理,方便自己之后查找,同時希望可以幫助到有實現相關功能的朋友。
二、映射工具類
映射工具類主要用于在不同實體類結構之間的轉換,經常用于DTO->BO的轉換.例:在Controller中接收的Body(DTO)與要存儲到數據庫中的字段(BO)經常是不同的.這時可以使用該工具類進行轉換,使用sourceToTarget對單個實體類或列表進行轉換.具體代碼如下:
2.1 依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency>
2.2 代碼
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;import java.util.ArrayList;
import java.util.Collection;
import java.util.List;/*** 轉換工具類*/
public class ConvertUtils {private static Logger logger = LoggerFactory.getLogger(ConvertUtils.class);/**** @param source 原始類實體* @param target 目標類* @return 目標類實體* @param <T> 泛型*/public static <T> T sourceToTarget(Object source, Class<T> target){if(source == null){return null;}T targetObject = null;try {targetObject = target.newInstance();BeanUtils.copyProperties(source, targetObject);} catch (Exception e) {logger.error("convert error ", e);}return targetObject;}/**** @param sourceList 原始類實體列表* @param target 目標類* @return 目標類實體列表* @param <T> 泛型*/public static <T> List<T> sourceToTarget(Collection<?> sourceList, Class<T> target){if(sourceList == null){return null;}List targetList = new ArrayList<>(sourceList.size());try {for(Object source : sourceList){T targetObject = target.newInstance();BeanUtils.copyProperties(source, targetObject);targetList.add(targetObject);}}catch (Exception e){logger.error("convert error ", e);}return targetList;}
}
三、日期格式
日期格式工具類主要用于日期格式的轉換和日期的計算,例如:從yyyy-MM-dd HH:mm:ss轉換為yyyy-MM-dd格式或者從字符串轉換為日期格式.具體代碼如下:
3.1 依賴
<dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>2.9.9</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.9</version><!--$NO-MVN-MAN-VER$ --></dependency>
3.2 代碼
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;/*** 日期處理* @author seaua*/
public class DateUtils {/** 時間格式(yyyy-MM-dd) */public final static String DATE_PATTERN = "yyyy-MM-dd";/** 時間格式(yyyy-MM-dd HH:mm:ss) */public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";public static Date parse(String date) {if(StringUtils.isEmpty(date)){return null;}SimpleDateFormat df = new SimpleDateFormat(DATE_TIME_PATTERN);try {return df.parse(date);} catch (ParseException e) {e.printStackTrace();return null;}}/*** 日期格式化 日期格式為:yyyy-MM-dd* @param date 日期* @return 返回yyyy-MM-dd格式日期*/public static String format(Date date) {return format(date, DATE_PATTERN);}/*** 日期格式化 日期格式為:yyyy-MM-dd* @param date 日期* @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN* @return 返回yyyy-MM-dd格式日期*/public static String format(Date date, String pattern) {if(date != null){SimpleDateFormat df = new SimpleDateFormat(pattern);return df.format(date);}return null;}/*** 日期解析* @param date 日期* @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN* @return 返回Date*/public static Date parse(String date, String pattern) {try {return new SimpleDateFormat(pattern).parse(date);} catch (ParseException e) {e.printStackTrace();}return null;}/*** 字符串轉換成日期* @param strDate 日期字符串* @param pattern 日期的格式,如:DateUtils.DATE_TIME_PATTERN*/public static Date stringToDate(String strDate, String pattern) {if (StringUtils.isBlank(strDate)){return null;}DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern);return fmt.parseLocalDateTime(strDate).toDate();}/*** 根據周數,獲取開始日期、結束日期* @param week 周期 0本周,-1上周,-2上上周,1下周,2下下周* @return 返回date[0]開始日期、date[1]結束日期*/public static Date[] getWeekStartAndEnd(int week) {DateTime dateTime = new DateTime();LocalDate date = new LocalDate(dateTime.plusWeeks(week));date = date.dayOfWeek().withMinimumValue();Date beginDate = date.toDate();Date endDate = date.plusDays(6).toDate();return new Date[]{beginDate, endDate};}/*** 對日期的【秒】進行加/減** @param date 日期* @param seconds 秒數,負數為減* @return 加/減幾秒后的日期*/public static Date addDateSeconds(Date date, int seconds) {DateTime dateTime = new DateTime(date);return dateTime.plusSeconds(seconds).toDate();}/*** 對日期的【分鐘】進行加/減** @param date 日期* @param minutes 分鐘數,負數為減* @return 加/減幾分鐘后的日期*/public static Date addDateMinutes(Date date, int minutes) {DateTime dateTime = new DateTime(date);return dateTime.plusMinutes(minutes).toDate();}/*** 對日期的【小時】進行加/減** @param date 日期* @param hours 小時數,負數為減* @return 加/減幾小時后的日期*/public static Date addDateHours(Date date, int hours) {DateTime dateTime = new DateTime(date);return dateTime.plusHours(hours).toDate();}/*** 對日期的【天】進行加/減** @param date 日期* @param days 天數,負數為減* @return 加/減幾天后的日期*/public static Date addDateDays(Date date, int days) {DateTime dateTime = new DateTime(date);return dateTime.plusDays(days).toDate();}/*** 對日期的【周】進行加/減** @param date 日期* @param weeks 周數,負數為減* @return 加/減幾周后的日期*/public static Date addDateWeeks(Date date, int weeks) {DateTime dateTime = new DateTime(date);return dateTime.plusWeeks(weeks).toDate();}/*** 對日期的【月】進行加/減** @param date 日期* @param months 月數,負數為減* @return 加/減幾月后的日期*/public static Date addDateMonths(Date date, int months) {DateTime dateTime = new DateTime(date);return dateTime.plusMonths(months).toDate();}/*** 對日期的【年】進行加/減** @param date 日期* @param years 年數,負數為減* @return 加/減幾年后的日期*/public static Date addDateYears(Date date, int years) {DateTime dateTime = new DateTime(date);return dateTime.plusYears(years).toDate();}
}
四、加密
加密工具類用于對數據進行加密,這里是使用HmacSHA256加密算法進行加密,具體代碼如下:
4.1 代碼
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;public class HMACSHA256 {public static String HMACSHA256(String key, String data) {try {SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA256");Mac mac = Mac.getInstance("HmacSHA256");mac.init(signingKey);return byte2hex(mac.doFinal(data.getBytes()));} catch (NoSuchAlgorithmException | InvalidKeyException e) {e.printStackTrace();}return null;}public static String byte2hex(byte[] b) {StringBuilder hs = new StringBuilder();String stmp;for (int n = 0; b != null && n < b.length; n++) {stmp = Integer.toHexString(b[n] & 0XFF);if (stmp.length() == 1) {hs.append('0');}hs.append(stmp);}return hs.toString().toUpperCase();}
}
五、Http請求
Http請求工具類用于從request獲取相關請求參數,如獲取參數列表(ParameterMap)或者請求的Language參數.具體代碼如下:
5.1 依賴
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.9</version><!--$NO-MVN-MAN-VER$ --></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
5.2 代碼
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;/*** Http*/
public class HttpContextUtils {/*** 獲取http請求* @return request*/public static HttpServletRequest getHttpServletRequest() {RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();if (requestAttributes == null) {return null;}return ((ServletRequestAttributes) requestAttributes).getRequest();}/*** 獲取http請求的請求參數列表* @param request http請求* @return 請求參數列表*/public static Map<String, String> getParameterMap(HttpServletRequest request) {Enumeration<String> parameters = request.getParameterNames();Map<String, String> params = new HashMap<>();while (parameters.hasMoreElements()) {String parameter = parameters.nextElement();String value = request.getParameter(parameter);if (StringUtils.isNotBlank(value)) {params.put(parameter, value);}}return params;}/*** 獲取域名 Domain* @return Domain*/public static String getDomain() {HttpServletRequest request = getHttpServletRequest();StringBuffer url = request.getRequestURL();return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();}/*** 獲取請求地址* @return origin*/public static String getOrigin() {HttpServletRequest request = getHttpServletRequest();return request.getHeader(HttpHeaders.ORIGIN);}/*** 獲取語言,默認返回 "zh-CN"* @return language*/public static String getLanguage() {// 默認語言String defaultLanguage = "zh-CN";// requestHttpServletRequest request = getHttpServletRequest();if (request == null) {return defaultLanguage;}// 請求語言defaultLanguage = request.getHeader(HttpHeaders.ACCEPT_LANGUAGE);return defaultLanguage;}/*** 獲取請求消息頭中的數據*/public static String getRequestReader(HttpServletRequest request) {String line;StringBuilder sb = new StringBuilder();try {while ((line = request.getReader().readLine()) != null) {sb.append(line);}request.getReader().close();} catch (Exception e) {e.printStackTrace();}return sb.toString();}}
六、金額
金額用于對金額數據進行轉換,即帶有¥格式的字符串數據,將其轉換為方便存儲和計算的數據,本工具類中將元轉換為分.具體代碼如下:
6.1代碼
/*** @author seaua*/
public class MoneyUtil {/*** 獲取金額,轉換單位,元轉換成分*/public static String getMoney(String amount) {if (amount == null) {return "0";}String currency = amount.replaceAll("[$¥,]", ""); // 處理包含, ¥// 或者$的金額int index = currency.indexOf(".");int length = currency.length();long amLong;if (index == -1) {amLong = Long.parseLong(currency + "00");} else if (length - index >= 3) {amLong = Long.parseLong((currency.substring(0, index + 3)).replace(".", ""));} else if (length - index == 2) {amLong = Long.parseLong((currency.substring(0, index + 2)).replace(".", "") + 0);} else {amLong = Long.parseLong((currency.substring(0, index + 1)).replace(".", "") + "00");}return Long.toString(amLong);}
}
七、二維碼
二維碼工具類在實際開發中用于二維碼的生成,在本工具類中createImageToLocal將生成的二維碼存儲到本地,createImage用于生成二維碼并轉換為base64字符串,用于在網絡中傳輸.具體代碼如下:
7.1 依賴
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.10.70.ALL</version></dependency><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.3</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.3</version></dependency>
7.2 代碼
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.Hashtable;import javax.imageio.ImageIO;import com.alipay.api.internal.util.file.ByteArrayOutputStream;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;import cn.hutool.core.codec.Base64Encoder;public class QRCodeUtil {// 二維碼尺寸public static final int QRCODE_SIZE = 300;// 存放二維碼的路徑public static final String PAY_PATH = "c://pay";/*** 生成二維碼存到本地* * @param content 源內容* @param outputStream 輸出流* @throws Exception*/public static void createImageToLocal(String content, OutputStream outputStream) throws Exception {Hashtable hints = new Hashtable();hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);hints.put(EncodeHintType.CHARACTER_SET, "utf-8");hints.put(EncodeHintType.MARGIN, 1);BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,hints);int width = bitMatrix.getWidth();int height = bitMatrix.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, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);}}// 存到磁盤ImageIO.write(image, "jpg", outputStream);}/*** 生成二維碼* * @param content 源內容* @return* @throws Exception*/public static String createImage(String content) throws Exception {Hashtable hints = new Hashtable();hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);hints.put(EncodeHintType.CHARACTER_SET, "utf-8");hints.put(EncodeHintType.MARGIN, 1);BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,hints);int width = bitMatrix.getWidth();int height = bitMatrix.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, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);}}// 創建儲存圖片二進制流的輸出流ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(image, "jpg", baos);// 轉成Base64格式byte[] b = baos.toByteArray();Base64Encoder encoder = new Base64Encoder();return encoder.encode(b);}}
八、坐標轉換
坐標轉換用于不同地理坐標數據之間的轉換,這在地理應用開發中經常用到,在本篇文章中的代碼中實現gps84ToXY(wgs84到大地2000),GCJ02ToWGS84:火星坐標系(GCJ02)轉地球坐標系(WGS84)具體代碼如下:
8.1 代碼
public class RtkUtils {/*** 將WGS84經緯度轉為大地2000坐標** @param B 緯度* @param L 經度* @param degree //* @return*/public static double[] gps84ToXY(double B, double L, double degree) {double[] xy = {0, 0};double a = 6378137;//橢球長半軸double b = 6356752.3142451795;//橢球短半軸double e = 0.081819190842621;//第一偏心率double eC = 0.0820944379496957;//第二偏心率double L0 = 0;//中央子午線經度int n = 0;//帶號if (degree == 6) {//6度n = (int) (Math.round((L + degree / 2) / degree));L0 = degree * n - degree / 2;} else {//3度n = (int) Math.round(L / degree);L0 = degree * n;}//開始計算double radB = B * Math.PI / 180;//緯度(弧度)double radL = L * Math.PI / 180;//經度(弧度)double deltaL = (L - L0) * Math.PI / 180;//經度差(弧度)double N = a * a / b / Math.sqrt(1 + eC * eC * Math.cos(radB) * Math.cos(radB));double C1 = 1.0 + 3.0 / 4 * e * e + 45.0 / 64 * Math.pow(e, 4) + 175.0 / 256 * Math.pow(e, 6) + 11025.0 / 16384 * Math.pow(e, 8);double C2 = 3.0 / 4 * e * e + 15.0 / 16 * Math.pow(e, 4) + 525.0 / 512 * Math.pow(e, 6) + 2205.0 / 2048 * Math.pow(e, 8);double C3 = 15.0 / 64 * Math.pow(e, 4) + 105.0 / 256 * Math.pow(e, 6) + 2205.0 / 4096 * Math.pow(e, 8);double C4 = 35.0 / 512 * Math.pow(e, 6) + 315.0 / 2048 * Math.pow(e, 8);double C5 = 315.0 / 131072 * Math.pow(e, 8);double t = Math.tan(radB);double eta = eC * Math.cos(radB);double X = a * (1 - e * e) * (C1 * radB - C2 * Math.sin(2 * radB) / 2 + C3 * Math.sin(4 * radB) / 4 - C4 * Math.sin(6 * radB) / 6 + C5 * Math.sin(8 * radB));xy[0] = X + N * Math.sin(radB) * Math.cos(radB) * Math.pow(deltaL, 2) * (1 + Math.pow(deltaL * Math.cos(radB), 2) * (5 - t * t + 9 * eta * eta + 4 * Math.pow(eta, 4)) / 12 + Math.pow(deltaL * Math.cos(radB), 4) * (61 - 58 * t * t + Math.pow(t, 4)) / 360) / 2;xy[1] = N * deltaL * Math.cos(radB) * (1 + Math.pow(deltaL * Math.cos(radB), 2) * (1 - t * t + eta * eta) / 6 + Math.pow(deltaL * Math.cos(radB), 4) * (5 - 18 * t * t + Math.pow(t, 4) - 14 * eta * eta - 58 * eta * eta * t * t) / 120) + 500000;// +n * 1000000;return xy;}private static final double PI = 3.1415926535897932384626;// 衛星橢球坐標投影到平面地圖坐標系的投影因子。 地球長半徑private static final double EARTH_MAJOR_RADIUS = 6378245.0;// 橢球的偏心率。private static final double ECCENTRICITY_RATIO = 0.00669342162296594323;/*** 火星坐標系(GCJ02)轉地球坐標系(WGS84)** @param gcjLat 火星坐標緯度* @param gcjLng 火星坐標經度*/public static Double[] GCJ02ToWGS84(Double gcjLng, Double gcjLat) {double dlat = transformlat(gcjLng - 105.0, gcjLat - 35.0);double dlng = transformlng(gcjLng - 105.0, gcjLat - 35.0);double radlat = gcjLat / 180.0 * PI;double magic = Math.sin(radlat);magic = 1 - ECCENTRICITY_RATIO * magic * magic;double sqrtmagic = Math.sqrt(magic);dlat = (dlat * 180.0) / ((EARTH_MAJOR_RADIUS * (1 - ECCENTRICITY_RATIO)) / (magic * sqrtmagic) * PI);dlng = (dlng * 180.0) / (EARTH_MAJOR_RADIUS / sqrtmagic * Math.cos(radlat) * PI);double mglat = gcjLat + dlat;double mglng = gcjLng + dlng;return new Double[]{gcjLng * 2 - mglng, gcjLat * 2 - mglat};}private static Double transformlat(double lng, double lat) {double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;return ret;}private static Double transformlng(double lng, double lat) {double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;return ret;}}
九、樹結構
樹結構工具類在實際開發中用于處理樹狀結構,如菜單、部門數據的展示等,具體代碼如下:
9.1代碼
9.1.1 節點
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;/*** 樹節點,所有需要實現樹節點的,都需要繼承該類* @author seaua*/
public class TreeNode<T> implements Serializable {private static final long serialVersionUID = 1L;/*** 主鍵*/private Long id;/*** 上級ID*/private Long pid;/*** 子節點列表*/private List<T> children = new ArrayList<>();public Long getId() {return id;}public void setId(Long id) {this.id = id;}public Long getPid() {return pid;}public void setPid(Long pid) {this.pid = pid;}public List<T> getChildren() {return children;}public void setChildren(List<T> children) {this.children = children;}
}
9.1.2 工具類
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;/*** 樹形結構工具類,如:菜單、部門等*/
public class TreeUtils {/*** 根據pid,構建樹節點*/public static <T extends TreeNode> List<T> build(List<T> treeNodes, Long pid) {//pid不能為空AssertUtils.isNull(pid, "pid");List<T> treeList = new ArrayList<>();for(T treeNode : treeNodes) {if (pid.equals(treeNode.getPid())) {treeList.add(findChildren(treeNodes, treeNode));}}return treeList;}/*** 查找子節點*/private static <T extends TreeNode> T findChildren(List<T> treeNodes, T rootNode) {for(T treeNode : treeNodes) {if(rootNode.getId().equals(treeNode.getPid())) {rootNode.getChildren().add(findChildren(treeNodes, treeNode));}}return rootNode;}/*** 構建樹節點*/public static <T extends TreeNode> List<T> build(List<T> treeNodes) {List<T> result = new ArrayList<>();//list轉mapMap<Long, T> nodeMap = new LinkedHashMap<>(treeNodes.size());for(T treeNode : treeNodes){nodeMap.put(treeNode.getId(), treeNode);}for(T node : nodeMap.values()) {T parent = nodeMap.get(node.getPid());if(parent != null && !(node.getId().equals(parent.getId()))){parent.getChildren().add(node);continue;}result.add(node);}return result;}}
十、結語
上述為本人在實際開發中經常用到的工具類,您可以直接使用這些工具類代碼,當然也可以優化這些類并擴展自己的相關功能。
如果你對區塊鏈感興趣,可以看一下我的區塊鏈專欄.
感謝關注和收藏!