From 0b6f27313255908b9268bb23bd8b398ae68faa70 Mon Sep 17 00:00:00 2001 From: eastargh Date: Thu, 10 Sep 2026 09:56:50 +0900 Subject: [PATCH] =?UTF-8?q?UMS=20=EC=9D=91=EB=8B=B5=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=20=EB=B0=8F=20=EC=83=81=EC=84=B8=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../messageRequestManDetail.jsp | 6 ++ .../rms/ext/djb/ums/service/UmsService.java | 80 +++++++++++++------ .../MessageRequestManService.java | 1 + .../apim/messagerequest/MessageRequestUI.java | 3 + .../service/ums/UmsDispatchService.java | 16 +++- 5 files changed, 79 insertions(+), 27 deletions(-) diff --git a/WebContent/jsp/onl/apim/messagerequest/messageRequestManDetail.jsp b/WebContent/jsp/onl/apim/messagerequest/messageRequestManDetail.jsp index f93e3b5..8f40f33 100644 --- a/WebContent/jsp/onl/apim/messagerequest/messageRequestManDetail.jsp +++ b/WebContent/jsp/onl/apim/messagerequest/messageRequestManDetail.jsp @@ -47,6 +47,8 @@ $('#sentDate').text(data.sentDateFull || ''); // 서버에서 마스킹+escape 된 안전 HTML $('#messageHtml').html(data.messageHtml || ''); + // 응답내용(RESPONSE_DATA) — 원문이므로 text 로만 출력 + $('#responseData').text(data.responseData || ''); // PENDING 건만 '실패 처리' 노출 (권한 제어는 buttonControl 이 담당) if (data.requestStatus !== 'PENDING') { @@ -142,6 +144,10 @@ 메세지 내용
+ + 응답내용 +
+ diff --git a/src/main/java/com/eactive/eai/rms/ext/djb/ums/service/UmsService.java b/src/main/java/com/eactive/eai/rms/ext/djb/ums/service/UmsService.java index f934b77..2f3bc04 100644 --- a/src/main/java/com/eactive/eai/rms/ext/djb/ums/service/UmsService.java +++ b/src/main/java/com/eactive/eai/rms/ext/djb/ums/service/UmsService.java @@ -1,6 +1,7 @@ package com.eactive.eai.rms.ext.djb.ums.service; import java.io.BufferedReader; +import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; @@ -11,6 +12,7 @@ import java.nio.charset.Charset; import java.security.SecureRandom; import java.text.SimpleDateFormat; import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -62,27 +64,35 @@ public class UmsService { throw new IllegalArgumentException("messageRequest is null"); } - this.httpConnection(messageRequest); + UmsResponse response = this.httpConnection(messageRequest); - return true; + // HTTP 응답코드가 2xx 일 때만 SENT, 나머지는 FAILED + boolean success = response.getHttpStatus() >= 200 && response.getHttpStatus() < 300; + + messageRequest.setRequestStatus(success ? "SENT" : "FAILED"); + messageRequest.setSentDate(LocalDateTime.now()); + messageRequest.setResponseData(response.getResponseData()); + messageRequestService.save(messageRequest); + + return success; } - private void httpConnection(MessageRequest messageRequest) throws Exception { + private UmsResponse httpConnection(MessageRequest messageRequest) throws Exception { HttpURLConnection conn = null; BufferedReader br = null; log.debug("<<>>:" + messageRequest.toString()); try { String host = propertyService.getPropertyValue("Monitoring", "djb.ums."+messageRequest.getMessageType().toLowerCase()+".url", ""); - + URL url = new URL(host); int timeoutValue = 5 * 1000; // 타임아웃 설정을 위한 값 (단위: ms) // Charset charset = Charset.forName("UTF-8"); Charset charset = Charset.forName("MS949"); - + StringBuffer sb = null; String bodyData = this.makeBodyData(messageRequest); - + String responseData = ""; String method = bodyData.isEmpty() ? "GET" : "POST"; conn = (HttpURLConnection) url.openConnection(); @@ -92,7 +102,7 @@ public class UmsService { conn.setConnectTimeout(timeoutValue); // 연결 타임아웃 설정(5초) conn.setReadTimeout(timeoutValue); // 읽기 타임아웃 설정(5초) conn.setDoOutput(true); - + // POst 방식인 경우에만 if (method.equals("POST")) { OutputStream os = conn.getOutputStream(); @@ -100,29 +110,32 @@ public class UmsService { os.write(requestData); os.close(); } - + + int responseCode = conn.getResponseCode(); + if (log.isDebugEnabled()) { log.debug("getContentType();" + conn.getContentType()); // 응답 콘텐츠 유형 구하기 - log.debug("getResponsecode();" + conn.getResponseCode()); // 응답 코드 구하기 + log.debug("getResponsecode();" + responseCode); // 응답 코드 구하기 log.debug("getResponseMessage():" + conn.getResponseMessage()); // 응답 메세지 구하기 } - + // http 요청 후 응답 받은 데이타를 버퍼에 쌓는다 - if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) { - br = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset)); - } else { - br = new BufferedReader(new InputStreamReader(conn.getErrorStream(), charset)); + InputStream is = (responseCode >= 200 && responseCode < 300) ? conn.getInputStream() : conn.getErrorStream(); + if (is != null) { + br = new BufferedReader(new InputStreamReader(is, charset)); + + String inputLine; + sb = new StringBuffer(); + while ((inputLine = br.readLine()) != null) { + sb.append(inputLine); + } + + responseData = sb.toString(); } + - String inputLine; - sb = new StringBuffer(); - while ((inputLine = br.readLine()) != null) { - sb.append(inputLine); - } - - responseData = sb.toString(); - - log.debug("UMS responseData:" + responseData); + + return new UmsResponse(responseCode, responseData); } finally { // http 요청 및 응답 완료 후 BufferedReader를 닫는다 if (br != null) { @@ -133,6 +146,25 @@ public class UmsService { } } } + + /** UMS HTTP 호출 결과(응답코드 + 응답본문) 보관용. */ + private static class UmsResponse { + private final int httpStatus; + private final String responseData; + + UmsResponse(int httpStatus, String responseData) { + this.httpStatus = httpStatus; + this.responseData = responseData; + } + + int getHttpStatus() { + return httpStatus; + } + + String getResponseData() { + return responseData; + } + } @@ -263,7 +295,7 @@ public class UmsService { } else { dataVO.setAlmtk_snd_prfl_key(propertyService.getPropertyValue("Monitoring", "djb.ums.sms.almtk_snd_prtl_key.public", "")); // 제주은행 플러스친구아이디 } - dataVO.setAlmtk_tmplt_cd(BZWK_DVCD + TEAM_DVCD + BZWK_DCLS_DVCD + "001"); // 템플릿코드 + dataVO.setAlmtk_tmplt_cd("JJB_85959019001"); // 템플릿코드 dataVO.setAlmtk_err_ltrs_snd_yn("Y"); // 오류자문자발송여부 dataVO.setAlmtk_btn_trnm_tycd("2"); // 카카오버튼전송방식 1-format string 2-JSON 3-XML diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/messagerequest/MessageRequestManService.java b/src/main/java/com/eactive/eai/rms/onl/apim/messagerequest/MessageRequestManService.java index f4e5dd8..f7f7b07 100644 --- a/src/main/java/com/eactive/eai/rms/onl/apim/messagerequest/MessageRequestManService.java +++ b/src/main/java/com/eactive/eai/rms/onl/apim/messagerequest/MessageRequestManService.java @@ -72,6 +72,7 @@ public class MessageRequestManService extends BaseService { ui.setUmsUid(e.getUmsUid()); ui.setRequestStatus(e.getRequestStatus()); + ui.setResponseData(e.getResponseData()); ui.setEaiInterfaceId(e.getEaiInterfaceId()); ui.setServiceId(e.getServiceId()); diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/messagerequest/MessageRequestUI.java b/src/main/java/com/eactive/eai/rms/onl/apim/messagerequest/MessageRequestUI.java index 3762170..7208901 100644 --- a/src/main/java/com/eactive/eai/rms/onl/apim/messagerequest/MessageRequestUI.java +++ b/src/main/java/com/eactive/eai/rms/onl/apim/messagerequest/MessageRequestUI.java @@ -22,6 +22,9 @@ public class MessageRequestUI { /* 본문 — 패턴 마스킹 + span 색상강조된 안전 HTML */ private String messageHtml; + /* UMS 응답 내용 (RESPONSE_DATA) — 원문 그대로, 화면에서는 text 로만 출력 */ + private String responseData; + /* 수신자 (마스킹) */ private String username; private String email; diff --git a/src/main/java/com/eactive/eai/rms/onl/common/service/ums/UmsDispatchService.java b/src/main/java/com/eactive/eai/rms/onl/common/service/ums/UmsDispatchService.java index a729fd4..468ba64 100644 --- a/src/main/java/com/eactive/eai/rms/onl/common/service/ums/UmsDispatchService.java +++ b/src/main/java/com/eactive/eai/rms/onl/common/service/ums/UmsDispatchService.java @@ -147,8 +147,8 @@ public class UmsDispatchService { try { transactionTemplate.execute(status -> { try { + // 상태(SENT/FAILED) 및 RESPONSE_DATA 저장은 umsService.send() 내부에서 처리한다. umsService.send(message); - updateMessageStatus(message, "SENT"); return null; } catch (Exception e) { // checked exception을 RuntimeException으로 감싸 전파 → TransactionTemplate이 rollback 후 re-throw @@ -159,7 +159,8 @@ public class UmsDispatchService { log.error("Failed to process message: {} - Error: {}", message.getId(), e.getMessage(), e); try { transactionTemplate.execute(s -> { - updateMessageStatus(message, "FAILED"); + // 응답 자체를 받지 못한 경우(네트워크/타임아웃 등) 예외 메시지를 RESPONSE_DATA 에 남긴다. + updateMessageStatus(message, "FAILED", toResponseData(e)); return null; }); } catch (Exception ex) { @@ -171,10 +172,19 @@ public class UmsDispatchService { - public void updateMessageStatus(MessageRequest message, String status) { + public void updateMessageStatus(MessageRequest message, String status, String responseData) { message.setRequestStatus(status); message.setSentDate(LocalDateTime.now()); + if (responseData != null) { + message.setResponseData(responseData); + } entityManager.merge(message); entityManager.flush(); } + + /** 예외를 RESPONSE_DATA 컬럼에 저장할 문자열로 변환한다. (RuntimeException 래퍼는 원인 예외로 풀어서 사용) */ + private static String toResponseData(Throwable t) { + Throwable root = (t instanceof RuntimeException && t.getCause() != null) ? t.getCause() : t; + return String.valueOf(root); + } } \ No newline at end of file