Merge remote-tracking branch 'origin/jenkins_with_weblogic' of C:/KJB_DEV/eapim-bundle/bundles/251215/eapim-admin_incremental_2025-11-15.bundle into jenkins_with_weblogic
This commit is contained in:
@@ -78,6 +78,9 @@
|
||||
<context:exclude-filter type="aspectj"
|
||||
expression="!com.eactive.eai.rms..*Controller" />
|
||||
</context:component-scan>
|
||||
|
||||
<!-- .json 요청에서 빈 응답을 {} 로 변환하는 ResponseBodyAdvice -->
|
||||
<bean class="com.eactive.eai.rms.common.advice.EmptyJsonResponseAdviceController" />
|
||||
<mvc:interceptors>
|
||||
<mvc:interceptor>
|
||||
<mvc:mapping path="/**" />
|
||||
|
||||
@@ -184,39 +184,125 @@ $(document).ready(function() {
|
||||
$("#btn_clone").hide();
|
||||
}
|
||||
|
||||
FilePond.registerPlugin(FilePondPluginFileValidateType);
|
||||
// FilePond 인스턴스 생성
|
||||
const pond = FilePond.create(document.querySelector('.filepond'), {
|
||||
instantUpload: false, // 파일을 즉시 업로드하지 않음
|
||||
allowRevert: false,
|
||||
acceptedFileTypes: ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/json'],
|
||||
// 서버 설정
|
||||
// 25.12.11 파일 가져오기 할 때 중복 검사 기능추가.
|
||||
FilePond.registerPlugin(FilePondPluginFileValidateType);
|
||||
|
||||
let uploadErrors = [];
|
||||
let processedCount = 0;
|
||||
let totalFiles = 0;
|
||||
|
||||
// FilePond 인스턴스 생성
|
||||
const pond = FilePond.create(document.querySelector('.filepond'), {
|
||||
instantUpload: false,
|
||||
allowRevert: false,
|
||||
acceptedFileTypes: ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/json'],
|
||||
|
||||
// 서버 설정
|
||||
server: {
|
||||
process: {
|
||||
url: url_file + '?cmd=LIST_IMPORT_FILE&serviceType=' + sessionStorage["serviceType"],
|
||||
method: 'POST',
|
||||
// 필요한 경우 headers나 다른 설정 추가
|
||||
},
|
||||
// revert, load, restore, fetch 설정 (필요한 경우)
|
||||
},
|
||||
// 다른 필요한 옵션 추가
|
||||
});
|
||||
ondata: (formData) => {
|
||||
const chkBox = document.querySelector('#uploadModal input[name="importDupliCheck"]');
|
||||
const isChecked = chkBox ? chkBox.checked : false;
|
||||
formData.append('importDupliCheck', isChecked);
|
||||
return formData;
|
||||
},
|
||||
onerror: (response) => {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
pond.on('processfiles', () => {
|
||||
// 여기에 모든 파일 업로드 완료 후 실행할 코드를 작성
|
||||
console.debug('모든 파일의 처리가 완료되었습니다.');
|
||||
$('#btn_search').click();
|
||||
});
|
||||
// 파일 처리 결과 수신
|
||||
pond.on('processfile', (error, file) => {
|
||||
processedCount++;
|
||||
|
||||
// "업로드 시작" 버튼 클릭 이벤트 핸들러
|
||||
document.getElementById('uploadButton').addEventListener('click', function() {
|
||||
pond.processFiles(); // 선택된 모든 파일을 업로드
|
||||
});
|
||||
if (error) {
|
||||
let errorMsg = '';
|
||||
|
||||
if (error.body) {
|
||||
errorMsg = error.body;
|
||||
} else if (typeof error === 'string') {
|
||||
errorMsg = error;
|
||||
} else {
|
||||
errorMsg = '가져오기 중 오류가 발생 했습니다.';
|
||||
}
|
||||
|
||||
let fileName = 'UnKnown';
|
||||
if (file) {
|
||||
if(file.filename) fileName = file.filename;
|
||||
else if (file.file && file.file.name) fileName = file.file.name;
|
||||
}
|
||||
|
||||
uploadErrors.push('파일명 [ ' + fileName + '] \n MESSAGE : ' + errorMsg);
|
||||
}
|
||||
|
||||
// 모든 파일 처리 완료 시
|
||||
if (processedCount >= totalFiles) {
|
||||
setTimeout(() => {
|
||||
if (uploadErrors.length > 0) {
|
||||
const msg = "파일 처리 중 오류가 발생했습니다. \n" + uploadErrors.join('\n');
|
||||
|
||||
// 실패 시 변수 초기화
|
||||
uploadErrors = [];
|
||||
processedCount = 0;
|
||||
|
||||
$('#btn_search').click();
|
||||
alert(msg);
|
||||
|
||||
} else {
|
||||
alert('모든 파일이 성공적으로 업로드 되었습니다.');
|
||||
$('#uploadModal').modal('hide');
|
||||
$('#btn_search').click();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
|
||||
// 업로드 버튼 클릭 이벤트
|
||||
document.getElementById('uploadButton').addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
uploadErrors = [];
|
||||
processedCount = 0;
|
||||
|
||||
const currentFiles = pond.getFiles();
|
||||
totalFiles = currentFiles.length;
|
||||
|
||||
if (totalFiles === 0) {
|
||||
alert("업로드 할 파일을 선택하세요.");
|
||||
return;
|
||||
}
|
||||
|
||||
const chkBox = document.getElementById('importDupliCheck');
|
||||
|
||||
if (chkBox && !chkBox.checked) {
|
||||
if (!confirm("중복검사를 체크하지 않는 경우 기존 값은 덮어 씌워집니다. \n진행하시겠습니까?")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pond.processFiles();
|
||||
});
|
||||
|
||||
// 모달이 닫힐 때만 초기화
|
||||
$('#uploadModal').on('hidden.bs.modal', function(e) {
|
||||
resetPond();
|
||||
});
|
||||
|
||||
function resetPond() {
|
||||
pond.removeFiles();
|
||||
|
||||
const chkBox = document.getElementById('importDupliCheck');
|
||||
if (chkBox) chkBox.checked = false;
|
||||
|
||||
processedCount = 0;
|
||||
totalFiles = 0;
|
||||
uploadErrors = [];
|
||||
}
|
||||
|
||||
// 모달 닫기 이벤트 핸들러
|
||||
$('#uploadModal').on('hidden.bs.modal', function (e) {
|
||||
pond.removeFiles(); // 모달이 닫힐 때 파일 목록에서 모든 파일 제거
|
||||
});
|
||||
});
|
||||
|
||||
function jqGridInit() {
|
||||
@@ -412,6 +498,9 @@ function jqGridInit() {
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- 파일 업로드 시 중복체크 -->
|
||||
<input type="checkbox" id="importDupliCheck" name="importDupliCheck">
|
||||
<label class="form-check-label" for="importDupliCheck">중복검사</label>
|
||||
<input type="file" class="filepond" name="file" multiple data-allow-reorder="true" data-max-file-size="3MB" data-max-files="10">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
||||
@@ -830,7 +830,12 @@
|
||||
//표준이 아닐경우 업무추출키 셋팅되어야 됨
|
||||
$("input[name=bzwkSvcKeyName]").val($("input[name=eaiTranName]").val());
|
||||
}
|
||||
|
||||
|
||||
// 사용자 편의를 위해 inboundRestPath 앞에 "/" 는 제외함.
|
||||
$("input[name=inboundRestPath]").val(function(index, value) {
|
||||
return value.replace(/^\/+/, "");
|
||||
});
|
||||
|
||||
var postData = $('#ajaxForm').serializeArray();
|
||||
if (isDetail){
|
||||
postData.push({ name: "cmd" , value:"UPDATE"});
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package com.eactive.eai.rms.common.advice;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* .json 요청에 대해 빈 응답 본문을 {}로 변환하는 ResponseBodyAdvice.
|
||||
*
|
||||
* 웹서버를 거치면서 Content-Type이 application/json으로 설정되는데,
|
||||
* 빈 응답이면 JavaScript(jQuery)가 JSON 파싱 시 에러가 발생하는 문제를 해결합니다.
|
||||
*/
|
||||
@ControllerAdvice
|
||||
public class EmptyJsonResponseAdviceController implements ResponseBodyAdvice<Object> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(EmptyJsonResponseAdviceController.class);
|
||||
private static final Map<String, Object> EMPTY_JSON = Collections.emptyMap();
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
logger.info("========== EmptyJsonResponseAdviceController 로딩됨 ==========");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
|
||||
// 모든 응답에 대해 적용 (beforeBodyWrite에서 .json 요청만 필터링)
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
|
||||
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
|
||||
ServerHttpResponse response) {
|
||||
|
||||
// .json 요청이 아니면 원본 그대로 반환
|
||||
String path = request.getURI().getPath();
|
||||
if (path == null || !path.endsWith(".json")) {
|
||||
return body;
|
||||
}
|
||||
|
||||
// 빈 응답인 경우 빈 JSON 객체로 변환
|
||||
if (body == null) {
|
||||
logger.debug("빈 응답 감지 (null), {} 로 변환: {}", path);
|
||||
return EMPTY_JSON;
|
||||
}
|
||||
|
||||
// String 타입의 빈 응답 처리
|
||||
if (body instanceof String && ((String) body).isEmpty()) {
|
||||
logger.debug("빈 응답 감지 (empty string), {} 로 변환: {}", path);
|
||||
return EMPTY_JSON;
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.eactive.eai.rms.common.advice;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* EmptyJsonResponseAdviceController 테스트용 컨트롤러.
|
||||
* 테스트 후 삭제 필요.
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/test/empty-json")
|
||||
public class EmptyJsonResponseTestController {
|
||||
|
||||
/**
|
||||
* null 반환 테스트
|
||||
* URL: /monitoring/test/empty-json/null.json
|
||||
*/
|
||||
@RequestMapping("/null.json")
|
||||
@ResponseBody
|
||||
public Object returnNull() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 빈 문자열 반환 테스트
|
||||
* URL: /monitoring/test/empty-json/empty-string.json
|
||||
*/
|
||||
@RequestMapping("/empty-string.json")
|
||||
@ResponseBody
|
||||
public String returnEmptyString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 정상 데이터 반환 테스트 (변환되지 않아야 함)
|
||||
* URL: /monitoring/test/empty-json/normal.json
|
||||
*/
|
||||
@RequestMapping("/normal.json")
|
||||
@ResponseBody
|
||||
public String returnNormal() {
|
||||
return "{\"status\":\"ok\"}";
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.web.SortDefault;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -432,7 +433,7 @@ public class AdapterController extends OnlBaseAnnotationController {
|
||||
|
||||
@PostMapping(value = "/onl/admin/adapter/adapterMan.file", params = "cmd=LIST_IMPORT_FILE")
|
||||
public ResponseEntity<?> listImportFromFile(
|
||||
@RequestParam("file") MultipartFile file) {
|
||||
@RequestParam("file") MultipartFile file, boolean importDupliCheck) {
|
||||
|
||||
try {
|
||||
|
||||
@@ -445,7 +446,7 @@ public class AdapterController extends OnlBaseAnnotationController {
|
||||
|
||||
synchronized (obj) {
|
||||
AdapterGroupUI importedUI = service
|
||||
.importAdapterFromJson(file);
|
||||
.importAdapterFromJson(file, importDupliCheck);
|
||||
|
||||
Map<String, String> resultMap = service
|
||||
.reloadSync(importedUI);
|
||||
@@ -456,6 +457,10 @@ public class AdapterController extends OnlBaseAnnotationController {
|
||||
|
||||
}
|
||||
|
||||
} catch (IllegalStateException dupEx) {
|
||||
return ResponseEntity
|
||||
.status(HttpStatus.CONFLICT)
|
||||
.body(dupEx.getMessage());
|
||||
} catch (Exception e) {
|
||||
logger.error(e);
|
||||
return ResponseEntity.internalServerError()
|
||||
|
||||
+20
-5
@@ -565,7 +565,7 @@ public class AdapterManService extends OnlBaseService {
|
||||
return adapterPropLoader.findSnaAppcodeProps((String) map.get("searchPrptygroupName"));
|
||||
}
|
||||
|
||||
public AdapterGroupUI importAdapterFromJson(MultipartFile file) throws Exception {
|
||||
public AdapterGroupUI importAdapterFromJson(MultipartFile file, boolean importDupliCheck) throws Exception {
|
||||
if (file.isEmpty()) {
|
||||
throw new IOException("File is empty");
|
||||
}
|
||||
@@ -574,13 +574,28 @@ public class AdapterManService extends OnlBaseService {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.addMixIn(AdapterGroupUI.class, AdapterGroupUIMixIn.class);
|
||||
AdapterGroupUI adapterGroupUI = objectMapper.readValue(inputStream, AdapterGroupUI.class);
|
||||
|
||||
if(!adapterGroupService.existsById(adapterGroupUI.getAdptrbzwkgroupname())){
|
||||
|
||||
String adapterGrpupName = adapterGroupUI.getAdptrbzwkgroupname();
|
||||
boolean adapterGroupExists = adapterGroupService.existsById(adapterGroupUI.getAdptrbzwkgroupname());
|
||||
|
||||
if (adapterGroupExists) {
|
||||
|
||||
if (importDupliCheck) {
|
||||
throw new IllegalStateException("AdapterGroup already exists [ " + adapterGrpupName + " ]" );
|
||||
} else {
|
||||
update(adapterGroupUI);
|
||||
}
|
||||
|
||||
} else {
|
||||
insert(adapterGroupUI);
|
||||
}else{
|
||||
update(adapterGroupUI);
|
||||
}
|
||||
|
||||
// if(!adapterGroupService.existsById(adapterGroupUI.getAdptrbzwkgroupname())){
|
||||
// insert(adapterGroupUI);
|
||||
// }else{
|
||||
// update(adapterGroupUI);
|
||||
// }
|
||||
|
||||
return adapterGroupUI;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user