[Spring Boot] AWS SNS 연동 및 Webhook.site 활용 메시지 발송 테스트

2026. 6. 5. 23:01·Backend/Spring
728x90

 

안녕하세요. 지난 포스팅에서 AWS 콘솔을 통해 SNS 주제를 만들고 IAM 자격 증명을 발급받았는데요.

[AWS] Amazon SNS 주제 생성 및 IAM 사용자 액세스 키 발급 가이드

 

[AWS] Amazon SNS 주제 생성 및 IAM 사용자 액세스 키 발급 가이드

안녕하세요. 마이크로서비스나 서버리스 애플리케이션에서 메시지 게시/구독을 담당하는 Amazon SNS(Simple Notification Service) 주제(Topic)를 생성하고, 이를 외부 애플리케이션(ex. Spring Boot, Node.js 등)에

0206cho.tistory.com

 

이번에는 Spring Boot 애플리케이션에 AWS SDK V2를 연동하여 토픽 생성, 구독 등록, 메시지 발행(Publish) API를 구현해 보겠습니다.

 

특히, 외부 수신처 서버가 없어도 HTTP 기반의 웹훅 알림을 완벽하게 모니터링하고 테스트할 수 있는 Webhook.site 활용법까지 함께 다뤄보겠습니다.

 

1. Webhook.site란

테스트를 진행하기 전, 오늘 구독 엔드포인트로 사용할 Webhook.site에 대해 간단히 설명하겠습니다.

  • 개념: 외부 시스템(ex. AWS SNS, GitHub 등)에서 보내는 HTTP POST 요청(웹훅)을 실시간으로 캡처하여 화면에 보여주는 무료 테스트 도구입니다.
  • 사용 이유: SNS의 https 프로토콜 구독을 테스트하려면 공인 IP와 도메인을 가진 수신용 웹 서버가 필요합니다. 하지만 Webhook.site를 사용하면 별도의 서버 구축이나 로컬 터널링(ngrok 등) 없이도 AWS가 던지는 알림 본문을 실시간으로 디버깅할 수 있어 매우 편리합니다.

 

2. Spring Boot 의존성 및 설정 (application.properties)

1) 의존성 추가 (build.gradle)

AWS SDK Java V2의 SNS 라이브러리와 Spring Cloud AWS 메시징 모듈을 추가합니다.

// AWS SDK V2 SNS
implementation 'software.amazon.awssdk:sns'
implementation platform('software.amazon.awssdk:bom:2.5.29')

// Spring Cloud AWS (컴파일 환경 설정용)
compileOnly group: 'org.springframework.cloud', name: 'spring-cloud-aws-messaging', version: '2.2.1.RELEASE'
compileOnly group: 'org.springframework.cloud', name: 'spring-cloud-aws-autoconfigure', version: '2.2.1.RELEASE'

 

2) 환경 설정 (application.properties)

지난 시간에 발급받은 IAM 액세스 키와 기본 리전 정보를 기입합니다.

Amazon SNS 주제 생성 및 IAM 사용자 액세스 키 발급 가이드

 

[AWS] Amazon SNS 주제 생성 및 IAM 사용자 액세스 키 발급 가이드

안녕하세요. 마이크로서비스나 서버리스 애플리케이션에서 메시지 게시/구독을 담당하는 Amazon SNS(Simple Notification Service) 주제(Topic)를 생성하고, 이를 외부 애플리케이션(ex. Spring Boot, Node.js 등)에

0206cho.tistory.com

# AWS SNS Configuration
sns.topic.arn=arn:aws:sns:ap-northeast-2:123456789012:TestTopic
aws.accessKey=YOUR_IAM_ACCESS_KEY_ID
aws.secretKey=YOUR_IAM_SECRET_ACCESS_KEY
aws.region=ap-northeast-2
cloud.aws.region.static=ap-northeast-2
cloud.aws.stack.auto=false

 

3. Java 소스코드 구현

1) AWSConfig.java 프로퍼티 바인딩

@Getter
@Configuration
public class AWSConfig {

    @Value("${sns.topic.arn}")
    private String snsTopicARN;

    @Value("${aws.accessKey}")
    private String awsAccessKey;

    @Value("${aws.secretKey}")
    private String awsSecretKey;

    @Value("${aws.region}")
    private String awsRegion;
}

 

2) SnsService.java - SnsClient 자격 증명 및 빌드

AWS SDK V2 스펙에 맞게 AwsCredentialsProvider를 구동하고, 인프라 통신을 전담할 SnsClient 빈을 관리하는 레이어입니다.

// AWS SNS(Simple Notification Service) 클라이언트 생성 및 인증 관리

@Service
public class SnsService {

