본문 바로가기
language/java

🧾Zipher프로토콜 - java 유틸파일 2

by 죄니안죄니 2025. 4. 8.

 

// 📁 패키지 예시: com.example.zipher.protocol

// ✅ 응답 타입 정의 (Enum)
// 문자열 응답을 파싱해 명확한 타입으로 분류하기 위한 열거형입니다.
// 'ACK', 'ERR', 'STS|', 'GFT|'로 시작하는 응답을 매핑합니다.
public enum ResponseType {
    ACK, ERR, STS, GFT, UNKNOWN;

    public static ResponseType from(String response) {
        if (response == null) return UNKNOWN;
        if (response.equalsIgnoreCase("ACK")) return ACK;
        if (response.equalsIgnoreCase("ERR")) return ERR;
        if (response.startsWith("STS|")) return STS;
        if (response.startsWith("GFT|")) return GFT;
        return UNKNOWN;
    }
} 

// ✅ 응답 처리 전략 인터페이스
// 각 응답 타입별로 서로 다른 처리 로직을 구현할 수 있도록 하는 전략 패턴의 기반 인터페이스입니다.
public interface ZipherResponseHandler {
    void handle(String response);
}

// ✅ ACK 처리 핸들러
// 프린터가 명령을 정상적으로 처리한 경우의 응답을 처리합니다.
public class AckHandler implements ZipherResponseHandler {
    public void handle(String response) {
        System.out.println("✅ 명령어 성공 처리 (ACK)");
    }
}

// ✅ ERR 처리 핸들러
// 프린터가 명령을 처리하지 못했거나 오류가 발생했을 때의 응답을 처리합니다.
public class ErrHandler implements ZipherResponseHandler {
    public void handle(String response) {
        System.err.println("❌ 명령어 실패 처리 (ERR)");
    }
}

// ✅ STS 응답 핸들러
// 프린터 상태를 요청했을 때 반환되는 STS 응답을 해석합니다.
public class StatusHandler implements ZipherResponseHandler {
    public void handle(String response) {
        String[] parts = response.split("\\|");
        if (parts.length >= 6) {
            String statusCode = parts[1];
            String errorCode = parts[2];
            String jobName = parts[3];
            String batchCount = parts[4];
            String totalCount = parts[5];
            System.out.printf("📡 상태: %s, 에러: %s, 작업: %s, 인쇄 수량: %s/%s%n",
                    statusCode, errorCode, jobName, batchCount, totalCount);
        } else {
            System.err.println("❗ 상태 응답 포맷 오류: " + response);
        }
    }
}

// ✅ GFT 오류 응답 핸들러
// 프린터에 존재하는 경고/에러 상태를 파싱하여 출력합니다.
public class FaultHandler implements ZipherResponseHandler {
    public void handle(String response) {
        String[] parts = response.split("\\|");
        int count = Integer.parseInt(parts[1]);
        System.out.println("🛠️ 오류 수: " + count);
        for (int i = 0; i < count; i++) {
            int idx = 2 + i * 3;
            String code = parts[idx];
            String clearable = parts[idx + 1].equals("1") ? "사용자 클리어 가능" : "기기 클리어 필요";
            String msg = parts[idx + 2];
            System.out.printf("⚠️ [%s] %s (%s)%n", code, msg, clearable);
        }
    }
}

// ✅ 기본 핸들러 (예외 상황)
// 정의되지 않은 응답 유형에 대해 실행되는 기본 처리기입니다.
public class UnknownHandler implements ZipherResponseHandler {
    public void handle(String response) {
        System.err.println("❓ 알 수 없는 응답 유형: " + response);
    }
}

// ✅ Dispatcher 클래스
// 실제 응답 문자열을 받아서 응답 유형을 판단하고,
// 해당 유형에 맞는 Handler에게 위임하여 처리하는 중심 허브 역할을 합니다.
// 한 번만 static 초기화되므로 재사용성이 매우 높고, 어디서든 불러다 사용할 수 있습니다.
// Dispatcher는 일반적으로 하나만 만들어두고, 어플리케이션 전역에서 재사용하는 싱글톤 또는 static 구조로 운영됩니다.
import java.util.Map;

public class ZipherResponseDispatcher {
    private static final Map<ResponseType, ZipherResponseHandler> handlers = Map.of(
            ResponseType.ACK, new AckHandler(),
            ResponseType.ERR, new ErrHandler(),
            ResponseType.STS, new StatusHandler(),
            ResponseType.GFT, new FaultHandler(),
            ResponseType.UNKNOWN, new UnknownHandler()
    );

    /**
     * 문자열 응답을 받아서 해당하는 핸들러로 처리 위임
     */
    public static void dispatch(String response) {
        ResponseType type = ResponseType.from(response);
        handlers.getOrDefault(type, new UnknownHandler()).handle(response);
    }
}

📌 실제 사용 예시

// 명령 전송 → 응답 수신 → 자동 분기 처리
String response = zipherClient.sendCommand("SLA|WeightJob|label=한라봉\\r");
ZipherResponseDispatcher.dispatch(response);
  • 명령어를 전송한 뒤,
  • 응답을 문자열로 받고,
  • ZipherResponseDispatcher.dispatch(...)에 넘기면
  • 응답 유형에 따라 자동으로 해당 핸들러(AckHandler, StatusHandler 등)가 실행됩니다.

댓글