Java 문자 발송 API 예제
JDK에 기본 포함된 HttpURLConnection 으로 센드엠 문자 발송 API를 호출하는 예제입니다. 별도 SDK가 필요 없습니다.
별도 SDK 없이 표준 HTTP 호출만으로 동작합니다.
적용 버전 「센드엠 API 연동정의서 v3.1」 · 작성 센드엠 고객지원팀 · 작성일 2026년 9월 16일 · 최종 수정 2026년 10월 21일
Java에서 문자를 어떻게 보내나요?
https://api.sendm.co.kr/v1/sms/send 에 POST 로 JSON을 보내고, 요청 헤더에 user-id 와 api-key 를 넣으면 됩니다. 응답 JSON의 code 가 "0" 이면 접수 성공입니다.
표준 HTTP 호출이라 HttpURLConnection, Apache HttpClient, OkHttp, Spring RestTemplate·WebClient 중 무엇을 써도 됩니다. 아래는 의존성이 가장 적은 HttpURLConnection 방식입니다.
실행 환경
| 구분 | 사용 | 검증 |
|---|---|---|
| 런타임 | JDK 8 이상 | 2026-09-16 실행 확인 |
| HTTP | JDK 기본 HttpURLConnection | 2026-09-16 실행 확인 |
| JSON | Gson 2.8.6 이상 (JsonParser.parseString 사용) | 2026-09-16 실행 확인 |
문자 요청 예제 단문(SMS) 전체 코드
예시 값을 실제 발신번호·수신번호·인증키로 바꿔 고객님 서버에서 실행하세요.
SendmClient.java
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class SendmClient {
private static final String API_URL = "https://api.sendm.co.kr/v1/sms/send";
/* 소스에 직접 쓰지 말고 환경변수나 설정파일에서 읽으세요. */
private static final String USER_ID = System.getenv("SENDM_USER_ID");
private static final String API_KEY = System.getenv("SENDM_API_KEY");
public String sendSms(String callerNo, String receiveNos, String message) throws Exception {
JsonObject body = new JsonObject();
body.addProperty("callerNo", callerNo); // 등록·승인된 발신번호
body.addProperty("receiveNos", receiveNos); // 여러 건은 # 로 구분
body.addProperty("message", message);
// body.addProperty("smsType", "LMS"); // 장문이면 추가
// body.addProperty("title", "제목"); // 장문 제목
// body.addProperty("adYn", "Y"); // 광고문자면 Y
byte[] payload = new Gson().toJson(body).getBytes(StandardCharsets.UTF_8);
HttpURLConnection conn = (HttpURLConnection) new URL(API_URL).openConnection();
try {
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setRequestProperty("user-id", USER_ID);
conn.setRequestProperty("api-key", API_KEY);
conn.setConnectTimeout(5000);
conn.setReadTimeout(30000);
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
os.write(payload);
}
int status = conn.getResponseCode();
/* 실패(4xx·5xx)일 때 getInputStream() 을 부르면 IOException 이 난다.
반드시 getErrorStream() 으로 읽어야 실패 사유를 볼 수 있다. */
InputStream in = (status == 200) ? conn.getInputStream() : conn.getErrorStream();
StringBuilder sb = new StringBuilder();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(in, StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
}
return sb.toString();
} finally {
conn.disconnect();
}
}
}
호출과 결과 판정
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
String raw = new SendmClient().sendSms(
"02-0000-0000", // 발신번호
"010-0000-0001#010-0000-0002", // 수신번호 (# 구분)
"주문이 접수되었습니다.");
JsonObject res = JsonParser.parseString(raw).getAsJsonObject();
if ("0".equals(res.get("code").getAsString())) {
long msgId = res.getAsJsonObject("data").get("msgId").getAsLong();
// msgId 를 저장해 두면 나중에 발송 결과를 조회할 수 있다
System.out.println("발송 접수 완료. msgId=" + msgId);
} else {
System.out.println("발송 실패 [" + res.get("code").getAsString() + "] "
+ res.get("message").getAsString());
}
code 는 숫자가 아니라 문자열 "0" 입니다. == 0 으로 비교하지 마세요.
발송 결과 조회와 잔여 건수
조회 API는 모두 GET 이며, 발송과 같은 인증 헤더를 넣으면 됩니다.
GET 호출 공통 함수
public String get(String url) throws Exception {
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
try {
conn.setRequestMethod("GET");
conn.setRequestProperty("user-id", USER_ID);
conn.setRequestProperty("api-key", API_KEY);
conn.setConnectTimeout(5000);
conn.setReadTimeout(30000);
int status = conn.getResponseCode();
InputStream in = (status == 200) ? conn.getInputStream() : conn.getErrorStream();
StringBuilder sb = new StringBuilder();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(in, StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
}
return sb.toString();
} finally {
conn.disconnect();
}
}
// 잔여 코인·발송 가능 건수
get("https://api.sendm.co.kr/v2/info/coinInfo");
// 발송 상세 결과 (수신자별 resultCd 포함)
get("https://api.sendm.co.kr/v1/sms/sendList/" + msgId);
// 예약 발송 취소
get("https://api.sendm.co.kr/v1/sms/cancel/" + msgId);
waitCnt 가 최대 48시간 남을 수 있습니다. 발송 루프 안에서 즉시 조회하지 말고 배치나 스케줄러로 분리하세요.
제한과 주의
GET /v1/sms/sendList)으로 접수 여부를 먼저 확인하고, 접수되지 않은 건만 다시 보냅니다.
- 응답
code가"0"이면 접수입니다. 수신 성공은 결과 조회로 따로 확인합니다. - 예약 발송의
sendDate는 호출 시점 기준으로 계산하세요. 예시 날짜를 그대로 복사하면 지난 시각이 됩니다. - 인증키는 서버 환경변수에서 읽고 저장소에 커밋하지 마세요.
- 광고문자는
adYn=Y로 보내며 야간(21시~08시) 발송 제한이 적용됩니다.
자주 막히는 문제와 해결
| 증상 | 원인 | 해결 |
|---|---|---|
| 한글이 깨져서 도착 | 요청 본문을 기본 인코딩으로 전송 | getBytes(StandardCharsets.UTF_8) 로 보내고 Content-Type 에 charset=UTF-8 명시 |
| 실패인데 예외만 남고 사유를 모름 | 4xx·5xx 응답에서 getInputStream() 호출 |
상태코드가 200이 아니면 getErrorStream() 으로 읽기 |
| 권한 없음으로 차단 | 호출 서버 IP가 미등록 | API 설정에서 발송 IP 등록. 서버 증설·이전 시 다시 등록 |
| 발신번호 오류 | callerNo 가 미등록·미승인 번호 |
발신번호 등록 후 사용 |
| 야간에만 실패 | 야간 발송 제한(21시~08시) | reserveYn=Y 와 sendDate 로 예약 전환 |
이 글에서 답한 질문
Java에서는 어떤 HTTP 라이브러리를 써야 하나요?
표준 HTTP 호출이라 HttpURLConnection, Apache HttpClient, OkHttp, Spring RestTemplate·WebClient 중 무엇을 써도 됩니다. 이 글의 예제는 의존성이 가장 적은 HttpURLConnection 방식(JDK 8 이상)입니다.
한글이 깨져서 도착하면 어떻게 하나요?
요청 본문을 기본 인코딩으로 보내서 생기는 문제입니다. getBytes(StandardCharsets.UTF_8)로 보내고 Content-Type에 charset=UTF-8을 적으세요.
권한 없음으로 차단되면 무엇을 확인하나요?
호출하는 서버의 IP가 등록되지 않은 경우입니다. API 설정에서 발송 IP를 등록하고, 서버를 늘리거나 옮기면 다시 등록하세요.
다음 단계
최종 업데이트 : 2026년 10월 21일 · 「센드엠 API 연동정의서 v3.1」 기준