    AWSConfig awsConfig;

    public SnsService(AWSConfig awsConfig) {
        this.awsConfig = awsConfig;
    }

    /**
     * AWS 서비스들에 접근할 수 있는 '신분증(자격 증명 공급자)'을 발급하는 메서드
     * @param accessKeyID
     * @param secretAccessKey
     * @return
     */
    public AwsCredentialsProvider getAwsCredentials(String accessKeyID, String secretAccessKey) {
        // 전달받은 Access Key와 Secret Key쌍을 조합하여 기본 자격 증명 객체 생성
        AwsBasicCredentials awsBasicCredentials = AwsBasicCredentials.create(accessKeyID, secretAccessKey);

        // AwsCredentialsProvider 인터페이스의 요구 메서드를 구현해 반환
        // () -> awsBasicCredentials : "인증서 필요할 때 방금 만든 이 키 세트를 넘겨줘"
        return () -> awsBasicCredentials;
    }

    /**
     * 실제 알림(SMS, 푸시 등)을 요청할 때 사용하는 AWS SNS 통신용 클라이언트 객체를 빌드
     * @return
     */
    public SnsClient getSnsClient() {
        // AWS SDK의 SnsClient 빌더 패턴을 사용하여 클라이언트를 조립
        return SnsClient.builder()
                // getAwsCredentials 메서드를 호출하여 AWSConfig에 들어있는 키 정보로 인증을 설정
                .credentialsProvider(
                        getAwsCredentials(awsConfig.getAwsAccessKey(), awsConfig.getAwsSecretKey())
                )
                // AWSConfig에 설정된 리전 정보를 기반으로 서비스 지역을 지정
                .region(Region.of(awsConfig.getAwsRegion()))
                // 설정을 마친 최종 SnsClient 인스턴스를 생성(build)하여 반환
                .build();
    }
}

 

3) SnsController.java - REST API 엔드포인트 구현

토픽 생성, 구독 등록, 메시지 발송 요청을 처리하는 컨트롤러입니다. 리소스 관리를 위해 사용 후 snsClient.close()를 잊지 않고 호출해 줍니다.

@Log4j2
@RestController
public class SnsController {

    private final AWSConfig awsConfig;
    private final SnsService snsService;

    public SnsController(AWSConfig awsConfig, SnsService snsService) {
        this.awsConfig = awsConfig;
        this.snsService = snsService;
    }

    /**
     * AWS SNS 토픽 생성 API
     * /create-topic?topicName=이름
     * @param topicName
     * @return
     */
    @PostMapping("/create-topic")
    public ResponseEntity<String> createTopic(@RequestParam final String topicName) {
        // AWS SDK 빌더를 이용해 지정한 이름으로 토픽 생성 요청 객체 빌드
        final CreateTopicRequest createTopicRequest = CreateTopicRequest.builder()
                .name(topicName)
                .build();

        // AWS 통신용 SnsClient를 얻어옴
        SnsClient snsClient = snsService.getSnsClient();

        // AWS 실제 서버에 토픽 생성을 요청하고 결과 응답을 받음
        final CreateTopicResponse createTopicResponse = snsClient.createTopic(createTopicRequest);

        // AWS 통신 결과가 성공이 아니라면 에러 응답 예외를 발생
        if (!createTopicResponse.sdkHttpResponse().isSuccessful()) {
            throw getResponseStatusException(createTopicResponse);
        }

        // 로그에 생성된 토픽의 고유 주소(ARN)와 전체 토픽 목록을 출력
        log.info("topic name = " + createTopicResponse.topicArn());
        log.info("topic list = " + snsClient.listTopics());

        snsClient.close();

        return new ResponseEntity<>("TOPIC CREATING SUCCESS", HttpStatus.OK);
    }

    /**
     * AWS SNS 토픽 구독 등록 API
     * 특정 토픽에 알림을 받아볼 수신처를 연결하는 기능
     * /subscribe?endpoint=주소&topicArn=토픽고유주소
     * @param endpoint  알림을 받아볼 목적지 주소 (이메일 주소, HTTP URL 등)
     * @param topicArn  구독할 대상 AWS SNS 토픽의 고유 주소
     */
    @PostMapping("/subscribe")
    public ResponseEntity<String> subscribe(@RequestParam final String endpoint, @RequestParam final String topicArn) {
        // 구독 요청 객체를 빌드
        final SubscribeRequest subscribeRequest = SubscribeRequest.builder()
                .protocol("https")
                .topicArn(topicArn)
                .endpoint(endpoint)
                .build();

        SnsClient snsClient = snsService.getSnsClient();

        // AWS SNS에 구독 처리 요청
        final SubscribeResponse subscribeResponse = snsClient.subscribe(subscribeRequest);

        // HTTP 응답 코드가 성공이 아니면 예외를 발생
        if (!subscribeResponse.sdkHttpResponse().isSuccessful()) {
            throw getResponseStatusException(subscribeResponse);
        }

        // 로그에 생성된 구독 고유 번호(Subscription ARN)와 전체 구독 리스트를 출력
        log.info("topicARN to subscribe = " + subscribeResponse.subscriptionArn());
        log.info("subscription list = " + snsClient.listSubscriptions());

        snsClient.close(); // 자원 해제
        return new ResponseEntity<>("TOPIC SUBSCRIBE SUCCESS", HttpStatus.OK);
    }

