728x90
이번 포스팅에서는 Spring Boot를 이용하여 공공데이터포탈의 IP 정보 검색 API를 연동하는 방법을 소개하겠습니다. 최근 공공기관과 기업들은 다양한 공공데이터를 활용하여 부가가치를 창출하고 있으며, 특히 IP 주소에 대한 정보는 네트워크 보안과 관련된 다양한 서비스에 필수적입니다.
1. 프로젝트 개요
Spring Boot를 이용한 간단한 웹 애플리케이션을 구축하여, 공공데이터포탈에서 제공하는 IP 정보 검색 API를 통해 IP 주소의 세부 정보를 조회해 보겠습니다. 이를 통해 특정 IP가 어떤 기관에 할당되어 있는지, 해당 기관의 위치와 네트워크 정보를 쉽게 얻을 수 있습니다.
2. API 연동 준비
우선, 공공데이터포탈에서 API 키를 발급받아야 합니다. API 키는 공공데이터포탈 회원가입 후, 해당 API 서비스에서 발급받을 수 있습니다. 발급된 키를 통해 Spring Boot 프로젝트에서 IP 정보 검색 기능을 구현할 수 있습니다. 아래 사이트에 접속하여 활용신청을 진행하시면 됩니다.
https://www.data.go.kr/data/15094277/openapi.do
3. 구현 과정
- DTO 클래스 설계: API에서 제공되는 JSON 응답을 처리하기 위한 DTO(Data Transfer Object) 클래스를 정의합니다. Jackson 라이브러리를 활용해 JSON 데이터를 자동으로 객체화할 수 있도록 설계합니다.
- API 호출 및 데이터 매핑: RestTemplate을 사용하여 API 호출을 수행하고, 응답 데이터를 DTO에 매핑합니다. 이때 발생할 수 있는 오류를 처리하기 위해 예외 처리 로직도 함께 구현합니다.
- 결과 출력 및 화면 구성: 조회된 IP 정보를 사용자에게 보기 쉽게 제공하기 위해 Thymeleaf를 사용하여 웹 페이지를 구성합니다. IP 검색 결과는 표 형태로 정리하여 사용자가 직관적으로 이해할 수 있도록 디자인합니다.
4. 예제 소스
4.1. build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.3'
id 'io.spring.dependency-management' version '1.1.6'
}
group = 'com.whois'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
// lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
tasks.named('test') {
useJUnitPlatform()
}
4.2. application.yml
server:
port: 1234
whois:
api-key: #발급받은 API Key#
4.3. WhoisResponse.java
@Getter
@Setter
public class WhoisResponse {
@JsonProperty("response")
private Response response;
@Getter
@Setter
public static class Response {
@JsonProperty("result")
private Result result;
@JsonProperty("whois")
private Whois whois;
}
@Getter
@Setter
public static class Result {
@JsonProperty("result_code")
private String resultCode;
@JsonProperty("result_msg")
private String resultMsg;
}
@Getter
@Setter
public static class Whois {
@JsonProperty("query")
private String query;
@JsonProperty("queryType")
private String queryType;
@JsonProperty("registry")
private String registry;
@JsonProperty("countryCode")
private String countryCode;
@JsonProperty("korean")
private LanguageInfo korean;
@JsonProperty("english")
private LanguageInfo english;
}
@Getter
@Setter
public static class LanguageInfo {
@JsonProperty("ISP")
private Isp isp;
@JsonProperty("user")
private User user;
}
@Getter
@Setter
public static class Isp {
@JsonProperty("netinfo")
private NetInfo netinfo;
@JsonProperty("techContact")
private TechContact techContact;
}
@Getter
@Setter
public static class User {
@JsonProperty("netinfo")
private NetInfo netinfo;
@JsonProperty("techContact")
private TechContact techContact;
}
@Getter
@Setter
public static class NetInfo {
@JsonProperty("range")
private String range;
@JsonProperty("prefix")
private String prefix;
@JsonProperty("servName")
private String servName;
@JsonProperty("orgName")
private String orgName;
@JsonProperty("orgID")
private String orgID;
@JsonProperty("addr")
private String addr;
@JsonProperty("zipCode")
private String zipCode;
@JsonProperty("regDate")
private String regDate;
@JsonProperty("netType")
private String netType;
}
@Getter
@Setter
public static class TechContact {
@JsonProperty("name")
private String name;
@JsonProperty("phone")
private String phone;
@JsonProperty("email")
private String email;
}
}
4.4. WhoisController.java
@Controller
public class WhoisController {
@Value("${whois.api-key}")
private String apiKey;
private ObjectMapper objectMapper = new ObjectMapper();
@GetMapping(value = {"/", ""})
public String index(@RequestParam String query, Model model) throws Exception {
WhoisResponse response = null;
if (query != null && !query.isEmpty()) {
StringBuilder urlBuilder = new StringBuilder("http://apis.data.go.kr/B551505/whois/ip_address");
urlBuilder.append("?" + URLEncoder.encode("serviceKey", "UTF-8") + "=" + apiKey);
urlBuilder.append("&" + URLEncoder.encode("query", "UTF-8") + "=" + URLEncoder.encode(query, "UTF-8"));
urlBuilder.append("&" + URLEncoder.encode("answer", "UTF-8") + "=" + URLEncoder.encode("json", "UTF-8"));
URL url = new URL(urlBuilder.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "application/json");
BufferedReader rd;
if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
conn.disconnect();
response = objectMapper.readValue(sb.toString(), WhoisResponse.class);
}
model.addAttribute("whoisResponse", response);
return "index";
}
}
4.5. index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Whois Search</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
<h1 class="text-center">Whois Search</h1>
<!-- 검색 입력 필드 -->
<form th:action="@{/}" method="get" class="form-inline justify-content-center mb-4">
<input type="text" name="query" class="form-control mr-2" placeholder="IP 주소 입력" required>
<button type="submit" class="btn btn-primary">검색</button>
</form>
<!-- 검색 결과 표시 -->
<div th:if="${whoisResponse != null}">
<h2>검색 결과</h2>
<table class="table table-bordered">
<thead class="thead-dark">
<tr>
<th>필드</th>
<th>값</th>
</tr>
</thead>
<tbody>
<!-- Result 정보 -->
<tr>
<td>Result Code</td>
<td th:text="${whoisResponse.response.result.resultCode}"></td>
</tr>
<tr>
<td>Result Message</td>
<td th:text="${whoisResponse.response.result.resultMsg}"></td>
</tr>
<!-- Whois 정보 -->
<tr>
<td>Query</td>
<td th:text="${whoisResponse.response.whois.query}"></td>
</tr>
<tr>
<td>Query Type</td>
<td th:text="${whoisResponse.response.whois.queryType}"></td>
</tr>
<tr>
<td>Registry</td>
<td th:text="${whoisResponse.response.whois.registry}"></td>
</tr>
<tr>
<td>Country Code</td>
<td th:text="${whoisResponse.response.whois.countryCode}"></td>
</tr>
<!-- ISP 정보 -->
<tr>
<td>ISP Organization Name (Korean)</td>
<td th:text="${whoisResponse.response.whois.korean.isp.netinfo.orgName}"></td>
</tr>
<tr>
<td>ISP Address (Korean)</td>
<td th:text="${whoisResponse.response.whois.korean.isp.netinfo.addr}"></td>
</tr>
<tr>
<td>ISP Organization Name (English)</td>
<td th:text="${whoisResponse.response.whois.english.isp.netinfo.orgName}"></td>
</tr>
<tr>
<td>ISP Address (English)</td>
<td th:text="${whoisResponse.response.whois.english.isp.netinfo.addr}"></td>
</tr>
<!-- User 정보 -->
<tr>
<td>User Organization Name (Korean)</td>
<td th:text="${whoisResponse.response.whois.korean.user.netinfo.orgName}"></td>
</tr>
<tr>
<td>User Address (Korean)</td>
<td th:text="${whoisResponse.response.whois.korean.user.netinfo.addr}"></td>
</tr>
<tr>
<td>User Organization Name (English)</td>
<td th:text="${whoisResponse.response.whois.english.user.netinfo.orgName}"></td>
</tr>
<tr>
<td>User Address (English)</td>
<td th:text="${whoisResponse.response.whois.english.user.netinfo.addr}"></td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 부트스트랩 자바스크립트 라이브러리 -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
5. 실행화면
6. 마무리
이번 프로젝트를 통해 공공데이터포탈의 API를 활용하는 방법과 Spring Boot를 이용한 REST API 연동의 기본적인 과정을 배울 수 있었습니다. 공공데이터는 개발자에게 무한한 가능성을 제공하며, 이를 어떻게 활용하느냐에 따라 혁신적인 서비스가 만들어질 수 있습니다. 전체소스는 Github를 참고해 주세요.
감사합니다.
728x90
'프레임워크 > SpringBoot' 카테고리의 다른 글
[SpringBoot] JPA + Criteria를 이용한 Join 예제 (2) | 2024.09.23 |
---|---|
[SpringBoot] Apache Kafka 간단한 예제만들기 (0) | 2024.09.19 |
[SpringBoot] HATEOAS 개념 및 간단한 예제 (1) | 2024.08.28 |
[SpringBoot] openNLP를 이용해 고객센터 챗봇 만들기 (0) | 2024.08.20 |
[SpringBoot] 외장톰캣 배포 404 오류 (0) | 2024.08.08 |