package kr.wisestone.owl.util; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Lists; import com.google.gson.Gson; import kr.wisestone.owl.domain.enumType.FileType; import kr.wisestone.owl.type.LikeType; import kr.wisestone.owl.vo.DepartmentVo; import kr.wisestone.owl.vo.UserVo; import org.apache.commons.codec.binary.*; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.ss.usermodel.Cell; import org.jsoup.Jsoup; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.web.multipart.MultipartFile; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.HttpsURLConnection; import javax.servlet.http.HttpServletRequest; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.*; import java.math.BigInteger; import java.net.*; import java.nio.file.Files; import java.nio.file.Paths; import java.security.MessageDigest; import java.security.spec.KeySpec; import java.text.DecimalFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class CommonUtil { private static final Logger LOGGER = LoggerFactory.getLogger(CommonUtil.class); private static final String ENCODING_TYPE = "UTF-8"; private static final String SALT = "c7224df62de46817a515ce79b24d48d2"; // AES128 암호화에 사용 private static final String IV = "3c1bc71695361ca0aec4d83bb328b444"; // AES128 암호화에 사용 private static final String PASS_PHRASE = "1024"; // AES128 암호화에 사용 private static final int ITERATION_COUNT = 10000; // AES128 암호화에 사용 private static final int KEY_SIZE = 128; // AES128 암호화에 사용 private static final String TMP_UPLOAD_FOLDER = "/tmpUploadFolder/"; // 이슈 생성, 수정에서 파일 업로드할 때 임시 폴더로 사용 public static String getClinetIp() { try { for (Enumeration en = NetworkInterface .getNetworkInterfaces(); en.hasMoreElements(); ) { NetworkInterface intf = en.nextElement(); for (Enumeration enumIpAddr = intf .getInetAddresses(); enumIpAddr.hasMoreElements(); ) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress() && !inetAddress.isLinkLocalAddress() && inetAddress.isSiteLocalAddress()) { return inetAddress.getHostAddress().toString(); } } } } catch (SocketException ex) { } return null; } /** * 초기 패스워드를 생성하여 반환한다. * * @return */ public static String randomStringMaker() { String random = null; Integer length = 10; random = RandomStringUtils.random(length, true, true); return random; } public static String randomProjectKey() { String random = null; Integer length = 5; random = RandomStringUtils.random(length, true, true).toUpperCase(); return random; } // sha 512 암호화 public static String encryptionSha512(String plainText) { try { MessageDigest md = MessageDigest.getInstance("SHA-512"); byte[] messageDigest = md.digest(plainText.getBytes()); BigInteger no = new BigInteger(1, messageDigest); String hashText = no.toString(16); while (hashText.length() < 32) { hashText = "0" + hashText; } return hashText; } catch (Exception e) { LOGGER.debug("encryptionSha512 error : " + e.getMessage()); e.printStackTrace(); return null; } } public static String getServerIpAddress() { try { Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface networkInterface = interfaces.nextElement(); if (networkInterface.isLoopback() || !networkInterface.isUp() || networkInterface.isVirtual() || networkInterface.isPointToPoint()) { continue; } Enumeration addresses = networkInterface.getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress inetAddress = addresses.nextElement(); final String ip = inetAddress.getHostAddress(); if (Inet4Address.class == inetAddress.getClass()) { return ip; } } } } catch (SocketException e) { throw new RuntimeException(e); } return null; } public static String likeStr(Map contents, String attr, LikeType type) { if (contents == null) { return "%%"; } Object value = contents.get(attr); if (value == null) { return "%%"; } return likeStr(value.toString(), type); } /** * Query에서 사용되는 Like 문자열을 만든다. * * @param source * @param type * @return */ public static String likeStr(String source, LikeType type) { if (source == null) { return "%%"; } else { if (type == LikeType.FULL) { return "%" + source + "%"; } else if (type == LikeType.LEFT) { return "%" + source; } else if (type == LikeType.RIGHT) { return source + "%"; } } return source; } public static String nvl(Object obj) { if (obj == null) { return ""; } return obj.toString(); } public static String nvl(String message, String defaultStr) { if (message == null) { return defaultStr; } return message; } public static String getApprovalCode() { return UUID.randomUUID().toString(); } public static String getOnlyClassName(Object object) { String className = object.getClass().getName(); String[] tokens = className.split("\\."); int lastToken = tokens.length - 1; String onlyName = tokens[lastToken]; return onlyName; } /** * 연결 시스템의 xml 형식의 String 값을 파싱해서 url만 돌려준다. * * @param xml * @return url String */ public static String xmltoString(String checkElementName, String xml) { // TODO Auto-generated method stub DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = null; try { db = dbf.newDocumentBuilder(); } catch (ParserConfigurationException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } Document doc = null; NodeList nodes = null; InputSource is = new InputSource(); is.setCharacterStream(new StringReader(xml)); try { doc = db.parse(is); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } nodes = doc.getElementsByTagName(checkElementName); return nodes.item(0).getTextContent(); } public static long changeByteToMB(long size) { return size / 1024 / 1024; } public static String getServerIp() { try { InetAddress address = InetAddress.getLocalHost(); return address.getHostAddress(); } catch (UnknownHostException e) { e.printStackTrace(); } return null; } /** * 다국어 메시지를 반환한다. * * @return */ public static Map getMessages() { return getMessages(WebAppUtil.getHttpServletRequest().getServletContext().getRealPath("/")); } /** * 다국어 메시지를 반환한다. * * @param rootPath * @return */ public static Map getMessages(String rootPath) { Map messages = new HashMap(); String[] resources = new String[]{"messages.properties", "label.properties", "code.properties"}; for (String resource : resources) { String resourcePath = rootPath + "/WEB-INF/i18n/" + resource; LOGGER.debug("message path : resourcePath = " + resourcePath); Properties prop = new Properties(); try { prop.load(new FileInputStream(resourcePath)); Iterator iter = prop.keySet().iterator(); while (iter.hasNext()) { String key = iter.next().toString(); messages.put(key, prop.get(key).toString()); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return messages; } public static String getDiagramObjectFormattedLocation(String location) { if (location == null) { return null; } if (location.indexOf(".") != -1) { return location.substring(0, location.indexOf(".")); } else { return location; } } public static String replaceBrWithNewline(String text) { org.jsoup.nodes.Document document = Jsoup.parse(text); document.select("br").append("\\n"); document.select("p").prepend("\\n\\n"); return document.text().replace("\\n", "\n"); } // UUID 로 겹치지 않는 키를 만들어 낸다. public static String getFileNameByUUID(String originalFileName) { String fileName = UUID.randomUUID().toString(); String[] fileType = originalFileName.split("\\."); fileName += "." + fileType[(fileType.length - 1)]; return fileName; } // multipartFile 정보를 file Map 형태로 변경한다. public static Map makeFileMap(MultipartFile multipartFile) { Map fileMap = new HashMap<>(); try { fileMap.put("fileName", multipartFile.getOriginalFilename()); fileMap.put("fileSize", multipartFile.getSize()); fileMap.put("contentType", multipartFile.getContentType()); fileMap.put("file", CommonUtil.multipartToFile(multipartFile)); } catch (Exception e) { LOGGER.debug(e.getMessage()); } return fileMap; } // string file 정보를 file Map 형태로 변경한다. public static Map makeFileMap(String fileName, String file, String contentType) { Map fileMap = new HashMap<>(); try { byte[] bytes = Base64.decodeBase64(file); fileMap.put("fileName", fileName); fileMap.put("fileSize", bytes.length); fileMap.put("contentType", contentType); fileMap.put("file", CommonUtil.bytesToFile(fileName, bytes)); } catch (Exception e) { LOGGER.debug(e.getMessage()); } return fileMap; } public static String getPostDataString(Map params) throws UnsupportedEncodingException { StringBuilder result = new StringBuilder(); boolean first = true; for (Map.Entry entry : params.entrySet()) { if (first) { first = false; } else { result.append("&"); } result.append(URLEncoder.encode(entry.getKey(), "UTF-8")); result.append("="); result.append(URLEncoder.encode(entry.getValue(), "UTF-8")); } return result.toString(); } // multipart 파일을 File 로 변경 public static File multipartToFile(MultipartFile multipart) { File convertFile = new File(WebAppUtil.getContextRealPath() + TMP_UPLOAD_FOLDER + getFileNameByUUID(multipart.getOriginalFilename())); if (!convertFile.exists()) { convertFile.mkdirs(); } try { multipart.transferTo(convertFile); } catch (IllegalStateException | IOException e) { LOGGER.debug("multipart 파일 file 변환 오류"); } return convertFile; } // string을 파일로 변환 public static File stringToFile(String fileName, String file) { byte[] bytes = null; try { bytes = Base64.decodeBase64(file); } catch (Exception ex) { LOGGER.debug("string to bytes 변환 오류"); } if (bytes != null) { return bytesToFile(fileName, bytes); } return null; } // bytes를 파일로 변환 public static File bytesToFile(String fileName, byte[] bytes) { File convertFile = new File(WebAppUtil.getContextRealPath() + TMP_UPLOAD_FOLDER + getFileNameByUUID(fileName)); if (!convertFile.exists()) { convertFile.mkdirs(); } try{ FileOutputStream lFileOutputStream = new FileOutputStream(convertFile); lFileOutputStream.write(bytes); lFileOutputStream.close(); }catch (IllegalStateException | IOException e) { LOGGER.debug("bytes 파일 file 변환 오류"); } return convertFile; } public static InputStream getFileInputStream(String strPath, String strNewFileName){ InputStream objInputStream = null; String strTargetPath = WebAppUtil.getContextRealPath() + strPath + "/" + strNewFileName; File originFile = new File(strTargetPath); try { objInputStream = new FileInputStream(originFile); } catch (Exception e) { LOGGER.debug("get Inputstream Error : " + e.getMessage()); } return objInputStream; } public static boolean moveToSaveStorage(String strBasePath, String strNewFileName, File tempFile) { boolean bRet = false; String strTargetBasePath = WebAppUtil.getContextRealPath() + strBasePath; strTargetBasePath = Paths.get(strTargetBasePath).toString(); String strTargetPath = strTargetBasePath + "/" + strNewFileName; File directory = new File(strTargetBasePath); if (! directory.exists()){ try { directory.mkdirs(); } catch (Exception e) { LOGGER.debug("make directory error : " + e.getMessage()); } } bRet = tempFile.renameTo(new File(strTargetPath)); if( !bRet ) { LOGGER.debug("file 이동 오류"); LOGGER.debug("original file Path : " + tempFile.getPath()); LOGGER.debug("target file Path : " + strTargetPath); } return bRet; } public static boolean deleteToSaveStorage(String strBasePath, String strFileName) { boolean bRet = false; String strTargetBasePath = WebAppUtil.getContextRealPath() + strBasePath; String strTargetPath = strTargetBasePath + strFileName; File delFile = new File(strTargetBasePath); if ( delFile.exists()){ if(!delFile.isDirectory()) { bRet = delFile.delete(); } } if( !bRet ) { LOGGER.debug("file 삭제 오류"); LOGGER.debug("original file Path : " + strTargetPath); } return bRet; } // 파일 확장자 체크 // 1. 모든 확장자를 제한하고 허용하는 일부 확장자만 업로드 되도록 제한 // 2. 확장자는 뒤에서부터 체크한다. // 3. 특수문자 체크 public static boolean checkFileType(String originalFileName) { boolean permit = false; if (StringUtils.isEmpty(originalFileName)) { return permit; } String[] extFileTypes = {"hwp", "txt", "pptx", "ppt", "pdf", "xlsx", "xls", "docx", "doc", "jpg", "png", "gif", "jpeg", "tif", "bmp", "wmv", "avi", "mp4", "mkv", "mov", "zip"}; String fileName = originalFileName.toLowerCase(); int pos = fileName.lastIndexOf("."); String ext = fileName.substring(pos + 1); for (String extFileType : extFileTypes) { if (extFileType.equals(ext)) { permit = true; break; } } if (fileName.contains("%00") || fileName.contains("%zz") || fileName.contains(";")) { permit = false; } return permit; } // 파일 유형을 찾는다. public static FileType getFileType(String originalFileName) { FileType fileType; Map fileTypeMap = new HashMap<>(); fileTypeMap.put("hwp", FileType.DOC); fileTypeMap.put("txt", FileType.DOC); fileTypeMap.put("pptx", FileType.DOC); fileTypeMap.put("ppt", FileType.DOC); fileTypeMap.put("pdf", FileType.DOC); fileTypeMap.put("xlsx", FileType.DOC); fileTypeMap.put("xls", FileType.DOC); fileTypeMap.put("docx", FileType.DOC); fileTypeMap.put("doc", FileType.DOC); // 문서 끝 fileTypeMap.put("jpg", FileType.IMAGE); fileTypeMap.put("png", FileType.IMAGE); fileTypeMap.put("gif", FileType.IMAGE); fileTypeMap.put("jpeg", FileType.IMAGE); fileTypeMap.put("tif", FileType.IMAGE); fileTypeMap.put("bmp", FileType.IMAGE); // 이미지 끝 fileTypeMap.put("wmv", FileType.MEDIA); fileTypeMap.put("avi", FileType.MEDIA); fileTypeMap.put("mp4", FileType.MEDIA); fileTypeMap.put("mkv", FileType.MEDIA); fileTypeMap.put("mov", FileType.MEDIA); // 미디어 끝 String fileName = originalFileName.toLowerCase(); int pos = fileName.lastIndexOf("."); String ext = fileName.substring(pos + 1); if (fileTypeMap.get(ext) != null) { fileType = (FileType) fileTypeMap.get(ext); } else { fileType = FileType.ETC; } return fileType; } // 이름 마스킹 처리(성을 제외한 이름 마스킹 처리) public static String maskingName(String name) { String maskedName = ""; // 마스킹 이름 String firstName = ""; // 성 String lastName = ""; // 이름 int lastNameStartPoint; // 이름 시작 포인터 if (!StringUtils.isEmpty(name)) { if (name.length() > 1) { firstName = name.substring(0, 1); lastNameStartPoint = name.indexOf(firstName); lastName = name.substring(lastNameStartPoint + 1, name.length()); String makers = ""; for (int i = 0; i < lastName.length(); i++) { makers += "*"; } lastName = lastName.replace(lastName, makers); maskedName = firstName + lastName; } else { maskedName = "*"; } } return maskedName; } // AES 128 암호화 public static String encryptAES128(String plaintext) { if (StringUtils.isEmpty(plaintext)) { return null; } try { SecretKey key = generateKey(SALT, PASS_PHRASE, ITERATION_COUNT, KEY_SIZE); byte[] encrypted = doFinal(Cipher.ENCRYPT_MODE, key, IV, plaintext.getBytes("UTF-8")); return encodeBase64(encrypted); } catch (Exception e) { LOGGER.debug("encryptAES128 error : " + e.getMessage()); } return null; } private static String encodeBase64(byte[] bytes) { return org.apache.commons.codec.binary.Base64.encodeBase64String(bytes); } private static SecretKey generateKey(String salt, String passPhrase, int iterationCount, int keySize) throws Exception { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); KeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), decodeHex(salt), iterationCount, keySize); SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); return key; } private static byte[] doFinal(int encryptMode, SecretKey key, String iv, byte[] bytes) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(encryptMode, key, new IvParameterSpec(decodeHex(iv))); return cipher.doFinal(bytes); } private static byte[] decodeHex(String str) throws Exception { return Hex.decodeHex(str.toCharArray()); } // AES 128 복호화 public static String decryptAES128(String text) { try { SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); KeySpec spec = new PBEKeySpec(PASS_PHRASE.toCharArray(), Hex.decodeHex(SALT.toCharArray()), ITERATION_COUNT, KEY_SIZE); SecretKey key = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(Hex.decodeHex(IV.toCharArray()))); byte[] decrypted = cipher.doFinal(Base64.decodeBase64(text)); return new String(decrypted, ENCODING_TYPE); } catch (Exception e) { LOGGER.debug("decryptAES128 error : " + e.getMessage()); } return null; } // AES 256 암호화 /*public static String encryptAES256(String msg, String key) throws Exception { SecureRandom random = new SecureRandom(); byte bytes[] = new byte[20]; random.nextBytes(bytes); byte[] saltBytes = bytes; // Password-Based Key Derivation function 2 SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); // 70000번 해시하여 256 bit 길이의 키를 만든다. PBEKeySpec spec = new PBEKeySpec(key.toCharArray(), saltBytes, 70000, 256); SecretKey secretKey = factory.generateSecret(spec); SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); // 알고리즘/모드/패딩 // CBC : Cipher Block Chaining Mode Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secret); AlgorithmParameters params = cipher.getParameters(); // Initial Vector(1단계 암호화 블록용) byte[] ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV(); byte[] encryptedTextBytes = cipher.doFinal(msg.getBytes("UTF-8")); byte[] buffer = new byte[saltBytes.length + ivBytes.length + encryptedTextBytes.length]; System.arraycopy(saltBytes, 0, buffer, 0, saltBytes.length); System.arraycopy(ivBytes, 0, buffer, saltBytes.length, ivBytes.length); System.arraycopy(encryptedTextBytes, 0, buffer, saltBytes.length + ivBytes.length, encryptedTextBytes.length); return Base64.getEncoder().encodeToString(buffer); } // AES 256 복호화 public static String decryptAES256(String msg, String key) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); ByteBuffer buffer = ByteBuffer.wrap(Base64.getDecoder().decode(msg)); byte[] saltBytes = new byte[20]; buffer.get(saltBytes, 0, saltBytes.length); byte[] ivBytes = new byte[cipher.getBlockSize()]; buffer.get(ivBytes, 0, ivBytes.length); byte[] encryoptedTextBytes = new byte[buffer.capacity() - saltBytes.length - ivBytes.length]; buffer.get(encryoptedTextBytes); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); PBEKeySpec spec = new PBEKeySpec(key.toCharArray(), saltBytes, 70000, 256); SecretKey secretKey = factory.generateSecret(spec); SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes)); byte[] decryptedTextBytes = cipher.doFinal(encryoptedTextBytes); return new String(decryptedTextBytes); }*/ // 엑셀 다운로드에 필요한 검색 조건 정보를 추출한다. public static Map getSearchConditions(HttpServletRequest request) throws IOException { Map conditions = new HashMap<>(); Map params = new HashMap<>(); Enumeration enumeration = request.getParameterNames(); while (enumeration.hasMoreElements()) { String name = (String) enumeration.nextElement(); if (!org.springframework.util.StringUtils.isEmpty(request.getParameter(name))) { params.put(name, request.getParameter(name)); } } if (!StringUtils.isEmpty(MapUtil.getString(params, "conditions"))) { ObjectMapper mapper = new ObjectMapper(); conditions = mapper.readValue(MapUtil.getString(params, "conditions"), new TypeReference>() { }); } return conditions; } // UserVos 에서 사용자 정보를 추출해서 문자열로 리턴해준다. - 주로 엑셀 download 에서 사용된다. public static String convertUserVosToString(List userVos) { StringBuilder stringBuilder = new StringBuilder(); int count = 0; for (UserVo userVo : userVos) { if (count > 0) { stringBuilder.append("\n"); } stringBuilder.append(userVo.getName()); stringBuilder.append("("); stringBuilder.append(userVo.getAccount()); stringBuilder.append(")"); count++; } return stringBuilder.toString(); } // DepartmentVos 에서 부서 정보를 추출해서 문자열로 리턴해준다. - 주로 엑셀 download 에서 사용된다. public static String convertDepartmentVosToString(List departmentVos) { StringBuilder stringBuilder = new StringBuilder(); int count = 0; for (DepartmentVo departmentVo : departmentVos) { if (count > 0) { stringBuilder.append("\n"); } stringBuilder.append(departmentVo.getDepartmentName()); count++; } return stringBuilder.toString(); } public static List findSearchPeriod(Date startDate, Date endDate) { Calendar cal = Calendar.getInstance(); cal.setTime(endDate); List days = Lists.newArrayList(); // 이번달 날짜 리스트 가져오기 while (cal.getTime().after(startDate)){ days.add(cal.getTime()); cal.add(Calendar.DATE, -1); } return days; } // 검색 일자를 구한다. public static List findSearchPeriod(String searchPeriod) { List searchDates = Lists.newArrayList(); switch (searchPeriod) { case DateUtil.THIS_WEEK: searchDates = DateUtil.getSearchDays(DateUtil.THIS_WEEK); break; case DateUtil.LAST_WEEK: searchDates = DateUtil.getSearchDays(DateUtil.LAST_WEEK); break; case DateUtil.LAST_SEVEN_DAYS: searchDates = DateUtil.getSearchDays(DateUtil.LAST_SEVEN_DAYS); break; case DateUtil.THIS_MONTH: searchDates = DateUtil.getSearchDays(DateUtil.THIS_MONTH); break; case DateUtil.LAST_MONTH: searchDates = DateUtil.getSearchDays(DateUtil.LAST_MONTH); break; case DateUtil.LAST_THIRTY_DAYS: searchDates = DateUtil.getSearchDays(DateUtil.LAST_THIRTY_DAYS); break; } return searchDates; } // 클라이언트의 브라우저 정보를 찾는다. public static String getBrowser(HttpServletRequest request) { String header = request.getHeader("User-Agent"); if (header.contains("MSIE") || header.contains("Trident")) { return "MSIE"; } else if (header.indexOf("Chrome") > -1) { return "Chrome"; } else if (header.indexOf("Opera") > -1) { return "Opera"; } return "Firefox"; } // 브라우저 별로 파일 공백을 처리한다. public static String getDisposition(String filename, String browser) throws Exception { String encodedFilename = null; switch (browser) { case "MSIE": case "Trident": encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20"); break; case "Firefox": encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\""; break; case "Opera": encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\""; break; case "Chrome": StringBuilder sb = new StringBuilder(); for (int i = 0; i < filename.length(); i++) { char c = filename.charAt(i); if (c > '~') { sb.append(URLEncoder.encode("" + c, "UTF-8")); } else { sb.append(c); } } encodedFilename = sb.toString(); break; } return encodedFilename; } // XSS 공격을 막기 위해 스크립트 태그를 없앤다. - 이슈 생성, 수정, 상세에서 태그를 살려야 하기 때문에 스크립트만 막는다. public static String preventXss(String dirty) { dirty = dirty.replaceAll(" searchChangeList(List targetIds, List searchIds) { List results = Lists.newArrayList(); for (Long searchId : searchIds) { boolean exist = false; for (Long targetId : targetIds) { if (searchId.equals(targetId)) { exist = true; break; } } if (!exist) { results.add(searchId); } } return results; } // 메일을 받는 사용자가 사용하고 있는 언어 정보를 가져온다. public static Locale getUserLanguage(String language) { Locale locale; switch (language) { case "ko": locale = new Locale("ko", "KR"); break; case "en": locale = new Locale("en", "US"); break; case "ja": locale = new Locale("ja", "JP"); break; case "vi": locale = new Locale("vi", "VN"); break; default: locale = new Locale("ko", "KR"); } return locale; } // 숫자에 3자리 마다 , 를 찍어준다 public static String getDecimalFormat(Object object) { DecimalFormat decimalFormat = new DecimalFormat("###,###"); return decimalFormat.format(object); } // 엑셀 import 데이터에서 cell 값을 문자열로 변환한다. public static String convertExcelStringToCell(Cell cell) { String cellValue = ""; switch (cell.getCellType()) { case Cell.CELL_TYPE_NUMERIC : // 날짜 형식인 경우 날짜로 변환 if (HSSFDateUtil.isCellDateFormatted(cell)) { Date date = cell.getDateCellValue(); cellValue = DateUtil.convertDateToStr(date, "yyyy-MM-dd HH:mm:ss"); } else { double doubleValue = cell.getNumericCellValue(); int intValue; if (doubleValue % 1 == 0) { intValue = (int)doubleValue; cellValue = intValue + ""; } else { cellValue = doubleValue + ""; } } break; case Cell.CELL_TYPE_STRING : cellValue = cell.getStringCellValue(); break; case Cell.CELL_TYPE_FORMULA : cellValue = cell.getCellFormula() + ""; break; case Cell.CELL_TYPE_BOOLEAN : cellValue = cell.getBooleanCellValue() + ""; break; } return cellValue; } // 웹 소켓 메세지 발송 public static void sendWebSocketMessage(SimpMessagingTemplate simpMessagingTemplate, Map messageMap) { String url = MapUtil.getString(messageMap, "url"); String content = MapUtil.getString(messageMap, "message"); String account = MapUtil.getString(messageMap, "account"); if (StringUtils.isEmpty(url) || StringUtils.isEmpty(content)) { LOGGER.error("Fail WebSocket Message - url or content empty"); return; } if (!StringUtils.isEmpty(account)) { simpMessagingTemplate.convertAndSendToUser(account, url, content); } else { simpMessagingTemplate.convertAndSend(url, content); } } // 메인 url만 추출 public static String extractUrl(String content){ try { String REGEX = "(http(s)?:\\/\\/)([a-z0-9\\w]+\\.*)+[a-z0-9]{2,4}"; Pattern p = Pattern.compile(REGEX, Pattern.CASE_INSENSITIVE); Matcher m = p.matcher(content); if (m.find()) { return m.group(); } return ""; } catch (Exception e) { return ""; } } // 메인 url 추출을 위해 http: 확인 public static String getUrl(String fullUrl) { if (fullUrl != null) { if (fullUrl.indexOf("http") == -1) { fullUrl = "http://" + fullUrl; } return extractUrl(fullUrl); } return ""; } }