package geoinfo.util; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.net.URLDecoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.sql.SQLException; import java.sql.Timestamp; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.*; import javax.servlet.http.HttpServletRequest; import org.apache.commons.httpclient.NameValuePair; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; public final class MyUtil { private static final Logger logger = LoggerFactory.getLogger(MyUtil.class); public static final String VERSION = "20240816_1430"; private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss"); // 주석 다는 기준: https://www.oracle.com/technetwork/java/javase/tech/index-137868.html /** * 특정 자리수의 랜덤 숫자를 생성한다. * @param nLength 랜덤문자의 길이 * @return 생성된 랜덤 문자 */ public static String getRandomNumber(int nLength) { Random generator = new Random(); String strRandValue = ""; for (int i = 0; i < nLength; i++) { strRandValue += Integer.toString( generator.nextInt(10) ); } return strRandValue; } /** * 현재 Timestamp를 반환한다 * @return 현재 Timestamp yyyy-MM-dd hh:mm:ss */ public static String getCurrentDateTime() { Timestamp timestamp = new Timestamp(System.currentTimeMillis()); System.out.println(timestamp); return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(timestamp); } /** * 현재 date를 반환한다 * @return 현재 Timestamp yyyy-MM-dd */ public static String getCurrentDate() { Timestamp timestamp = new Timestamp(System.currentTimeMillis()); System.out.println(timestamp); return new SimpleDateFormat("yyyy-MM-dd").format(timestamp); } /** * 현재 시각 구하기 * @return 현재 Timestamp hh:mm:ss */ public static String getCurrentTime() { Timestamp timestamp = new Timestamp(System.currentTimeMillis()); System.out.println(timestamp); return new SimpleDateFormat("hh:mm:ss").format(timestamp); } /** * 년 월 일 날짜 더하기 * * @param dt(날짜) , y(년) , m(월), d(일) * @Exam addDate("2018-09-10",1,12,1) -->20200911 addDate("2018-09-10",1,-2,1) -->20200711 * @return String */ public static String addDate(String dt, int y, int m, int d) throws Exception { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Calendar cal = Calendar.getInstance(); Date date = format.parse(dt); cal.setTime(date); cal.add(Calendar.YEAR, y); //년 더하기 cal.add(Calendar.MONTH, m); //월 더하기 cal.add(Calendar.DATE, d); //일 더하기 return format.format(cal.getTime()); } /** * 일 구하기 * * @param dt(날짜) * @Exam addDate("2018-09-10",1,12,1) -->20200911 addDate("2018-09-10",1,-2,1) -->20200711 * @return int */ public static int getDate(String dt) throws Exception { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Calendar cal = Calendar.getInstance(); Date date = format.parse(dt); cal.setTime(date); logger.info("getDate:" + cal.get(cal.DATE)); return cal.get(cal.DATE); } /** * UPDATE 문에서 문자열 타입의 필드를 추가한다. * * @param strQuery 쿼리, strColumnName 컬럼명, strTarget * @Exam addUpdateString("UPDATE SET ", "name", "홍길동") --> UPDATE SET name='홍길동', * @return String */ public static String addUpdateString(String strQuery, String strColumnName, String strValue ) { if( strValue != null && strValue.isEmpty() == false && strValue.equals("undefined") == false && strValue.equals("null") == false ) { strQuery += strColumnName + "='" + strValue + "',"; } return strQuery; } /** * UPDATE 문에서 Long 타입의 필드를 추가한다. * * @param strQuery 쿼리, strColumnName 컬럼명, longTarget * @Exam addUpdateString("UPDATE SET ", "age", 2l) --> UPDATE SET age=2, * @return String */ public static String addUpdateLong(String strQuery, String strColumnName, Long longTarget ) { if( longTarget != null ) { strQuery += strColumnName + "=" + longTarget + ","; } return strQuery; } /* public static boolean isJSONValid(String test) { try { new JSONObject(test); } catch (JSONException ex) { // edited, to include @Arthur's comment // e.g. in case JSONArray is valid as well... try { new JSONArray(test); } catch (JSONException ex1) { return false; } } return true; } */ public static String getQuery(List params) throws UnsupportedEncodingException { StringBuilder result = new StringBuilder(); boolean first = true; for (NameValuePair pair : params) { if (first) first = false; else result.append("&"); //result.append(URLEncoder.encode(pair.getName(), "UTF-8")); result.append(pair.getName()); result.append("="); result.append(pair.getValue()); //result.append(URLEncoder.encode(pair.getValue(), "UTF-8")); } return result.toString(); } /** * SHA-256으로 해싱하는 메소드 * @param msg * @return * @throws NoSuchAlgorithmException */ public static String sha256(String msg) throws NoSuchAlgorithmException { MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(msg.getBytes()); return bytesToHex(md.digest()); } /** * 바이트를 헥스값으로 변환한다 * * @param bytes * @return */ public static String bytesToHex(byte[] bytes) { StringBuilder builder = new StringBuilder(); for (byte b: bytes) { builder.append(String.format("%02x", b)); } return builder.toString(); } /** * 세틀뱅크 수취인 조회 서비스 HTML문서에서 특정 값 추출하기 * @param html_line * @param inputName * @return */ public static String parseInpuValueForSettleBankResponse(String html_line, String inputName) { String[] strArrValue = html_line.split("name=\"" + inputName + "\" value="); String strValue = ""; if( strArrValue.length == 2 ) { strValue = strArrValue[1].replaceAll("[\"|>|\\r\\n|\\n\\r|\\r|\\n|\\s|\\+)]",""); try { //logger.info("Encoding EUC-KR:" + URLDecoder.decode(strValue, "EUC-KR")); //logger.info("Encoding UTF-8:" + URLDecoder.decode(strValue, "UTF-8")); strValue = URLDecoder.decode(strValue, "UTF-8"); } catch (UnsupportedEncodingException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } } return strValue; } /** * 숫자 외 소수점을 포함한 모든 특수문자를 제거해준다. * */ public static String removeSpecialChractersNumber( String decimalNumber ) { decimalNumber = decimalNumber.replaceAll("[^0-9]", ""); //숫자 외 모두 제거한다. return decimalNumber; } /** * 수수점을 제외한 나머지 특수문자를 제거해준다. 그리고 소수점은 1개만 들어가도록 해준다. * */ public static String removeSpecialChractersDecimalNumber( String decimalNumber ) { decimalNumber = decimalNumber.replaceAll("[^0-9.\\-]", ""); //숫자와 쩜.-말고는 제거한다. // 소수점 1개만 넣도록 하기 int nDotIdx = decimalNumber.indexOf("."); if( nDotIdx > -1 ) { String[] arrSplit = decimalNumber.split("\\."); if( arrSplit.length != 0) { decimalNumber = ""; } for( int i = 0; i < arrSplit.length ; i++ ) { decimalNumber += arrSplit[i]; if( i == 0 ) { decimalNumber += "."; } } } logger.info("removeSpecialChractersDecimalNumber() decimalNumber:" + decimalNumber); return decimalNumber; } /** * 소수점자리수가 3자리 이상이면 2자리까지만 남기고 나머지는 지운다. * @param decimalNumber 소수점 자리 n개 이상 인 경우, 지울 숫자가 들어있는 문자열 * @param nLimitDecimalNumber 허용할 소수점 자 * @return */ public static String removeOverDecimalNumber( String decimalNumber, int nLimitDecimalNumber ) { logger.error("decimalNumber:" + decimalNumber); int nDotIdx = decimalNumber.indexOf("."); if( nDotIdx > -1 ) { String[] arrSplit = decimalNumber.split("\\."); if( arrSplit[1].length() > nLimitDecimalNumber ) { return arrSplit[0] + "." + arrSplit[1].substring(0,2); } } logger.error("decimalNumber:" + decimalNumber); return decimalNumber; } /** * 1,000 단위마다 콤마를 찍는다. * @param bdAmount * @return */ public static String addComma(BigDecimal bdAmount) { return addComma(bdAmount.toPlainString()); } /** * 1,000 단위마다 콤마를 찍는다. * @param doubleAmount * @return */ public static String addComma(Double doubleAmount) { return addComma(BigDecimal.valueOf(doubleAmount)); } /** * 1,000 단위마다 콤마를 찍는다. * @param longAmount * @return */ public static String addComma(Long longAmount) { return addComma(BigDecimal.valueOf(longAmount)); } /** * 1,000 단위마다 콤마를 찍는다. * @param strAmount * @return */ public static String addComma(String strAmount) { DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US); DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols(); if( isNumeric(strAmount) == false ) { return strAmount; } int nDotIndex = strAmount.indexOf("."); symbols.setGroupingSeparator(','); formatter.setDecimalFormatSymbols(symbols); if( nDotIndex > -1 ) { return formatter.format(Double.parseDouble( strAmount )); } else { return formatter.format(Long.parseLong( strAmount )); } } /** * 숫자에서 끝에 0000을 제거한다. * */ public static String trimTrailingZero( String decimalNumber ) { decimalNumber = decimalNumber.replaceAll("[^0-9.\\-]", ""); //숫자와 쩜.-말고는 제거한다. decimalNumber = decimalNumber.indexOf(".") < 0 ? decimalNumber : decimalNumber.replaceAll("0*$", "").replaceAll("\\.$", ""); logger.info("trimTrailingZero() decimalNumber:" + decimalNumber); return decimalNumber; } /** * SQL 인젝션 방어를 위해 특수문자를 제거한다. * @param myString * @return */ public static String removeSQLInjectionSpecialCharacter(String myString) { if( myString == null ) { return myString; } myString = myString.replaceAll( "<|>|\\(|\\)|'|\"|\\|;|=|\\+|\\||&|#|\\.\\.", " "); return myString; } /** * UUID(GUID)를 얻는다. * @return 구한 UUID(GUID) 값. */ public static String getUuid() { String uuid = UUID.randomUUID().toString(); return uuid; } /** 숫자인지 아닌지 확인한다. */ public static boolean isNumeric(String strNum) { if (strNum == null) { return false; } try { double d = Double.parseDouble(strNum); } catch (NumberFormatException nfe) { return false; } return true; } public static boolean isNumeric(Double num) { if (num == null) { return false; } return isNumeric(num.toString()); } public static boolean isNumeric(Integer num) { if (num == null) { return false; } return isNumeric(num.toString()); } public static boolean isNumeric(Long num) { if (num == null) { return false; } return isNumeric(num.toString()); } /** Long형태의 숫자인지 아닌지 확인한다. */ public static boolean isNumericForLong(String strNum) { if (strNum == null) { return false; } try { Long lValue = Long.parseLong(strNum); } catch (NumberFormatException nfe) { return false; } return true; } public static Integer getIntegerFromObject(Object obj) { if (obj instanceof Integer ) { return (Integer) obj; } else if (obj instanceof String ) { return Integer.parseInt((String) obj); } else if (obj instanceof Long) { return ((Long) obj).intValue(); } else if (obj instanceof Double) { return ((Long)Math.round((Double)obj)).intValue(); } return null; } public static Long getLongFromObject(Object obj) { if (obj instanceof String ) { String strObj = (String) obj; if( isNumeric(strObj) ) { return Long.parseLong((String) obj); } } else if (obj instanceof Integer) { return ((Integer) obj).longValue(); } else if (obj instanceof Long) { return (Long) obj; } else if (obj instanceof Double) { return ((Long)Math.round((Double)obj)); } return null; } public static Double getDoubleFromObject(Object obj) throws Exception { String str = getStringFromObject(obj); str = removeSpecialChractersDecimalNumber(str); return Double.parseDouble((String) str); } public static BigDecimal getBigDecimalFromObject(Object obj) throws Exception { return BigDecimal.valueOf(getDoubleFromObject(obj)); } public static String getStringFromObject(Object obj) throws Exception { if (obj == null) { return null; } else if (obj instanceof String ) { return (String) obj; } else if (obj instanceof Integer) { return ((Integer)obj).toString(); } else if (obj instanceof Long) { return ((Long) obj).toString(); } else if (obj instanceof Float) { return ((Float)obj).toString(); } else if (obj instanceof Double) { return ((Double)obj).toString(); } else if (obj instanceof BigDecimal) { return ((BigDecimal)obj).toPlainString(); } else if (obj instanceof Date) { return ((Date)obj).toString(); } return null; } public static org.json.simple.JSONObject getJSONObjectFromObject(Object obj) { if (obj instanceof org.json.simple.JSONObject ) { return (org.json.simple.JSONObject) obj; } else if (obj instanceof String ) { JSONParser parser = new JSONParser(); try { obj = parser.parse( (String) obj ); } catch (ParseException e) { e.printStackTrace(); } return (org.json.simple.JSONObject) obj; } return null; } public static org.json.simple.JSONArray getJSONArrayFromObject(Object obj) { if (obj instanceof org.json.simple.JSONArray ) { return (org.json.simple.JSONArray) obj; } else if (obj instanceof String ) { JSONParser parser = new JSONParser(); try { obj = parser.parse( (String) obj ); } catch (ParseException e) { e.printStackTrace(); } return (org.json.simple.JSONArray) obj; } return null; } public static Boolean getBooleanFromObject(Object obj) { if (obj instanceof String ) { return Boolean.parseBoolean( ((String)obj).trim() ); } else if (obj instanceof Boolean) { return (Boolean)obj; } return null; } /** * Parse a URI String into Name-Value Collection * 쿼리스트링을 분석해서 Map형태로 return해준다. * @param query * @return query string name-value Map. * @throws UnsupportedEncodingException */ public static Map splitQuery(String query, String token) throws UnsupportedEncodingException { Map query_pairs = new LinkedHashMap(); String[] pairs = query.split(token); for (String pair : pairs) { int idx = pair.indexOf("="); query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8")); } return query_pairs; } public static SortedMap getParameterMap(HttpServletRequest request) { SortedMap sMap = Collections.synchronizedSortedMap ( new TreeMap(request.getParameterMap())); String params = "\n--------------------------------------------------------------\n" + MyUtil.getBASEURL(request) + request.getRequestURI() + " IN:" + "\n--------------------------------------------------------------\n"; synchronized(sMap) { for(String key : sMap.keySet()) { String[] value = sMap.get(key); for(int i=0; i sMap = Collections.synchronizedSortedMap ( new TreeMap(request.getParameterMap())); String params = "\n--------------------------------------------------------------\n" + MyUtil.getBASEURL(request) + request.getRequestURI() + " IN:" + "\n--------------------------------------------------------------\n"; synchronized(sMap) { for(String key : sMap.keySet()) { String[] value = sMap.get(key); for(int i=0; i 1.23 * @return * @throws Exception */ public static Double floor(String strAmount, int decimalPlace) throws Exception { Double dPoint = Double.parseDouble(strAmount); String[] arrSplitedDot = strAmount.split("\\."); int nLength = arrSplitedDot.length; if (arrSplitedDot.length == 2) { if (MyUtil.isNumeric(arrSplitedDot[1])) { //소수부 끝에 0을 제거해준다. arrSplitedDot[1] = arrSplitedDot[1].replaceAll("0+$", ""); int nDecimalLength = arrSplitedDot[1].length(); if( nDecimalLength >= decimalPlace ) { String strDecimal = "1"; for (int i = 0; i < decimalPlace; i++) { strDecimal += "0"; } dPoint = Math.floor(dPoint*Long.valueOf(strDecimal)) / Long.valueOf(strDecimal); } } } return dPoint; } /** * days안에는 "월" 또는 "월,수,금" 이런 요일에 대한 한글문자가 들어가고 오늘이 주어진 요일 안에 포함되는지 여부를 알아낸다. * * @param days "월" 또는 "월,수,금'과 같이 요일이 한글로 들어있다. * @return 만약 days에 "월"이 들어가 있고 오늘이 월요일이라면 true를 return한다. */ public static Boolean isContainDayOfWeekToday( String days ) { // 1. Date 생성 / 현재 날짜 Date currentDate = new Date(); System.out.println(currentDate); // 2. Calendar 생성 Calendar calendar = Calendar.getInstance(); calendar.setTime(currentDate); // 3. 텍스트 요일 구하기 (숫자) int dayOfWeekNumber = calendar.get(Calendar.DAY_OF_WEEK); if( dayOfWeekNumber == 1 ) { if( days.indexOf("일") > -1 ) { return true; } } else if( dayOfWeekNumber == 2 ) { if( days.indexOf("월") > -1 ) { return true; } } else if( dayOfWeekNumber == 3 ) { if( days.indexOf("화") > -1 ) { return true; } } else if( dayOfWeekNumber == 4 ) { if( days.indexOf("수") > -1 ) { return true; } } else if( dayOfWeekNumber == 5 ) { if( days.indexOf("목") > -1 ) { return true; } } else if( dayOfWeekNumber == 6 ) { if( days.indexOf("금") > -1 ) { return true; } } else if( dayOfWeekNumber == 7 ) { if( days.indexOf("토") > -1 ) { return true; } } return false; } /** * 현재 시각이 timeRange에 명시한 시간대 안에 포함되는지 여부를 return 한다. * @param timeRange 01~14 -> 오전 1시부터 오후 2시를 의미하며 ~ 구분자를 사용한다. * @return 현재 시각이 해당 시간대 내에 포함되면 true를 return 한다. * @throws Exception timeRange이 형식에 맞지 않으면 Exception이 발생한다. */ public static Boolean isInTimeRange( String timeRange ) throws Exception { String[] arrTimeRange = timeRange.split("~"); if( arrTimeRange.length != 2 ) { throw new Exception("timeRange이 형식에 맞지 않습니다."); } if( MyUtil.isNumeric(arrTimeRange[0]) == false ) { throw new Exception("timeRange이 형식에 맞지 않습니다 - 1"); } if( MyUtil.isNumeric(arrTimeRange[1]) == false ) { throw new Exception("timeRange이 형식에 맞지 않습니다 - 1"); } Date currentDate = new Date(); // 포맷팅 정의 SimpleDateFormat formatter = new SimpleDateFormat("HH"); // 포맷팅 적용 String formatedNow = formatter.format(currentDate); Integer currentHour = MyUtil.getIntegerFromObject( formatedNow ); Integer rangeStart = MyUtil.getIntegerFromObject( arrTimeRange[0] ); Integer rangeEnd = MyUtil.getIntegerFromObject( arrTimeRange[0] ); if( rangeStart <= rangeEnd && rangeEnd <= rangeEnd ) { return true; } return false; } /** * Oracle 11g의 CLOB값을 String 값으로 변환한다. * @param clob * @return * @throws SQLException */ public static String ClobToString(java.sql.Clob clob) throws SQLException { String clobData = ""; if (clob != null) { java.io.Reader reader = clob.getCharacterStream(); java.io.BufferedReader br = new java.io.BufferedReader(reader); StringBuilder sb = new StringBuilder(); String line; try { while ((line = br.readLine()) != null) { sb.append(line); sb.append("\n"); // 필요에 따라 줄바꿈 추가 } clobData = sb.toString(); } catch (java.io.IOException e) { e.printStackTrace(); // 오류 처리 } finally { try { br.close(); reader.close(); } catch (java.io.IOException e) { e.printStackTrace(); } } } return clobData; } // JSONObject를 HashMap으로 변환 public static HashMap JSONObjectToHashMap( JSONObject jsonObject ) { HashMap params = new HashMap<>(); for (Object key : jsonObject.keySet()) { String keyStr = (String) key; Object value = jsonObject.get(keyStr); params.put(keyStr, value); } return params; } }