diff --git a/src/main/java/com/eactive/eai/transformer/message/JSONMessage.java b/src/main/java/com/eactive/eai/transformer/message/JSONMessage.java index e708fe3..3683cd1 100644 --- a/src/main/java/com/eactive/eai/transformer/message/JSONMessage.java +++ b/src/main/java/com/eactive/eai/transformer/message/JSONMessage.java @@ -1,7 +1,6 @@ package com.eactive.eai.transformer.message; import java.math.BigDecimal; -import java.text.DecimalFormat; import java.util.HashMap; import java.util.Iterator; import java.util.Stack; @@ -338,14 +337,15 @@ public class JSONMessage extends Message { if( parent instanceof ObjectNode ) { obj = (ObjectNode)parent; - String val = getStringValue(item.getValue(),item); + // 출력 시점 자릿수 검증 (변환으로 생성된 값은 setData 입력검증을 거치지 않음) + validateDecimal(item.getValue(), item); + + // String인 경우에만 Masking 이 가능 - 숫자는 불가능 int itemType = item.getDataTypeId(); if (isMask && "Y".equals(item.getMask()) && (Types.TYPE_STRING == itemType )){ - val = maskString2(val, item.getMaskLength(), item.getMaskOffset()); + String val = maskString2(getStringValue(item.getValue(),item), item.getMaskLength(), item.getMaskOffset()); item.setValue(val); } -// Object value = toJsonObjectType(item.getDataTypeId(), val); - String value = val; if( item.getOccMax() > 1 || item.getOccMax() == -1 ) { // FIELD ARRAY FORMAT "name":["value1", "value2"] arr = (ArrayNode)obj.get(item.getName()); if (arr == null){ @@ -480,41 +480,22 @@ public class JSONMessage extends Message { } } + /** + * item 값을 문자열로 변환한다. 마스킹 대상(TYPE_STRING) 필드에서만 사용된다. + */ protected String getStringValue(Object value, Item item) throws Exception{ if (value == null) return null; String val=""; if (value instanceof String){ - String data = (String)value; - - if (item.getDataTypeId() == Types.TYPE_BIGDECIMAL){ - val = getFormat(data,item.getLength(),item.getDecimalPointLength()); - }else{ - val = data; - } + val = (String)value; } else if (value instanceof byte[]){ - String data = new String((byte[])value); - if (item.getDataTypeId() == Types.TYPE_BIGDECIMAL){ - val = getFormat(data,item.getLength(),item.getDecimalPointLength()); - }else{ - val = data; - } + val = new String((byte[])value); } else if ( value instanceof BigDecimal) { - String data = ((BigDecimal) value).toPlainString(); - if (item.getDataTypeId() == Types.TYPE_BIGDECIMAL){ - val = getFormat(data,item.getLength(),item.getDecimalPointLength()); - }else{ - val = data; - } + val = ((BigDecimal) value).toPlainString(); } else if ( value instanceof Integer) { - String data = String.valueOf(value); - if (item.getDataTypeId() == Types.TYPE_BIGDECIMAL){ - val = getFormat(data,item.getLength(),item.getDecimalPointLength()); - }else{ - val = data; - } + val = String.valueOf(value); } else if ( value instanceof Boolean) { - String data = String.valueOf(value); - val = data; + val = String.valueOf(value); } return val; } @@ -591,83 +572,46 @@ public class JSONMessage extends Message { } } - private String getFormat(String value,int length,int pointLength) throws Exception { - boolean validation = SystemKeys.isValidationEnabled(); - return getFormat(value, length, pointLength, validation) ; - } - - private String getFormat(String value, int length, int pointLength, boolean isValidation) throws Exception{ - if(isValidation) { - if (!Converter.isValid(value,length,pointLength)){ - throw new Exception(String.format("Invalid decimal point format Error value=%s,length=%d,pointLength=%d" - , value,length,pointLength) - ); - } - - boolean isMinus=false; - String pattern = ""; - //음수/양수 check - if (value.indexOf("-")>=0){ - isMinus = true; - } - String data = value.replaceAll(" ", "").replaceAll("-", ""); - if (pointLength> 0 ){//소수부가 있을 경우 - for(int i=isMinus?1:0;i 0 ){ - if (data.length ==1){ - if (data[0].length() > length - pointLength - 1 ){ //정수부 오류 - return false; - } - }else if (data.length ==2){ - if (data[0].length() > length - pointLength - 1 ){ //정수부 오류 - return false; - } - if (data[1].length() > pointLength ){ //실수부 오류 - return false; - } - }else{ - //오류 - return false; - } - - }else{ - if (data.length != 1){ //소수점이 들어와서 오류 - return false; - } - if (data[0].length() > length - pointLength - 1){ //정수부 오류 - return false; - } + + int length = item.getLength(); + int pointLength = item.getDecimalPointLength(); + if (SystemKeys.isValidationEnabled() && !Converter.isValid(data, length, pointLength)) { + throw new Exception(String.format("Invalid decimal point format Error value=%s,length=%d,pointLength=%d" + , data,length,pointLength) + ); } - return true; + // 숫자형 여부 확인 - 파싱 불가 시 NumberFormatException + new BigDecimal(data.replaceAll(" ", "")); } - + // private Object toJsonObjectType(int itemType, String value) { // Object jsonValueObject = null; // diff --git a/src/test/java/com/eactive/eai/transformer/JSONMessageValidationTest.java b/src/test/java/com/eactive/eai/transformer/JSONMessageValidationTest.java index a32256e..9415e76 100644 --- a/src/test/java/com/eactive/eai/transformer/JSONMessageValidationTest.java +++ b/src/test/java/com/eactive/eai/transformer/JSONMessageValidationTest.java @@ -26,7 +26,8 @@ import com.eactive.eai.transformer.message.MessageSetDataException; * 테스트 대상 레이아웃: EAI_UJSONTYPE_REQ1 * - INT_VALUE : INT, length=5, decimal=0 * - LONG_VALUE : LONG, length=10, decimal=0 - * - BIG_VALUE : BIGDECIMAL, length=10, decimal=5 → 정수부 최대 4자리 + * - BIG_VALUE : BIGDECIMAL, length=10, decimal=5 → 정수부 최대 5자리 + * (length 는 소수점(.) 문자를 제외한 전체 자릿수 규약) * - BIG15_VALUE : BIGDECIMAL, length=15, decimal=0 → 정수부 최대 15자리 * - STR_VALUE : STRING, length=20 * @@ -195,12 +196,12 @@ class JSONMessageValidationTest { // ───────────────────────────────────────────────────────────────── @Test - @DisplayName("BIG_VALUE 정수부 초과(5자리 > 4자리 제한) → MessageSetDataException") + @DisplayName("BIG_VALUE 정수부 초과(6자리 > 5자리 제한) → MessageSetDataException") void testBigDecimalIntegerPartOverflow() { enableValidation(); - // 정수부 5자리(12345) → 제한(4자리) 초과 - String data = "{\"EAI_UJSONTYPE_REQ1\":{\"BIG_VALUE\":12345.12345}}"; + // 정수부 6자리(123456) → 제한(5자리) 초과 + String data = "{\"EAI_UJSONTYPE_REQ1\":{\"BIG_VALUE\":123456.12345}}"; Message msg = MessageFactory.getFactory().getMessage("EAI_UJSONTYPE_REQ1"); MessageSetDataException ex = assertThrows( @@ -260,17 +261,33 @@ class JSONMessageValidationTest { assertTrue(result.contains("BIG_VALUE"), "BIG_VALUE가 결과에 포함되어야 합니다"); } + @Test + @DisplayName("BIG_VALUE 정수부 경계값(정수부 5자리 + 소수부 5자리) → 정상 처리") + void testBigDecimalIntegerPartBoundary() throws Exception { + enableValidation(); + + // length=10, decimal=5 이고 length 에 소수점(.)은 포함되지 않으므로 + // 정수부 5자리(10-5)까지 허용된다. + String data = "{\"EAI_UJSONTYPE_REQ1\":{\"BIG_VALUE\":12345.12345}}"; + Message msg = MessageFactory.getFactory().getMessage("EAI_UJSONTYPE_REQ1"); + msg.setData(data); + + String result = (String) msg.getData(); + assertNotNull(result, "결과값이 null이 아니어야 합니다"); + assertTrue(result.contains("BIG_VALUE"), "BIG_VALUE가 결과에 포함되어야 합니다"); + } + // ───────────────────────────────────────────────────────────────── // 2-c. BigDecimal 자릿수 초과 (JSON 문자열 형태) — transformer.validation=true 필요 // ───────────────────────────────────────────────────────────────── @Test - @DisplayName("BIG_VALUE 정수부 초과 문자열 입력(5자리 > 4자리 제한) → MessageSetDataException") + @DisplayName("BIG_VALUE 정수부 초과 문자열 입력(6자리 > 5자리 제한) → MessageSetDataException") void testBigDecimalIntegerPartOverflowFromString() { enableValidation(); - // JSON 문자열 "12345.12345" → 정수부 5자리 초과 - String data = "{\"EAI_UJSONTYPE_REQ1\":{\"BIG_VALUE\":\"12345.12345\"}}"; + // JSON 문자열 "123456.12345" → 정수부 6자리 초과 + String data = "{\"EAI_UJSONTYPE_REQ1\":{\"BIG_VALUE\":\"123456.12345\"}}"; Message msg = MessageFactory.getFactory().getMessage("EAI_UJSONTYPE_REQ1"); MessageSetDataException ex = assertThrows(