    /**
     * AWS SNS 메시지 발행(전송) API
     * 특정 토픽을 구독하고 있는 모든 수신처(HTTPS Endpoint, 이메일 등)에 메시지를 일괄 뿌리는 기능\
     * /publish?topicArn=토픽고유주소
     * @param topicArn  메시지를 보낼 타겟 토픽 고유 주소
     * @param message   보낼 내용 (JSON 바디 맵 구조)
     */
    @PostMapping("/publish")
    public String publish(@RequestParam String topicArn, @RequestBody Map<String, Object> message) {
        SnsClient snsClient = snsService.getSnsClient();

        // 발송할 제목과 본문(Map을 문자열로 변환)을 담아 발행 요청 객체 빌드
        final PublishRequest publishRequest = PublishRequest.builder()
                .topicArn(topicArn)
                .subject("HTTP ENDPOINT TEST MESSAGE") // 알림 메일/푸시의 제목 영역
                .message(message.toString())           // 알림 본문 영역
                .build();

        // AWS SNS 서버를 통해 메시지를 전송
        PublishResponse publishResponse = snsClient.publish(publishRequest);

        // 전송 결과의 HTTP 상태 코드를 로그에 남김
        log.info("message status:" + publishResponse.sdkHttpResponse().statusCode());

        snsClient.close(); // 자원 해제

        // 발송 성공 시 AWS가 부여한 고유 메시지 ID를 반환
        return "sent MSG ID = " + publishResponse.messageId();
    }

    /**
     * AWS 통신 실패 시 내부 HTTP 에러(500 Internal Server Error) 예외 객체를 조립
     */
    private ResponseStatusException getResponseStatusException(SnsResponse response) {
        return new ResponseStatusException(
                HttpStatus.INTERNAL_SERVER_ERROR, response.sdkHttpResponse().statusText().get()
        );
    }
}

 

 

4. Postman & Webhook.site 실전 테스트

코드를 모두 구동했다면 포스트맨과 웹훅 사이트를 띄워 아래 순서대로 연동을 검증합니다.

 

1) 신규 토픽 생성 요청

포스트맨을 열어 localhost:8080/create-topic?topicName=board-server 로 POST 요청을 보냅니다.

  • 결과: 바디에 TOPIC CREATING SUCCESS 응답이 떨어집니다.

  • AWS 콘솔 확인: AWS SNS 콘솔의 주제 목록에 board-server라는 신규 표준 토픽이 정상적으로 등록되었으며, 고유 고유 ARN 주소가 발급된 것을 볼 수 있습니다.

 

2) 수신용 가상 앤드포인트 URL 발급 (Webhook.site)

Webhook.site에 접속하면 가입 없이 즉시 고유한 가상 URL이 발급됩니다.

  • 화면 중앙 Your unique URL 란에 표시된 주소([https://webhook.site/](https://webhook.site/)...)를 복사합니다.

 

3) 해당 URL로 SNS 토픽 구독(Subscribe) 요청

다시 포스트맨으로 돌아와 구독 등록 API를 호출합니다.

  • 요청 주소: localhost:8080/subscribe
  • 파라미터: endpoint에는 방금 복사한 웹훅 주소를, topicArn에는 1)에서 생성된 AWS 토픽 ARN 주소를 넣고 POST 전송합니다 
  • 결과: 성공적으로 대기 상태의 구독이 맺어집니다.

 

4) 구독 확인 인증 처리

AWS SNS는 HTTPS 엔드포인트 도메인의 소유권을 확인하기 위해, 최초 구독 시 해당 주소로 구독 확인 메세지를 보냅니다.

  • Webhook.site 화면을 보면 왼쪽에 POST 요청이 들어와 있는 것을 볼 수 있습니다.
  • 우측 본문(Raw Content) JSON 내용 내부를 보면 SubscribeURL 항목이 존재합니다.

  • 이 SubscribeURL 주소를 전체 복사하여 브라우저 새 창에 주소창 입력 후 엔터를 쳐서 접속해 줍니다.

  • 화면에 XML 결과가 나오며 AWS SNS 콘솔 상에서 구독 상태가 최종 '확인됨'으로 활성화됩니다.

 

