diff --git a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/MessageCodec.java b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/MessageCodec.java index f3b84de..e699fbe 100644 --- a/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/MessageCodec.java +++ b/boot/common-framework/src/main/java/com/klaro/acquirecore/framework/MessageCodec.java @@ -1,24 +1,133 @@ package com.klaro.acquirecore.framework; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import org.springframework.stereotype.Component; -/** - * 레거시 {@code msg_layout.h} 고정길이 전문(電文) 코덱의 Spring 빈 자리표시자. - * - *
실 전환에서는 고정길이(positional) 바이트 레이아웃 ↔ DTO 바인딩을 담당한다
- * (BeanIO 또는 커스텀 코덱). 지금은 스켈레톤이 빈으로 뜨는지만 증명한다.
- */
-@Component
-public class MessageCodec {
+import java.util.Map;
- /** 고정길이 필드를 우측을 공백으로 채워 정규화한다 (자리표시자 구현). */
- public String padRight(String value, int width) {
- if (value == null) {
- value = "";
+/**
+ * Message codec interface and JSON implementation.
+ * Provides encoding/decoding of TxRequest and TxResponse.
+ */
+public interface MessageCodec {
+
+ byte[] encodeRequest(TxRequest request);
+ TxRequest decodeRequest(byte[] data);
+ byte[] encodeResponse(TxResponse response);
+ TxResponse decodeResponse(byte[] data);
+ String getContentType();
+
+ @Component
+ class JsonMessageCodec implements MessageCodec {
+
+ private final ObjectMapper objectMapper;
+
+ public JsonMessageCodec() {
+ this.objectMapper = new ObjectMapper()
+ .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
+ .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
- if (value.length() >= width) {
- return value.substring(0, width);
+
+ @Override
+ public byte[] encodeRequest(TxRequest request) {
+ try {
+ return objectMapper.writeValueAsBytes(new RequestDto(
+ request.getServiceName(),
+ request.getPayload(),
+ request.getContext() != null ? request.getContext().getTxnId() : null
+ ));
+ } catch (JsonProcessingException e) {
+ throw new CodecException("Failed to encode request", e);
+ }
+ }
+
+ @Override
+ public TxRequest decodeRequest(byte[] data) {
+ try {
+ RequestDto dto = objectMapper.readValue(data, RequestDto.class);
+ return new TxRequest(dto.serviceName, dto.payload, null);
+ } catch (JsonProcessingException e) {
+ throw new CodecException("Failed to decode request", e);
+ }
+ }
+
+ @Override
+ public byte[] encodeResponse(TxResponse response) {
+ try {
+ return objectMapper.writeValueAsBytes(new ResponseDto(
+ response.getResult().name(),
+ response.getResult().getCode(),
+ response.getData(),
+ response.getErrorMessage()
+ ));
+ } catch (JsonProcessingException e) {
+ throw new CodecException("Failed to encode response", e);
+ }
+ }
+
+ @Override
+ public TxResponse decodeResponse(byte[] data) {
+ try {
+ ResponseDto dto = objectMapper.readValue(data, ResponseDto.class);
+ return new TxResponse(
+ TxCore.TxResult.fromCode(dto.resultCode),
+ dto.data,
+ dto.errorMessage
+ );
+ } catch (JsonProcessingException e) {
+ throw new CodecException("Failed to decode response", e);
+ }
+ }
+
+ @Override
+ public String getContentType() {
+ return "application/json";
+ }
+
+ public