네이버에서 제공하는 API 중 검색 API 를 사용하는 방법을 정리했고, 네이버에서 예제로 제공하는 코드를 사용했습니다. json 형식으로결과를 가져와서 보여주는 부분을 추가하고 main 함수에서 호출하는 방법을 정리했습니다.
1. 네이버에 내 어플리케이션 등록
네이버 개발자 홈페이지에 들어갑니다.
그리고 메뉴바에서 Application>에플리케이션 등록을 누릅니다.
그리고 나서 프로젝트의 이름과 패키지 정보를 입력합니다.
등록하면 ClientId와 ClientSecret 코드를 줍니다.
2. 예제 코드
안드로이드 스튜디오에서 프로젝트를 열고 ApiExamSearchBlog라는 새로운 java class를 생성하고 예제 코드를 복붙합니다.
아래는 제가 예제 코드에서 약간 수정한 코드입니다.
parseData() 함수는 가져온 json 데이터에서 title만 출력하도록 했습니다.
public class ApiExamSearchBlog {
static public String clientId = "ClientId"; //애플리케이션 클라이언트 아이디값"
static public String clientSecret = "ClientSecret"; //애플리케이션 클라이언트 시크릿값"
public static void main() {
String text = null;
try {
text = URLEncoder.encode("그린팩토리", "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("검색어 인코딩 실패",e);
}
String apiURL = "https://openapi.naver.com/v1/search/blog?query=" + text; // json 결과
//String apiURL = "https://openapi.naver.com/v1/search/blog.xml?query="+ text; // xml 결과
Map<String, String> requestHeaders = new HashMap<>();
requestHeaders.put("X-Naver-Client-Id", clientId);
requestHeaders.put("X-Naver-Client-Secret", clientSecret);
String responseBody = get(apiURL,requestHeaders);
parseData(responseBody);
}
private static String get(String apiUrl, Map<String, String> requestHeaders){
HttpURLConnection con = connect(apiUrl);
try {
con.setRequestMethod("GET");
for(Map.Entry<String, String> header :requestHeaders.entrySet()) {
con.setRequestProperty(header.getKey(), header.getValue());
}
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // 정상 호출
return readBody(con.getInputStream());
} else { // 에러 발생
return readBody(con.getErrorStream());
}
} catch (IOException e) {
throw new RuntimeException("API 요청과 응답 실패", e);
} finally {
con.disconnect();
}
}
private static HttpURLConnection connect(String apiUrl){
try {
URL url = new URL(apiUrl);
return (HttpURLConnection)url.openConnection();
} catch (MalformedURLException e) {
throw new RuntimeException("API URL이 잘못되었습니다. : " + apiUrl, e);
} catch (IOException e) {
throw new RuntimeException("연결이 실패했습니다. : " + apiUrl, e);
}
}
private static String readBody(InputStream body){
InputStreamReader streamReader = new InputStreamReader(body);
try (BufferedReader lineReader = new BufferedReader(streamReader)) {
StringBuilder responseBody = new StringBuilder();
String line;
while ((line = lineReader.readLine()) != null) {
responseBody.append(line);
}
return responseBody.toString();
} catch (IOException e) {
throw new RuntimeException("API 응답을 읽는데 실패했습니다.", e);
}
}
private static void parseData(String responseBody) {
String title;
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(responseBody.toString());
JSONArray jsonArray = jsonObject.getJSONArray("items");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
title = item.getString("title");
System.out.println("TITLE : " + title);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
MainActivity.java에서는 다음과 같이 호출했습니다.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread thread = new Thread() {
public void run() {
ApiExamSearchBlog api = new ApiExamSearchBlog();
api.main();
}
};
thread.start();
}
}
Thread를 이용해서 호출해야합니다.
그렇지 않으면 android.os.NetworkOnMainThreadException 에러가 발생합니다.
실행했을 때 다음과 같이 결과가 나왔습니다.
3. Thread 상속
하지만 위 코드는 MainActivity.java에서 Thread를 호출하면서 코드가 길어지는 감이 있습니다.
그래서 저는 MainActivity 코드를 최소화(?) 하기 위해서 ApiExamSearchBlog가 Thread를 상속받도록 했습니다.
public class ApiExamSearchBlog extends Thread{
static public String clientId = "UCAOoacZwjeanj2X67eu"; //애플리케이션 클라이언트 아이디값"
static public String clientSecret = "2UC_M1_IfP"; //애플리케이션 클라이언트 시크릿값"
public void run(){
main();
}
public static void main() {
String text = null;
try {
text = URLEncoder.encode("그린팩토리", "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("검색어 인코딩 실패",e);
}
String apiURL = "https://openapi.naver.com/v1/search/blog?query=" + text; // json 결과
//String apiURL = "https://openapi.naver.com/v1/search/blog.xml?query="+ text; // xml 결과
Map<String, String> requestHeaders = new HashMap<>();
requestHeaders.put("X-Naver-Client-Id", clientId);
requestHeaders.put("X-Naver-Client-Secret", clientSecret);
String responseBody = get(apiURL,requestHeaders);
parseData(responseBody);
}
private static String get(String apiUrl, Map<String, String> requestHeaders){
HttpURLConnection con = connect(apiUrl);
try {
con.setRequestMethod("GET");
for(Map.Entry<String, String> header :requestHeaders.entrySet()) {
con.setRequestProperty(header.getKey(), header.getValue());
}
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // 정상 호출
return readBody(con.getInputStream());
} else { // 에러 발생
return readBody(con.getErrorStream());
}
} catch (IOException e) {
throw new RuntimeException("API 요청과 응답 실패", e);
} finally {
con.disconnect();
}
}
private static HttpURLConnection connect(String apiUrl){
try {
URL url = new URL(apiUrl);
return (HttpURLConnection)url.openConnection();
} catch (MalformedURLException e) {
throw new RuntimeException("API URL이 잘못되었습니다. : " + apiUrl, e);
} catch (IOException e) {
throw new RuntimeException("연결이 실패했습니다. : " + apiUrl, e);
}
}
private static String readBody(InputStream body){
InputStreamReader streamReader = new InputStreamReader(body);
try (BufferedReader lineReader = new BufferedReader(streamReader)) {
StringBuilder responseBody = new StringBuilder();
String line;
while ((line = lineReader.readLine()) != null) {
responseBody.append(line);
}
return responseBody.toString();
} catch (IOException e) {
throw new RuntimeException("API 응답을 읽는데 실패했습니다.", e);
}
}
private static void parseData(String responseBody) {
String title;
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(responseBody.toString());
JSONArray jsonArray = jsonObject.getJSONArray("items");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
title = item.getString("title");
System.out.println("TITLE : " + title);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
그리고 MainActivity.java에서는 아래와 같이 호출하면 됩니다.
Thread thread = new ApiExamSearchBlog();
thread.start();
요새 코드를 짧게 짜는 방법, 함수화, 추상화 관련해서 공부하고 있습니다.
분명 수업 때 들은 내용도 다시 공부하니 처음 들은 것 같고 어렵네요.
개발은 끊임없이 공부해야 하는걸 다시금 느끼고 있습니다;ㅅ;
잘못된 내용이 있다면 언제든지 댓글이나 메일로 알려주시면 감사하겠습니다.
이 포스팅이 도움이 되었다면 공감 부탁드립니다.
궁금한 점은 언제든지 댓글 남겨주시면 답변해드리겠습니다:D
'major > Android' 카테고리의 다른 글
[Kotlin] 액티비티 전환하기 - intent, putExtra (0) | 2020.03.23 |
---|---|
[Android] Firebase Database 사용하기 (1) | 2020.03.21 |
[Android] Fragment 구현 (0) | 2020.03.20 |
구글 플레이에 앱 출시하기, 게시 보류 (0) | 2020.03.20 |
[JAVA] Calendar 사용법 정리 (0) | 2020.03.18 |