JAVA常用工具類

java開發常用工具類
java正則表達式的匹配包括:郵箱,手機,姓名,昵稱,身份證號,銀行卡號等;
生成6位隨機數;
對url中字元串進行編碼和解碼;
獲取客戶端ip地址;
獲取系統當前時間;

生成32位編碼不含橫線;

生成MD5編碼;

通過身份證獲取性別;

通過身份證獲取生日;

手機號中間4位替換成星號;

郵箱地址加星號;

生成隨機密碼;

 

複製程式碼
  1 package commons;
  2 
  3 import com.alibaba.fastjson.JSONObject;
  4 import org.apache.commons.beanutils.BeanUtilsBean;
  5 import org.apache.commons.beanutils.PropertyUtilsBean;
  6 import org.springframework.util.DigestUtils;
  7 import org.springframework.util.StringUtils;
  8 
  9 import javax.servlet.http.HttpServletRequest;
 10 import java.io.*;
 11 import java.net.MalformedURLException;
 12 import java.net.URL;
 13 import java.net.URLDecoder;
 14 import java.security.SecureRandom;
 15 import java.sql.Timestamp;
 16 import java.text.ParseException;
 17 import java.text.SimpleDateFormat;
 18 import java.util.*;
 19 import java.util.concurrent.locks.Lock;
 20 import java.util.concurrent.locks.ReentrantLock;
 21 import java.util.regex.Matcher;
 22 import java.util.regex.Pattern;
 23 import java.util.stream.Stream;
 24 
 25 /**
 26  * 通用工具類.
 27  */
 28 public class CommonUtil {
 29     private static SecureRandom random = new SecureRandom();
 30 
 31     public static final Pattern MAIL_PATTERN = Pattern.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");
 32 
 33     public static final Pattern MOBILE_PATTERN = Pattern.compile("^1[3|4|5|7|8][0-9]\\d{8}$");
 34 
 35     public static final Pattern NAME_PATTERN = Pattern.compile("^[\\u4E00-\\u9FBF][\\u4E00-\\u9FBF(.|·)]{0,13}[\\u4E00-\\u9FBF]$");
 36 
 37     public static final Pattern NICKNAME_PATTERN = Pattern.compile("^((?!\\d{5})[\\u4E00-\\u9FBF(.|·)|0-9A-Za-z_]){2,11}$");
 38 
 39     public static final Pattern PASSWORD_PATTERN = Pattern.compile("^[\\s\\S]{6,30}$");
 40 
 41     public static final Pattern CODE_PATTERN = Pattern.compile("^0\\d{2,4}$");
 42 
 43     public static final Pattern POSTCODE_PATTERN = Pattern.compile("^\\d{6}$");
 44 
 45     public static final Pattern ID_PATTERN = Pattern.compile("^\\d{6}(\\d{8}|\\d{11})[0-9a-zA-Z]$");
 46 
 47     public static final Pattern BANK_CARD_PATTERN = Pattern.compile("^\\d{16,30}$");
 48 
 49     /**
 50      * 生成6位隨機數字, 用於手機簡訊驗證碼.
 51      *
 52      * @return 6位隨機數字
 53      */
 54     public static int random() {
 55         int x = Math.abs(random.nextInt(899999));
 56 
 57         return x + 100000;
 58     }
 59 
 60     /**
 61      * 對url字元串進行編碼.
 62      *
 63      * @param url 要編碼的url字元串
 64      * @return 編碼後的字元串
 65      */
 66     public static String urlEncoder(String url) {
 67         if (StringUtils.isEmpty(url)) {
 68             return null;
 69         }
 70         try {
 71             return java.net.URLEncoder.encode(url, "utf-8");
 72         } catch (UnsupportedEncodingException e) {
 73             e.printStackTrace();
 74         }
 75         return null;
 76     }
 77 
 78     /**
 79      * 對url字元串進行解碼.
 80      *
 81      * @param url 要解碼的url字元串
 82      * @return 解碼後的字元串
 83      */
 84     public static String urlDecoder(String url) {
 85         if (StringUtils.isEmpty(url)) {
 86             return null;
 87         }
 88         try {
 89             return URLDecoder.decode(url, "UTF-8");
 90         } catch (UnsupportedEncodingException e) {
 91             e.printStackTrace();
 92         }
 93         return null;
 94     }
 95 
 96     /**
 97      * 驗證字元串是不是郵箱.
 98      *
 99      * @param email 要驗證的郵箱
100      * @return 是否正確郵箱
101      */
102     public static boolean validateEmail(String email) {
103         if (StringUtils.isEmpty(email)) {
104             return false;
105         }
106         Matcher m = MAIL_PATTERN.matcher(email);
107         return m.matches();
108     }
109 
110     /**
111      * 驗證字元串是不是手機號.
112      *
113      * @param mobile 要驗證的手機號
114      * @return 是否正確手機號
115      */
116     public static boolean validateMobile(String mobile) {
117         if (StringUtils.isEmpty(mobile)) {
118             return false;
119         }
120         Matcher m = MOBILE_PATTERN.matcher(mobile);
121         return m.matches();
122     }
123 
124     /**
125      * 驗證身份證是否有效.
126      *
127      * @param idCardNumber 要驗證的身份證
128      * @return 是否正確身份證
129      */
130     public static boolean validateId(String idCardNumber) {
131         if (StringUtils.isEmpty(idCardNumber)) {
132             return false;
133         }
134         Matcher m = ID_PATTERN.matcher(idCardNumber);
135         return m.matches() && IdCardUtils.validateCard(idCardNumber);
136     }
137 
138     /**
139      * 驗證姓名是否有效.
140      *
141      * @param name 要驗證的姓名
142      * @return 是否正確姓名
143      */
144     public static boolean validateName(String name) {
145         if (StringUtils.isEmpty(name) || name.replaceAll("[^.·]", "").length() > 1) {
146             return false;
147         }
148         Matcher m = NAME_PATTERN.matcher(name);
149         return m.matches();
150     }
151 
152     /**
153      * 驗證昵稱是否有效.
154      *
155      * @param nickname 要驗證的昵稱
156      * @return 是否正確昵稱
157      */
158     public static boolean validateNickname(String nickname) {
159 
160         //規則 不能包含5個數字 允許中英文和數字 2-11位
161         if (StringUtils.isEmpty(nickname) || nickname.replaceAll("[^0-9]", "").length() > 4) {
162             return false;
163         }
164         Matcher m = NICKNAME_PATTERN.matcher(nickname);
165         return m.matches();
166     }
167 
168     /**
169      * 驗證密碼格式是否有效.
170      *
171      * @param password 要驗證的密碼
172      * @return 是否正確密碼格式
173      */
174     public static boolean validatePassword(String password) {
175         if (StringUtils.isEmpty(password)) {
176             return false;
177         }
178         Matcher m = PASSWORD_PATTERN.matcher(password);
179         return m.matches();
180     }
181 
182     /**
183      * 驗證區號是否有效.
184      *
185      * @param code 要驗證的區號
186      * @return 是否正確身份證
187      */
188     public static boolean validateCode(String code) {
189         if (StringUtils.isEmpty(code)) {
190             return false;
191         }
192         Matcher m = CODE_PATTERN.matcher(code);
193         return m.matches();
194     }
195 
196     /**
197      * 驗證郵政編碼是否有效.
198      *
199      * @param postcode 要驗證的郵政編碼
200      * @return 是否正確郵政編碼
201      */
202     public static boolean validatePostcode(String postcode) {
203         if (StringUtils.isEmpty(postcode)) {
204             return false;
205         }
206         Matcher m = POSTCODE_PATTERN.matcher(postcode);
207         return m.matches();
208     }
209 
210     /**
211      * 驗證銀行卡是否有效.
212      *
213      * @param bankCardNumber 要驗證的銀行卡號
214      * @return 是否正確銀行卡號
215      */
216     public static boolean validateBankCardNumber(String bankCardNumber) {
217         if (StringUtils.isEmpty(bankCardNumber)) {
218             return false;
219         }
220         Matcher m = BANK_CARD_PATTERN.matcher(bankCardNumber);
221         return m.matches();
222     }
223 
224     /**
225      * 獲取客戶端IP地址.
226      *
227      * @param request request請求
228      * @return ip地址
229      */
230     public static String getIpAddr(HttpServletRequest request) {
231         String ip = request.getHeader("Cdn-Src-Ip");
232         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
233             ip = request.getHeader("X-Forwarded-For");
234         }
235         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
236             ip = request.getRemoteAddr();
237         }
238         if (StringUtils.hasText(ip)) {
239             return StringUtils.tokenizeToStringArray(ip, ",")[0];
240         }
241         return "";
242     }
243 
244     /**
245      * 獲取當前系統時間,以java.sql.Timestamp類型返回.
246      *
247      * @return 當前時間
248      */
249     public static Timestamp getTimestamp() {
250         Timestamp d = new Timestamp(System.currentTimeMillis());
251         return d;
252     }
253 
254     /**
255      * 生成32位編碼,不含橫線
256      *
257      * @return uuid串
258      */
259     public static String getUUID() {
260         String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
261         return uuid.toUpperCase();
262     }
263 
264     /**
265      * 生成MD5編碼
266      *
267      * @param data 要編碼的字元串
268      * @return 加密後的字元串
269      */
270     public static String md5(String data) {
271         return md5(data, 1);
272     }
273 
274 
275     /**
276      * 生成MD5編碼
277      *
278      * @param data 要編碼的字元串
279      * @param time 加密次數
280      * @return 加密後的字元串
281      */
282     public static String md5(String data, int time) {
283         byte[] bytes = data == null ? new byte[0] : data.getBytes(Constants.UTF8);
284 
285         while (time-- > 1) {
286             bytes = DigestUtils.md5Digest(bytes);
287         }
288 
289         return DigestUtils.md5DigestAsHex(bytes).toUpperCase();
290     }
291 
292     /**
293      * 空字元串轉為null
294      *
295      * @param object 要規則化的對象
296      * @param <T>    對象類型
297      * @return 規則化後的對象
298      */
299     public static <T> T normalizeBlankStringFields(T object) {
300         if (object == null) return null;
301 
302         PropertyUtilsBean utils = BeanUtilsBean.getInstance().getPropertyUtils();
303         Stream.of(utils.getPropertyDescriptors(object)).forEach(pd -> {
304             try {
305                 Object value = utils.getNestedProperty(object, pd.getName());
306                 if (value == null) return;
307 
308                 if (!StringUtils.hasText(value.toString())) {
309                     utils.setNestedProperty(object, pd.getName(), null);
310                 }
311             } catch (Throwable e) {
312             }
313         });
314 
315         return object;
316     }
317 
318     /**
319      * 通過身份證獲取性別
320      *
321      * @param idNumber 身份證號
322      * @return 返回性別, 0 保密 , 1 男 2 女
323      */
324     public static Integer getGenderByIdNumber(String idNumber) {
325 
326         int gender = 0;
327 
328         if (idNumber.length() == 15) {
329             gender = Integer.parseInt(String.valueOf(idNumber.charAt(14))) % 2 == 0 ? 2 : 1;
330         } else if (idNumber.length() == 18) {
331             gender = Integer.parseInt(String.valueOf(idNumber.charAt(16))) % 2 == 0 ? 2 : 1;
332         }
333 
334         return gender;
335 
336     }
337 
338     /**
339      * 通過身份證獲取生日
340      *
341      * @param idNumber 身份證號
342      * @return 返回生日, 格式為 yyyy-MM-dd 的字元串
343      */
344     public static String getBirthdayByIdNumber(String idNumber) {
345 
346         String birthday = "";
347 
348         if (idNumber.length() == 15) {
349             birthday = "19" + idNumber.substring(6, 8) + "-" + idNumber.substring(8, 10) + "-" + idNumber.substring(10, 12);
350         } else if (idNumber.length() == 18) {
351             birthday = idNumber.substring(6, 10) + "-" + idNumber.substring(10, 12) + "-" + idNumber.substring(12, 14);
352         }
353 
354         return birthday;
355 
356     }
357 
358 
359     /**
360      * 通過身份證獲取年齡
361      *
362      * @param idNumber 身份證號
363      * @return 返回年齡
364      */
365     public static Integer getAgeByIdNumber(String idNumber) {
366 
367         String birthString = getBirthdayByIdNumber(idNumber);
368         if (StringUtils.isEmpty(birthString)) {
369             return 0;
370         }
371 
372         return getAgeByBirthString(birthString);
373 
374     }
375 
376     /**
377      * 通過身份證獲取年齡
378      *
379      * @param idNumber     身份證號
380      * @param isNominalAge 是否按元旦算年齡,過了1月1日加一歲 true : 是 false : 否
381      * @return 返回年齡
382      */
383     public static Integer getAgeByIdNumber(String idNumber, boolean isNominalAge) {
384 
385         String birthString = getBirthdayByIdNumber(idNumber);
386         if (StringUtils.isEmpty(birthString)) {
387             return 0;
388         }
389 
390         return getAgeByBirthString(birthString, isNominalAge);
391 
392     }
393 
394     /**
395      * 通過生日日期獲取年齡
396      *
397      * @param birthDate 生日日期
398      * @return 返回年齡
399      */
400     public static Integer getAgeByBirthDate(Date birthDate) {
401 
402         return getAgeByBirthString(new SimpleDateFormat("yyyy-MM-dd").format(birthDate));
403 
404     }
405 
406 
407     /**
408      * 通過生日字元串獲取年齡
409      *
410      * @param birthString 生日字元串
411      * @return 返回年齡
412      */
413     public static Integer getAgeByBirthString(String birthString) {
414 
415         return getAgeByBirthString(birthString, "yyyy-MM-dd");
416 
417     }
418 
419     /**
420      * 通過生日字元串獲取年齡
421      *
422      * @param birthString  生日字元串
423      * @param isNominalAge 是否按元旦算年齡,過了1月1日加一歲 true : 是 false : 否
424      * @return 返回年齡
425      */
426     public static Integer getAgeByBirthString(String birthString, boolean isNominalAge) {
427 
428         return getAgeByBirthString(birthString, "yyyy-MM-dd", isNominalAge);
429 
430     }
431 
432     /**
433      * 通過生日字元串獲取年齡
434      *
435      * @param birthString 生日字元串
436      * @param format      日期字元串格式,為空則默認"yyyy-MM-dd"
437      * @return 返回年齡
438      */
439     public static Integer getAgeByBirthString(String birthString, String format) {
440         return getAgeByBirthString(birthString, "yyyy-MM-dd", false);
441     }
442 
443 
444     /**
445      * 通過生日字元串獲取年齡
446      *
447      * @param birthString  生日字元串
448      * @param format       日期字元串格式,為空則默認"yyyy-MM-dd"
449      * @param isNominalAge 是否按元旦算年齡,過了1月1日加一歲 true : 是 false : 否
450      * @return 返回年齡
451      */
452     public static Integer getAgeByBirthString(String birthString, String format, boolean isNominalAge) {
453 
454         int age = 0;
455 
456         if (StringUtils.isEmpty(birthString)) {
457             return age;
458         }
459 
460         if (StringUtils.isEmpty(format)) {
461             format = "yyyy-MM-dd";
462         }
463 
464         try {
465 
466             Calendar birthday = Calendar.getInstance();
467             Calendar today = Calendar.getInstance();
468             SimpleDateFormat sdf = new SimpleDateFormat(format);
469             birthday.setTime(sdf.parse(birthString));
470             age = today.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
471             if (!isNominalAge) {
472                 if (today.get(Calendar.MONTH) < birthday.get(Calendar.MONTH) ||
473                         (today.get(Calendar.MONTH) == birthday.get(Calendar.MONTH) &&
474                                 today.get(Calendar.DAY_OF_MONTH) < birthday.get(Calendar.DAY_OF_MONTH))) {
475                     age = age - 1;
476                 }
477             }
478         } catch (ParseException e) {
479             e.printStackTrace();
480         }
481 
482         return age;
483 
484     }
485 
486     /**
487      * 手機號中間四位替換成星號
488      *
489      * @param mobile
490      * @return
491      */
492     public static String maskMobile(String mobile) {
493         if (validateMobile(mobile)) {
494             return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
495         }
496         return mobile;
497     }
498 
499     /**
500      * 手機號中間四位自定義替換
501      *
502      * @param mobile
503      * @param transCode 中間四位目標值 如GXJF 將136GXJF1111
504      * @return
505      */
506     public static String maskMobile(String mobile, String transCode) {
507         if (validateMobile(mobile)) {
508             transCode = StringUtils.isEmpty(transCode) ? "****" : transCode;
509             return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", String.format("$1%s$2", transCode));
510         }
511         return mobile;
512     }
513 
514     /**
515      * 郵箱地址加星號
516      *
517      * @param email
518      * @return
519      */
520     public static String maskEmail(String email) {
521         if (validateEmail(email)) {
522             String userName = email.substring(0, email.indexOf("@"));
523             int len = userName.length();
524             if (len >= 5) {
525                 int total = len - 3;
526                 int half = total / 2;
527                 int start = half;
528                 int end = len - half;
529                 if (total % 2 != 0) {
530                     end = end - 1;
531                 }
532                 StringBuilder sb = new StringBuilder(email);
533                 for (int i = start; i < end; i++) {
534                     sb.setCharAt(i, '*');
535                 }
536                 return sb.toString();
537             }
538         }
539         return email;
540     }
541 
542     /**
543      * 帳號中間四位自定義替換
544      *
545      * @param account
546      * @return
547      */
548     public static String maskTradeAccount(String account) {
549         return account.replaceAll("(\\d{7})\\d*(\\d{4})", "$1****$2");
550     }
551 
552 
553     /**
554      * 讀取jsonResult的value中的某個屬性值
555      *
556      * @param jsonResult
557      * @param attrName
558      * @return
559      */
560 
561     public static String readJSONResultValueAttr(JSONResult jsonResult, String attrName) {
562         String ret = "";
563         try {
564             ret = ((JSONObject) jsonResult.getValue()).get(attrName).toString();
565         } catch (Exception e) {
566             //e.printStackTrace();
567         }
568         return ret;
569     }
570 
571     /**
572      * 驗證是否為日期
573      *
574      * @param date
575      * @return
576      */
577     public static boolean validateDate(String date) {
578         boolean convertSuccess = true;
579         SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
580         try {
581             format.setLenient(false);
582             format.parse(date);
583         } catch (ParseException e) {
584             convertSuccess = false;
585         }
586         return convertSuccess;
587     }
588 
589     /**
590      * 獲取時間戳,作為遞增的ID
591      */
592     private static final Lock lock = new ReentrantLock();   //鎖對象
593 
594     public static long getUniqueLong() {
595         long l;
596         lock.lock();
597         try {
598             l = System.currentTimeMillis();
599         } finally {
600             lock.unlock();
601         }
602         return l;
603     }
604 
605     /**
606      * 解析出url參數中的鍵值對
607      * 如 "index.jsp?Action=del&id=123",解析出Action:del,id:123存入map中
608      *
609      * @param URL url地址
610      * @return url請求參數部分
611      */
612     public static String getUrlParams(String URL, String key) {
613         Map<String, String> mapRequest = new HashMap<String, String>();
614         String[] arrSplit = null;
615         String strUrlParam = null;
616         java.net.URL aURL = null;
617         try {
618             aURL = new URL(URL);
619             strUrlParam = aURL.getQuery();
620         } catch (MalformedURLException e) {
621             e.printStackTrace();
622         }
623         if (strUrlParam == null) {
624             return "";
625         }
626         arrSplit = strUrlParam.split("[&]");
627         for (String strSplit : arrSplit) {
628             String[] arrSplitEqual = null;
629             arrSplitEqual = strSplit.split("[=]");
630             if (arrSplitEqual.length > 1) {
631                 mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]);
632             } else {
633                 if (!StringUtils.isEmpty(arrSplitEqual[0])) {
634                     mapRequest.put(arrSplitEqual[0], "");
635                 }
636             }
637         }
638         if (mapRequest.containsKey(key)) {
639             try {
640                 return URLDecoder.decode(mapRequest.get(key), "UTF-8");
641             } catch (UnsupportedEncodingException e) {
642                 e.printStackTrace();
643             } catch (Exception e) {
644 
645             }
646         }
647         return "";
648     }
649 
650 
651 
652     /**
653      * 生成隨機密碼
654      *
655      * @param pwd_len 生成的密碼的總長度
656      * @return 密碼的字元串
657      */
658     public static String genRandomNum(int pwd_len) {
659         // 35是因為數組是從0開始的,26個字母+10個數字
660         final int maxNum = 36;
661         int i; // 生成的隨機數
662         int count = 0; // 生成的密碼的長度
663         char[] str = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
664                 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
665                 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
666         StringBuffer pwd = new StringBuffer("");
667         Random r = new Random();
668         while (count < pwd_len) {
669             // 生成隨機數,取絕對值,防止生成負數,
670             i = Math.abs(r.nextInt(maxNum)); // 生成的數最大為36-1
671             if (i >= 0 && i < str.length) {
672                 pwd.append(str[i]);
673                 count++;
674             }
675         }
676         return pwd.toString();
677     }
678 
679 
680 
681 }