본문 바로가기

STUDY/국비과정

[JAVA 웹 개발 공부] 국비지원 66일차 - API 자료 읽기, HTTP 요청 보내기, OkHttp, jsonschema2pojo, Jsoup, Jackson Dataformat CSV

API 자료 읽어오기

 

package kr.co.greenart.testjson;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class SimpleGet {
	public static void main(String[] args) {
		String apiURL = "https://myfakeapi.com/api/users/1";
		
		try {
			URL url = new URL(apiURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			
			if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
					StringBuilder sb = new StringBuilder();
					String line;
					while ((line = br.readLine()) != null) {
						sb.append(line);
					}
					System.out.println(sb.toString());
				}
			} else {
				System.out.println(conn.getResponseCode());
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
{
    "User":
    {"id":1,"first_name":"Alyosha","last_name":"Caldero","email":"acaldero0@behance.net",
    "gender":"Male","birthdate":"29/12/1997","company_name":"King and Sons",
    "department":"Sales","job_title":"Senior Editor","address":[{"street":"1 Hanson Terrace",
    "street_name":"Merrick","city":"Beaufort","state":"South Carolina","country":"United States",
    "country_code":"US","postal_code":"29905"}],"phone":"+7 (835) 885-9702",
    "avatar":"https://robohash.org/voluptasautmagni.png?size=180x180&set=set1",
    "email_verified":true,"password":"6707389d040d09a08ad2803846f30db544242f06","last_login":"Never",
    "last_login_ip":"239.243.71.212","subscribed":true}
}

 

 

GET 방식 vs POST 방식

 

GET방식과 POST방식은 HTTP 프로토콜을 이용해서 서버에 무언가를 전달할 때 사용하는 방식이다.

1. Get 방식
(1) 주로 데이터를 조회할 경우 사용(SELECT)
(2) URL에 데이터를 포함(길이제한 있음)
(3) 캐싱(한번 접근한 뒤 다음번 요청엔 더 빠르게 접근하기 위해 데이터를 저장해두는것) → Post방식보다 속도 빠름

2. Post 방식
(1) 주로 데이터를 추가, 수정할 경우 사용(INSERT, UPDATE, DELETE)
(2) URL에 데이터가 노출되지 않음
(3) 데이터를 Body에 포함(헤더 Content-Type 명시)

 

+) Content-Type
*application/x-www-form-urlencoded
*text/plain
*multipart/form-data

 

 

HTTP 요청 보내기

 

1. StringBuilder 이용

 

*GET 방식

package kr.co.greenart.testjson;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class SimpleGet {
	public static void main(String[] args) {
		String apiURL = "https://webhook.site/ca1a1c63-dab1-4346-a142-09ae7dabaffb?name=eunjin";
		
		try {
			URL url = new URL(apiURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			
			if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
					StringBuilder sb = new StringBuilder();
					String line;
					while ((line = br.readLine()) != null) {
						sb.append(line);
					}
					System.out.println(sb.toString());
				}
			} else {
				System.out.println(conn.getResponseCode());
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

*POST 방식

package kr.co.greenart.testjson;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class SimplePost {
	public static void main(String[] args) {
		String apiURL = "https://webhook.site/ca1a1c63-dab1-4346-a142-09ae7dabaffb";
		
		try {
			URL url = new URL(apiURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Content-Type", "text/plain; charset=utf8");
			conn.setDoOutput(true);
			
			try (PrintWriter pw = new PrintWriter(conn.getOutputStream())) {
				pw.println("Hello World. EunJin");
			}
			
			if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
					StringBuilder sb = new StringBuilder();
					String line;
					while ((line = br.readLine()) != null) {
						sb.append(line);
					}
					System.out.println(sb.toString());
				}
			} else {
				System.out.println(conn.getResponseCode());
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

 

2. ObjectMapper(JSON 형식 변환) 이용

 

*POST 방식

package kr.co.greenart.testjson;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;



public class SimplePost {
	public static void main(String[] args) {
		String apiURL = "https://webhook.site/ca1a1c63-dab1-4346-a142-09ae7dabaffb";
		
		try {
			URL url = new URL(apiURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Content-Type", "text/plain; charset=utf8");
			conn.setDoOutput(true);
			
			ObjectMapper mapper = new ObjectMapper();
			ObjectNode node = mapper.createObjectNode();
			node.put("name", "eunjin");
			node.put("message", "Hello. Message");
			
			try (PrintWriter pw = new PrintWriter(conn.getOutputStream())) {
				pw.println(mapper.writeValueAsString(node));
			}
			
			int code = conn.getResponseCode();
			System.out.println(code);
			if (code == HttpURLConnection.HTTP_OK) {
				try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
					StringBuilder sb = new StringBuilder();
					String line;
					while ((line = br.readLine()) != null) {
						sb.append(line);
					}
					System.out.println(sb.toString());
				}
			} else {
				System.out.println(conn.getResponseCode());
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

*GET 방식

package kr.co.greenart.testjson;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class SimpleGet2 {
	public static void main(String[] args) {
		String apiURL = "http://localhost:8080/web06/file/download?id=1";
		
		try {
			URL url = new URL(apiURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			
			int code = conn.getResponseCode();
			System.out.println(code);
			if (code == HttpURLConnection.HTTP_OK) {
				
				try (BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
						BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("save.png"))) {
					int b;
					while ((b = bis.read()) != -1) {
						bos.write(b);
					}
				}
			} 
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

 

OkHttp 라이브러리

 

OkHttp는 REST API, HTTP 통신을 간편하게 사용할 수 있도록 만들어진 자바 라이브러리다.

 

https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp/4.10.0

<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.10.0</version>
</dependency>

 

package kr.co.greenart.testjson;

import java.io.IOException;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class TestOkHttp {
	public static void main(String[] args) {
		OkHttpClient client = new OkHttpClient();
		Request request = new Request.Builder()
				.url("https://webhook.site/ca1a1c63-dab1-4346-a142-09ae7dabaffb")
				.build();
		
		try (Response resp = client.newCall(request).execute()) {
			System.out.println(resp.code());
			System.out.println(resp.headers());
			System.out.println(resp.body().string());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
200
Server: nginx
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Request-Id: 443e0b85-1e2c-43b3-8499-658a1e97f1a9
X-Token-Id: ca1a1c63-dab1-4346-a142-09ae7dabaffb
Cache-Control: no-cache, private
Date: Wed, 01 Feb 2023 02:45:37 GMT

hello~~~

 

+) API 연습

http://www.gimhae.go.kr/openapi/tour/restaurant.do

package kr.co.greenart.testjson;

import java.io.IOException;
import java.util.List;

import com.example.Example;
import com.example.Result;
import com.fasterxml.jackson.databind.ObjectMapper;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class TestOkHttp3 {
	public static void main(String[] args) {
		OkHttpClient client = new OkHttpClient();
		Request request = new Request.Builder()
				.url("http://www.gimhae.go.kr/openapi/tour/restaurant.do")
				.build();
		
		try (Response resp = client.newCall(request).execute()) {
			System.out.println(resp.code());
			System.out.println(resp.headers());
			String json = resp.body().string();
			
			ObjectMapper mapper = new ObjectMapper();
			Example example = mapper.readValue(json, Example.class);
			
			List<Result> list = example.getResults();
			System.out.println("김해시 추천 맛집 목록입니다.");
			for (Result r : list) {
				System.out.print(r.getName() + ":");
				System.out.println(r.getAddress());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

 

jsonschema2pojo

 

json 문자열을 이용해 POJO class 를 자동생성할 수 있다.

 

https://www.jsonschema2pojo.org/

 

jsonschema2pojo

Reference properties For each property present in the 'properties' definition, we add a property to a given Java class according to the JavaBeans spec. A private field is added to the parent class, along with accompanying accessor methods (getter and sette

www.jsonschema2pojo.org

 

@JsonIgnore : Response에 해당 필드가 제외된다.
@JsonProperty : Response에 해당 속성의 이름이 변경된다.

 

 

Jsoup Java HTML Parser 라이브러리

 

jsoup은 HTML 문서에 저장된 데이터를 구문 분석, 추출 및 조작하도록 설계된 오픈 소스 Java 라이브러리이다.

 

+) Parsing(파싱)
내가 원하는대로 데이터를 가공/변환하는 것이다.
HTML 파싱은 HTML 소스를 얻어온 후 내가 원하는 부분만 추출하는 목적으로 사용된다.

 

https://mvnrepository.com/artifact/org.jsoup/jsoup/1.15.3

<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.15.3</version>
</dependency>

 

package kr.co.greenart.testjson;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class Saramin {
	private static String getInfo(String link) throws IOException {
		String url = "https://www.saramin.co.kr";
		Document doc = Jsoup.connect(url + link).timeout(5000).get();
		String info = doc.select("meta[name=description]").first().attr("content");
		return info;
	}
	
	public static void main(String[] args) {
		String url = "https://www.saramin.co.kr/zf_user/search?searchType=search&searchword=java&company_cd=0%2C1%2C2%2C3%2C4%2C5%2C6%2C7%2C9%2C10&panel_type=&search_optional_item=y&search_done=y&panel_count=y&preview=y";
		
		try {
			Document doc = Jsoup.connect(url).timeout(5000).get();
			Elements elems = doc.select("a[href]");
			
			Set<String> links = new HashSet<>();
			
			for (Element e : elems) {
				String attr = e.attr("href");
				if (attr.startsWith("/zf_user/jobs/relay/view")) {
					links.add(attr);
				}
			}
			for (String l : links) {
				String info = getInfo(l);
				System.out.println(info);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

 

Jackson Dataformat CSV 라이브러리

 

Jackson 라이브러리를 사용하면 자바 객체에 담긴 내용을 Json 뿐만 아니라 CSV(Comma-Separated Values)로도 전환 할 수 있다. CSV는 엑셀로 파일을 바로 열어보려는 요구에서 주로 사용 되는데 자바 객체에 담긴 내용을 CSV로 전환하고 파일로 저장할 수 있다.

 

https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-csv/2.14.2

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-csv -->
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-csv</artifactId>
    <version>2.14.2</version>
</dependency>

 

*Person.java

package kr.co.greenart.testjson;

public class Person {
	private String name;
	private int age;
	
	public Person() {}
	
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

 

*CsvTest.java

package kr.co.greenart.testjson;

import java.io.File;
import java.io.IOException;
import java.util.List;

import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import com.fasterxml.jackson.dataformat.csv.CsvSchema.ColumnType;

public class CsvTest {
	public static void main(String[] args) throws IOException {
		CsvSchema schema = new CsvSchema.Builder()
				.addColumn("name", ColumnType.STRING)
				.addColumn("age", ColumnType.NUMBER)
				.build().withHeader();
				
		MappingIterator<Person> iter = new CsvMapper()
			.readerFor(Person.class)
			.with(schema)
			.readValues(new File("person.csv"));
		
		List<Person> list = iter.readAll();
		System.out.println(list);
	}
}