commons-configuration
commons-configuration
diff --git a/mens-core/src/main/java/kr/xit/biz/ens/model/cmm/CmmEnsRequestDTO.java b/mens-core/src/main/java/kr/xit/biz/ens/model/cmm/CmmEnsRequestDTO.java
index c96e9a7..b797e82 100644
--- a/mens-core/src/main/java/kr/xit/biz/ens/model/cmm/CmmEnsRequestDTO.java
+++ b/mens-core/src/main/java/kr/xit/biz/ens/model/cmm/CmmEnsRequestDTO.java
@@ -1,5 +1,7 @@
package kr.xit.biz.ens.model.cmm;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
@@ -9,7 +11,6 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
-import org.hibernate.validator.constraints.NotEmpty;
/**
*
@@ -30,14 +31,14 @@ import org.hibernate.validator.constraints.NotEmpty;
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
+@JsonInclude(Include.NON_ABSENT)
public class CmmEnsRequestDTO implements Serializable {
/**
* 시군구 코드
*/
@Schema(requiredMode = RequiredMode.REQUIRED, title = "시군구코드", example = "88328")
- @NotEmpty(message = "시군구 코드는 필수 입니다")
- @Size(max = 10)
+ @Size(min = 1, max = 10, message = "시군구 코드는 필수 입니다")
@JsonProperty("signguCode")
private String signguCode;
@@ -45,8 +46,7 @@ public class CmmEnsRequestDTO implements Serializable {
* 과태료 코드
*/
@Schema(requiredMode = RequiredMode.REQUIRED, title = "과태료코드", example = "11")
- @NotEmpty(message = "과태료 코드는 필수 입니다")
- @Size(max = 2)
+ @Size(min = 1, max = 2, message = "과태료 코드는 필수 입니다")
@JsonProperty("ffnlgCode")
- private final String ffnlgCode = "11";
+ private String ffnlgCode = "11";
}
diff --git a/mens-core/src/main/java/kr/xit/biz/ens/model/pplus/PplusDTO.java b/mens-core/src/main/java/kr/xit/biz/ens/model/pplus/PplusDTO.java
index 2f04a7e..5d37b2a 100644
--- a/mens-core/src/main/java/kr/xit/biz/ens/model/pplus/PplusDTO.java
+++ b/mens-core/src/main/java/kr/xit/biz/ens/model/pplus/PplusDTO.java
@@ -1,9 +1,9 @@
package kr.xit.biz.ens.model.pplus;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema.RequiredMode;
-import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.Size;
import kr.xit.biz.ens.model.cmm.CmmEnsRequestDTO;
@@ -69,10 +69,9 @@ public class PplusDTO {
* 우편 제작 요청 발신/수신 data file, 첨부파일의 경우 필수 값 아님
*
*/
- //@JsonIgnore
+ @JsonIgnore
@Schema(requiredMode = RequiredMode.AUTO, title = "첨부파일", example = " ")
- @NotEmpty(message = "첨부파일은 필수 입니다")
- private MultipartFile[] pstFile;
+ private MultipartFile pstFile;
}
/**
@@ -82,20 +81,38 @@ public class PplusDTO {
* Response: PpCommonResponse
*
*/
- @Schema(name = "PpAcceptRequest2", description = "Postplus 우편제작 접수 요청 DTO")
+ @Schema(name = "PpAcceptRequestStruct", description = "Postplus 우편제작 접수 요청 구조 DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@JsonInclude(JsonInclude.Include.NON_NULL)
- public static class PpAcceptRequest2 extends CmmEnsRequestDTO {
+ public static class PpAcceptRequestStruct extends CmmEnsRequestDTO {
@Schema(requiredMode = RequiredMode.REQUIRED)
@Valid
- private ReqMstData master;
+ private PpAcceptReqDataStruct master;
@Schema(requiredMode = RequiredMode.REQUIRED)
@Valid
- private ReqDtlData detail;
+ private PpAcceptReqDataStruct detail;
+ }
+
+ /**
+ *
+ * Postplus 우편제작 접수 요청 Data 구조 DTO
+ *
+ */
+ @Schema(name = "PpAcceptReqDataStruct", description = "Postplus 우편제작 접수 요청 Data 구조 DTO")
+ @Data
+ @NoArgsConstructor
+ @AllArgsConstructor
+ @SuperBuilder
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ public static class PpAcceptReqDataStruct {
+ @NotBlank
+ private String cols;
+ @NotBlank
+ private String rows;
}
/**
@@ -136,51 +153,13 @@ public class PplusDTO {
* Postplus 우편제작 접수 요청 Data Master DTO
*
*/
- @Schema(name = "ReqMstData", description = "Postplus 우편제작 접수 요청 Data Master DTO")
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- @SuperBuilder
- @JsonInclude(JsonInclude.Include.NON_NULL)
- public static class ReqMstData {
-
- @NotBlank
- private List cols;
- @NotBlank
- private List rows;
- }
-
- /**
- *
- * Postplus 우편제작 접수 요청 Data Detail DTO
- *
- */
- @Schema(name = "ReqDtlData", description = "Postplus 우편제작 접수 요청 Data Dtl DTO")
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- @SuperBuilder
- @JsonInclude(JsonInclude.Include.NON_NULL)
- public static class ReqDtlData {
-
- @NotBlank
- private List cols;
- @NotBlank
- private List> rows;
- }
-
- /**
- *
- * Postplus 우편제작 접수 요청 Data Master DTO
- *
- */
- @Schema(name = "ReqDataMst", description = "Postplus 우편제작 접수 요청 Data master DTO")
+ @Schema(name = "PpAcceptReqDataMst", description = "Postplus 우편제작 접수 요청 Data master DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@JsonInclude(JsonInclude.Include.NON_NULL)
- public static class ReqDataMst {
+ public static class PpAcceptReqDataMst {
//-----------------------------------------------------------------------
// 필수
//-----------------------------------------------------------------------
@@ -344,7 +323,8 @@ public class PplusDTO {
*/
@Schema(requiredMode = RequiredMode.REQUIRED, title = "반송여부유무", example = "N")
@NotEmpty(message = "반송여부는 필수입니다(Y|N)")
- private final String 반송여부 = "N";
+ //private final String 반송여부 = "N";
+ private final String[] 반송여부 = new String[]{"Y", "N"};
/**
*
@@ -445,13 +425,13 @@ public class PplusDTO {
* Postplus 우편제작 접수 요청 Data Detail DTO
*
*/
- @Schema(name = "ReqDataDtl", description = "Postplus 우편제작 접수 요청 Data detail DTO")
+ @Schema(name = "PpAcceptReqDataDtl", description = "Postplus 우편제작 접수 요청 Data detail DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@JsonInclude(JsonInclude.Include.NON_NULL)
- public static class ReqDataDtl {
+ public static class PpAcceptReqDataDtl {
//-----------------------------------------------------------------------
// 필수
//-----------------------------------------------------------------------
diff --git a/mens-core/src/main/java/kr/xit/core/spring/config/custom/bouncy/BouncyUtils.java b/mens-core/src/main/java/kr/xit/core/spring/config/custom/bouncy/BouncyUtils.java
index 1c5dcc7..8813bf3 100644
--- a/mens-core/src/main/java/kr/xit/core/spring/config/custom/bouncy/BouncyUtils.java
+++ b/mens-core/src/main/java/kr/xit/core/spring/config/custom/bouncy/BouncyUtils.java
@@ -143,14 +143,14 @@ public class BouncyUtils {
}
}
- public static void encryptionFile(String key, String filePath) throws IOException {
+ public static void encryptionFile(final String key, final String filePath, final String fileName) throws IOException {
byte[] plainFileBytes = FileUtil.getFileBytesFrom(filePath);
- FileUtil.saveFile(filePath, encrypt(key, plainFileBytes));
+ FileUtil.saveFile(filePath, fileName, encrypt(key, plainFileBytes));
}
- public static void decryptionFile(String key, String filePath) throws IOException {
+ public static void decryptionFile(final String key, final String filePath, final String fileName) throws IOException {
byte[] encryptedFileBytes = FileUtil.getFileBytesFrom(filePath);
- FileUtil.saveFile(filePath, BouncyDecUtils.decrypt(key, encryptedFileBytes));
+ FileUtil.saveFile(filePath, fileName, BouncyDecUtils.decrypt(key, encryptedFileBytes));
}
/**
diff --git a/mens-core/src/main/java/kr/xit/core/spring/util/ApiWebClientUtil.java b/mens-core/src/main/java/kr/xit/core/spring/util/ApiWebClientUtil.java
index c3bb145..6a6aa3a 100644
--- a/mens-core/src/main/java/kr/xit/core/spring/util/ApiWebClientUtil.java
+++ b/mens-core/src/main/java/kr/xit/core/spring/util/ApiWebClientUtil.java
@@ -47,6 +47,7 @@ import reactor.core.publisher.Mono;
* @see ClientError
* @see ServerError
* @see ErrorParse
+ * @see kr.xit.core.spring.config.support.CustomJacksonConfig
*/
@Slf4j
@Component
diff --git a/mens-core/src/main/java/kr/xit/core/support/utils/FileUtil.java b/mens-core/src/main/java/kr/xit/core/support/utils/FileUtil.java
index 47e259f..11c819f 100644
--- a/mens-core/src/main/java/kr/xit/core/support/utils/FileUtil.java
+++ b/mens-core/src/main/java/kr/xit/core/support/utils/FileUtil.java
@@ -1,8 +1,27 @@
package kr.xit.core.support.utils;
+import static java.nio.file.Files.probeContentType;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
import kr.xit.core.exception.BizRuntimeException;
import java.io.*;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItem;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
/**
*
@@ -19,6 +38,8 @@ import java.io.*;
*
*
*/
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class FileUtil {
public static byte[] getFileBytesFrom(String path) {
@@ -36,12 +57,158 @@ public class FileUtil {
return fileBytes;
}
- public static void saveFile(String path, byte[] fileData) {
+ public static void saveFile(String path, String fileName, byte[] fileData) {
+ Path p = Paths.get(path);
- try(FileOutputStream fos = new FileOutputStream(path);){
+ if(!Files.isDirectory(p)){
+ try {
+ Files.createDirectory(p);
+ } catch (IOException e) {
+ throw BizRuntimeException.create(e.getMessage());
+ }
+ }
+ try(FileOutputStream fos = new FileOutputStream(path + "/" + fileName);){
fos.write(fileData);
} catch (IOException e) {
throw BizRuntimeException.create(e.getMessage());
}
}
+
+ /**
+ * 파일명 + 파일경로를 받아 MultipartFile 생성 return
+ * @param fileNm
+ * @param filePath
+ * @return MultipartFile
+ */
+ @SuppressWarnings("DuplicatedCode")
+ public static MultipartFile createMutipartFile(final String fileNm, final String filePath){
+ File file = new File(filePath+"/"+fileNm);
+ try {
+ FileItem fileItem = new DiskFileItem(fileNm, probeContentType(file.toPath()), false, file.getName(), (int) file.length(), file.getParentFile());
+
+ try(InputStream input = Files.newInputStream(file.toPath());
+ OutputStream os = fileItem.getOutputStream()) {
+ IOUtils.copy(input, os);
+ }catch(IOException e){
+ throw BizRuntimeException.create(e.getMessage());
+ }
+ return new CommonsMultipartFile(fileItem);
+
+ } catch (IOException ex) {
+ throw BizRuntimeException.create(ex.getMessage());
+ }
+ }
+
+ /**
+ * binary(byte) 파일객체 에서 MultipartFile 객체 GET
+ * @param fileNm 원본파일 명
+ * @param filePath 업로드 경로 - MultipartFile 객체 생성을 위한 임시 경로
+ * @param data byte 파일 객체
+ * @param isFileDelete 임시 파일 삭제 여부
+ * @return MultipartFile 생성된 MultipartFile
+ */
+ @SuppressWarnings("DuplicatedCode")
+ public static MultipartFile createMutipartFileFromBytes(final String fileNm, final String filePath, final byte[] data, boolean isFileDelete){
+ File file = new File(filePath+"/"+fileNm);
+ try {
+ FileUtils.writeByteArrayToFile(file, data);
+
+ FileItem fileItem = new DiskFileItem(fileNm, probeContentType(file.toPath()), false, file.getName(), (int) file.length(), file.getParentFile());
+
+ try(InputStream input = Files.newInputStream(file.toPath());
+ OutputStream os = fileItem.getOutputStream()) {
+ IOUtils.copy(input, os);
+ }catch(IOException e){
+ throw BizRuntimeException.create(e.getMessage());
+ }
+ if(isFileDelete && file.exists()) {
+ //noinspection ResultOfMethodCallIgnored
+ file.delete();
+ }
+ return new CommonsMultipartFile(fileItem);
+ } catch (IOException ex) {
+ throw BizRuntimeException.create(ex.getMessage());
+ }
+ }
+
+ /**
+ * zip 파일 생성
+ * @param filePath source file path
+ * @param fileNameList source file name list
+ * @param zipFilePath zip file folder
+ * @param zipFileName zip file name
+ */
+ public static String compressZip(final String filePath, final List fileNameList, final String zipFilePath, final String zipFileName) {
+ List fileList = new ArrayList<>();
+
+ fileNameList.forEach(s -> fileList.add(new File(filePath, s)));
+ return compressZip(fileList, zipFilePath, zipFileName);
+ }
+
+ /**
+ * Zip 파일 생성
+ * @param fileList zip file name list
+ * @param zipFilePath zip file folder
+ * @param zipFileName zip file name
+ */
+ public static String compressZip(final List fileList, final String zipFilePath, final String zipFileName) {
+ File zipFile = new File(zipFilePath, zipFileName);
+
+ byte[] buff = new byte[4096];
+ // 압축파일 생성
+ try(ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))){
+
+ // 파일 압축
+ fileList.forEach(f -> {
+ try(FileInputStream fis = new FileInputStream(f)){
+ // 압축파일 지정
+ ZipEntry ze = new ZipEntry(f.getName());
+ zos.putNextEntry(ze);
+
+ // 압축 파일에 추가
+ int len;
+ while ((len = fis.read(buff)) > 0) zos.write(buff, 0, len);
+
+ zos.closeEntry();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ });
+ return zipFilePath + "/" + zipFileName;
+
+ } catch (FileNotFoundException e) {
+ log.error("zip파일 생성 오류::{}", e.getLocalizedMessage());
+ throw BizRuntimeException.create("zip 파일생성 오류[대상파일 미존재]");
+ } catch (IOException e) {
+ log.error("zip파일 생성 오류::{}", e.getLocalizedMessage());
+ throw BizRuntimeException.create("zip 파일생성 오류[대상파일 미존재]");
+ }
+ }
+
+ /**
+ *
+ * path 경로의 모든 파일 삭제(directory 포함)
+ * @param path String 삭제할 경로
+ *
+ */
+ public static void removeDirectyAndFiles(String path){
+ try {
+ // 작업 파일 삭제
+ Path dir = Paths.get(path);
+ Files.walk(dir) // Traverse the file tree in depth-first order
+ .sorted(Comparator.reverseOrder())
+ .forEach(f -> {
+ try {
+ Files.delete(f); //delete each file or directory
+ } catch (IOException e) {
+ log.error(e.getLocalizedMessage());
+ e.printStackTrace();
+ }
+ });
+ }catch (IOException ie){
+ log.error(ie.getLocalizedMessage());
+ ie.printStackTrace();
+ }
+ }
}
diff --git a/mens-core/src/main/java/kr/xit/core/support/utils/JsonUtils.java b/mens-core/src/main/java/kr/xit/core/support/utils/JsonUtils.java
index 3858ed5..3e9f4c9 100644
--- a/mens-core/src/main/java/kr/xit/core/support/utils/JsonUtils.java
+++ b/mens-core/src/main/java/kr/xit/core/support/utils/JsonUtils.java
@@ -1,15 +1,8 @@
package kr.xit.core.support.utils;
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.databind.cfg.CoercionAction;
-import com.fasterxml.jackson.databind.cfg.CoercionInputShape;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@@ -18,9 +11,25 @@ import kr.xit.core.spring.util.SpringUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+
/**
- * JSON Util Class
+ *
+ * description : JSON Utility
+ *
+ * packageName : kr.xit.core.support.utils
+ * fileName : JsonUtils
+ * author : limju
+ * date : 2023-09-04
+ * ======================================================================
+ * 변경일 변경자 변경 내용
+ * ----------------------------------------------------------------------
+ * 2023-09-04 limju 최초 생성
+ *
+ *
+ * @see kr.xit.core.spring.config.support.CustomJacksonConfig
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class JsonUtils {
@@ -75,8 +84,11 @@ public class JsonUtils {
* @return T
*/
public static T toObjByObj(final Object obj, final Class cls) {
- final String str = toJson(obj);
- return str != null ? toObject(str, cls) : null;
+ try {
+ return obj != null ? OM.convertValue(obj, cls) : null;
+ } catch (IllegalArgumentException e) {
+ throw BizRuntimeException.create(e.getLocalizedMessage());
+ }
}
/**
@@ -111,6 +123,91 @@ public class JsonUtils {
}
}
+ /**
+ * Object의 key와 value를 추출
+ * -> key배열, value배열의 JSONObject return
+ * @param obj key, value를 추출할 Object
+ * @param keyName key배열의 JSON key name
+ * @param valueName value배열의 JSON key name
+ * @return JSONObject key배열, value배열의 JSONObject
+ */
+ public static JSONObject extractObjKeyValue(final Object obj, final String keyName, final String valueName){
+ return extractJsonKeyValue(toObjByObj(obj, JSONObject.class), keyName, valueName);
+ }
+
+ /**
+ * JSONObject의 key와 value를 추출
+ * -> key배열, value배열의 JSONObject return
+ * @param json
+ * @param keyName key배열의 JSON key name
+ * @param valueName value배열의 JSON key name
+ * @return JSONObject key배열, value배열의 JSONObject
+ */
+ public static JSONObject extractJsonKeyValue(final JSONObject json, final String keyName, final String valueName){
+ final JSONObject rtnJson = new JSONObject();
+ final JSONArray keys = new JSONArray();
+ final JSONArray values = new JSONArray();
+ for (Object key : json.keySet()) {
+ Object value = json.get(key);
+
+ if (value instanceof JSONObject)
+ extractJsonKeyValue((JSONObject)value, keyName, valueName);
+ else if (value instanceof JSONArray)
+ ((JSONArray)value).forEach(obj -> extractJsonKeyValue((JSONObject)obj, keyName, valueName));
+ else{
+ //System.out.println(key + ", " + value);
+ keys.add(String.valueOf(key));
+ values.add(value);
+ }
+ }
+ rtnJson.put(keyName, keys);
+ rtnJson.put(valueName, values);
+ return rtnJson;
+ }
+
+ /**
+ * JSONArray의 key와 value를 추출
+ * -> key배열, value배열의 JSONObject return
+ * @param jsons JSONArray
+ * @param keyName key배열의 JSON key name
+ * @param valueName value배열의 JSON key name
+ * @return JSONObject key배열, value배열의 JSONObject
+ */
+ public static JSONObject extractJsonArrayKeyValue(final net.sf.json.JSONArray jsons, final String keyName, final String valueName){
+ final JSONObject rtnJson = new JSONObject();
+ final JSONArray keys = new JSONArray();
+ final JSONArray values = new JSONArray();
+ for(int i = 0; i extractJsonKeyValue((JSONObject)obj, keyName, valueName));
+ else{
+ //System.out.println(key + ", " + value);
+ keys.add(String.valueOf(key));
+ values.add(value);
+ }
+ }
+ rtnJson.put(keyName, keys);
+ rtnJson.put(valueName, values);
+ return rtnJson;
+ }
+
/**
* Json 데이터 보기 좋게 변환.
* @param obj Object json
@@ -125,25 +222,6 @@ public class JsonUtils {
}
}
- private static ObjectMapper getObjectMapper() {
- final ObjectMapper om = new ObjectMapper();
- om.setSerializationInclusion(Include.NON_NULL);
- // No serializer found for class 에러 - private 필드
- om.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
- om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
- om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- om.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, false);
-
- om.coercionConfigDefaults()
- .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsNull);
-// om.coercionConfigFor(LogicalType.Enum)
-// .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsNull);
-// om.coercionConfigFor(LogicalType.POJO)
-// .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsNull);
-
- return om;
- }
-
/**
* Json 데이터 보기 좋게 변환.
* @param json String json