5) 최종 메시지 발행 및 결과 확인

이제 연동이 완료되었으니 실전 데이터를 쏴보겠습니다.

  • 포스트맨에서 localhost:8080/publish?topicArn=토픽ARN 으로 요청을 보냅니다
  • Body (JSON): 전송할 로그나 메시지 포맷을 세팅합니다.

  • 최종 검증: Webhook.site 실시간 대시보드에 두 번째 `POST` 알림이 팝업됩니다. 상세 로그의 `Message` 필드를 확인하면, 우리가 Spring Boot에서 보낸 맵 형태의 문자열 본문(`{message=모니터링을 위한 알림입니다., number=1}`)이 정상적으로 인입된 것을 확인할 수 있습니다 .

 

 

이로써 Spring Boot 백엔드 애플리케이션 환경에서 AWS SDK V2를 활용해 SNS 채널 파이프라인을 제어하고, Webhook.site 도구로 수신부 아키텍처 디버깅까지 마쳤습니다. 이 구조를 확장하면 서버 내 치명적인 예외(Error) 발생 시 관리자 이메일/Slack 웹훅 등으로 실시간 알림 시스템을 유연하게 구축할 수 있습니다.

 

다음 글에서는 슬랙 모니터링 에러 알림 테스트 API를 만들어보겠습니다. 오늘도 끝까지 읽어주셔서 감사합니다!

Slack API 연동하여 모니터링 에러 알림 테스트

 

[Spring Boot] Slack API 연동하여 모니터링 에러 알림 테스트

안녕하세요! 개발을 하다 보면 서버에서 발생하는 에러나 중요한 경고 시스템 로그를 실시간으로 모니터링해야 하는 순간이 찾아옵니다. 오늘은 저번 AWS API에 이어,AWS SNS 연동 및 Webhook.site 활용

0206cho.tistory.com

 

728x90

'Backend > Spring' 카테고리의 다른 글

[Spring] eGovFramework 환경에서 구글 SMTP 연동 및 첨부파일 메일 보내기  (0) 2026.06.11
[Spring Boot] Slack API 연동하여 모니터링 에러 알림 테스트  (1) 2026.06.09
[Spring AI] 로컬 LLM과 Redis를 활용한 나만의 RAG 시스템 구축 가이드  (0) 2026.05.10
[Spring] 전자정부프레임워크 crpto DB정보 globals.properties 암호화  (0) 2026.01.29
[Spring] WebFlux 초기 설정  (0) 2024.11.18
'Backend/Spring' 카테고리의 다른 글
  • [Spring] eGovFramework 환경에서 구글 SMTP 연동 및 첨부파일 메일 보내기
  • [Spring Boot] Slack API 연동하여 모니터링 에러 알림 테스트
  • [Spring AI] 로컬 LLM과 Redis를 활용한 나만의 RAG 시스템 구축 가이드
  • [Spring] 전자정부프레임워크 crpto DB정보 globals.properties 암호화
min_sol
min_sol
  • min_sol
    비글개발연구소🐾
    min_sol
  • 전체
    오늘
    어제
    • 분류 전체보기 (291)
      • Programming (132)
        • Algorithm (56)
        • JAVA (40)
        • GIS (5)
        • PyQt (10)
        • C# (11)
        • Mobile (6)
        • AI (4)
      • Backend (41)
        • Spring (19)
        • JSP (11)
        • Network (5)
      • Frontend (30)
        • Nexacro (1)
        • React (11)
        • Vue (13)
        • Next.js (4)
      • Database (11)
        • PostgreSQL (1)
        • Oracle (8)
        • Elasticsearch (1)
      • DevOps (10)
        • Linux (7)
        • Mac (1)
        • AWS (1)
      • Tools (32)
        • IntelliJ (1)
        • VSCode (1)
        • GitHub (10)
        • RPA (20)
      • Security (9)
      • etc (22)
        • ERROR (5)
        • 세미나 | 교육 (11)
        • 자격증 (1)
        • 일상 (2)
        • 2021 (2)
  • 인기 글

  • 태그

    스윙
    이클립스
    연습문제
    백준
    명품자바에센셜
    알고리즘
    자동화
    계산기
    코딩테스트
    jsp
    자바
    VUE
    vue.js
    Java
    RPA
    spring
    생능출판
    자료구조
    PyQt
    PyQt5
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
min_sol
[Spring Boot] AWS SNS 연동 및 Webhook.site 활용 메시지 발송 테스트
상단으로

티스토리툴바