** JSON Parsing
1. JSON(JavaScript Object Notation)
- 자바스크립트 데이터 표현식으로 데이터를 표현하는 포맷
- 기존에 사용하던 XML 보다는 파싱이 쉽고 가볍습니다.
- 사람이 알아보기에는 XML 보다는 어렵습니다.
- 표현법
1) 배열 : []
2) 객체 : {}
3) 속성 ; {속성:데이터}
2. JSON Parsing
- 기본 Java API 만으로는 안 되고 외부 라이브러리를 사용해야 합니다.
- www.mvnrepository.com/ 에서 JSON 라이브러리를 검색해서 다운로드 받아서 사용
1) JSONArrary 클래스
- JSON 배열을 저장하기 위한 클래스
- new JSONArray(json 배열 문자열) 로 생성
- 배열 안의 데이터는 get자료형(인덱스) 를 이용해서 가져옵니다.
2) JSONObject 클래스
- JSON 객체를 저장하기 위한 클래스
- new JSONObject(json 객체 문자열) 로 생성
- 객체 안의 데이터는 get자료형(속성이름)을 이용해서 가져옵니다.
** 웹에서 문자열 다운로드
1. 다운로드 받을 URL 문자열을 이용해서 java.net.URL 클래스의 인스턴스를 만들어야 합니다.
2. URL 클래스의 인스턴스를 이용해서 HttpURLConnection 인스턴스를 만들어야 합니다.
- (HttpURLConnection)URL인스턴스.openConnection()
3. HttpURLConnection 인스턴스의 메소드들을 호출해서 옵션을 설정합니다.
4. HttpURLConnection 에서 데이터를 줄 단위로 읽어올 수 있는 BufferedReader 인스턴스를 생성합니다.
- new BufferedReader(new InputStreamReader(URLConnection인스턴스.getInputStream()))
5. BufferedReader 객체를 이용해서 줄 단위로 읽어서 하나의 문자열 만들기
- StringBuilder sb = new StringBuilder();
- while(true){
- String line = BufferedReader인스턴스.readLine();
- if(line==null)break;
- sb.append(line);}
- String 변수 = sb.toString();
6. 웹에서 문자열을 다운로드 받는 작업은 일반 연산에 비해 오래 걸리는 작업입니다. 이런 작업을 동기적(순서대로)으로 수행하게 되면 작업이 종료할 때까지 다른 작업을 못하기 때문에 비동기적으로 수행할 수 있도록 스레드를 이용하는 것이 바람직합니다.
** 실습 : 다음 책 검색 API 주소인 http://apis.daum.net/search/book?apikey=465b06fae32febacbc59502598dd7685&output=json&q=java 에서 author 값만 추출하기
package opensource; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import org.json.JSONArray; import org.json.JSONObject; public class JSONParsing { public static void main(String[] args) { //!--다운로드 받을 문자열을 저장할 변수 Thread th = new Thread() { public void run() { //!--스레드로 수행할 내용 *웹이 나오면 무조건 try catch가 있다고 봐야 함. try { //!--다운로드 받을 URL을 생성 URL url = new URL( "http://apis.daum.net/search/book?apikey=465b06fae32febacbc59502598dd7685&output=json&q=java\r\n" ); //!--URL 연결 객체 생성 HttpURLConnection con = (HttpURLConnection)url.openConnection(); //!--옵션 설정 //캐시설정 여부 - 다운로드 받아놓고 다음에 다운로드 받은 데이터를 이용할 것인지 여부를 설정 con.setUseCaches(false); //얼마동안 접속을 시도해 볼 것인지를 설정 con.setConnectTimeout(30000); //!--문자열을 읽기 위한 스트림 생성 BufferedReader br = new BufferedReader( new InputStreamReader( con.getInputStream() ) ); //!--줄 단위로 데이터를 읽어서 sb에 추가 StringBuilder sb = new StringBuilder(); while(true) { String line = br.readLine(); if(line == null) { break; } sb.append(line); } //!--sb 내용을 json에 대입 String json = sb.toString();
//System.out.println(json); //!--JSON 문자열 파싱 JSONObject main = new JSONObject(json); //System.out.println(main); //!--channel 키의 데이터를 JSONObject 타입으로 가져오기 JSONObject channel = main.getJSONObject("channel"); //System.out.println(channel); //!--channel 에서 item 키의 값을 배열로 가져오기 JSONArray item = channel.getJSONArray("item"); //System.out.println(item); //!--item 배열을 순회 int i = 0; while(i<item.length()) {
JSONObject book = item.getJSONObject(i); System.out.println(book); String author = book.getString("author"); System.out.println(author); i = i + 1;
} }catch(Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); }
} }; th.start(); } } |
** 실습 : 위도와 경도를 대입해서 관광명소를 알려주는 다음 API
https://apis.daum.net/local/v1/search/category.json?apikey=465b06fae32febacbc59502598dd7685&code=AT4&location=37.514322572335935,127.06283102249932&radius=20000
package opensource; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import org.json.JSONArray; import org.json.JSONObject; public class JSONParsingAdress { public static void main(String[] args) { //!--다운로드 받을 문자열을 저장할 변수 Thread th = new Thread() { public void run() { //!--스레드로 수행할 내용 *웹이 나오면 무조건 try catch가 있다고 봐야 함. try { //!--다운로드 받을 URL을 생성 URL url = new URL( "https://apis.daum.net/local/v1/search/category.json?apikey=465b06fae32febacbc59502598dd7685&code=AT4&location=37.5306551,126.73075270000004&radius=20000"); //!--URL 연결 객체 생성 HttpURLConnection con = (HttpURLConnection) url.openConnection(); //!--옵션 설정 // 캐시설정 여부 - 다운로드 받아놓고 다음에 다운로드 받은 데이터를 이용할 것인지 여부를 설정 con.setUseCaches(false); // 얼마동안 접속을 시도해 볼 것인지를 설정 con.setConnectTimeout(30000); //!--문자열을 읽기 위한 스트림 생성 BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream())); //!--줄 단위로 데이터를 읽어서 sb에 추가 StringBuilder sb = new StringBuilder(); while (true) { String line = br.readLine(); if (line == null) { break; } sb.append(line); } //!--sb 내용을 json에 대입 String json = sb.toString(); //System.out.println(json); //!--JSON 문자열 파싱 JSONObject main = new JSONObject(json); //!--channel 키의 데이터를 JSONObject 타입으로 가져오기 JSONObject channel = main.getJSONObject("channel"); //!--channel 에서 item 키의 값을 배열로 가져오기 JSONArray item = channel.getJSONArray("item"); //!--item 배열을 순회 int i = 0; while(i<item.length()) { JSONObject bestplace = item.getJSONObject(i); String title = bestplace.getString("title"); String address = bestplace.getString("address"); String newAddress = bestplace.getString("newAddress"); String placeUrl = bestplace.getString("placeUrl");
System.out.println(title); System.out.println("주소: "+address); System.out.println("도로명 주소: "+newAddress); System.out.println("홈페이지: "+placeUrl); System.out.println("---------------------------"); i = i + 1;
}
} catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } } }; th.start(); } }
|
** XML(eXensible Markup Language)
- 웹에서 자주 변하는 데이터를 표현하기 위해 사용하는 데이터 포맷
- html은 브라우저 별로 해석을 다르게 하고 구조적이지 않기 때문에 데이터를 전달하는 용도로는 사용할 수 없습니다.
<a href="">안녕
<a><b></a></b>
데이터는 명확해야 해서 XML은 적합치 않다.
- XML의 태그를 브라우저가 임의로 해석하지 않습니다.
- 최근에는 용량이 너무 커서 json으로 데이터를 표현하는 경우가 많아 졌습니다.
- 아직도 프로젝트 설정 파일이나 RSS 에서는 XML을 사용하는 곳이 종종 있습니다.
- 파싱방법
1. DOM(Document Object Model) Parser
- 모든 태그를 메모리에 펼쳐 놓고 찾아가는 방식
- 모든 태그를 메모리에 전부 펼치기 때문에 메모리 사용량이 많지만 속도는 빠름
2. SAX Parser
- 태그를 하나 하나 읽어가면서 파싱하는 방식
- 메모리 사용량은 적지만 어렵고 속도는 느림
** 실습 : http://www.weather.go.kr/weather/forecast/mid-term-xml.jsp?stnId=109 에서 넘겨받은 데이터 중에서 tmx 태그의 모든 값을 출력하기
package opensource; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.net.*; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class XPsing { public static void main(String[] args) { // !--다운로드 받을 문자열을 저장할 변수 Thread th = new Thread() { public void run() { // !--스레드로 수행할 내용 *웹이 나오면 무조건 try catch가 있다고 봐야 함. try { // !--다운로드 받을 URL을 생성 URL url = new URL( "http://www.mfds.go.kr/www/rss/brd.do?brdId=ntc0021"); // !--URL 연결 객체 생성 HttpURLConnection con = (HttpURLConnection) url.openConnection(); // !--옵션 설정 // 캐시설정 여부 - 다운로드 받아놓고 다음에 다운로드 받은 데이터를 이용할 것인지 여부를 설정 con.setUseCaches(false); // 얼마동안 접속을 시도해 볼 것인지를 설정 con.setConnectTimeout(30000); // !--문자열을 읽기 위한 스트림 생성 BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream())); // !--줄 단위로 데이터를 읽어서 sb에 추가 StringBuilder sb = new StringBuilder(); while (true) { String line = br.readLine(); if (line == null) { break; } sb.append(line); } // !--sb 내용을 xml에 대입 String xml = sb.toString(); System.out.println(xml); //xml 문자열을 파싱할 수 있는 객체를 생성 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); //파싱할 문자열을 스트림으로 변환 InputStream is = new ByteArrayInputStream(xml.getBytes()); //문자열을 파싱 수행 - org.w3c.dom Document doc = builder.parse(is); //루트 찾기 Element root = doc.getDocumentElement(); System.out.println(root);
//title 태그 전부 찾기 NodeList list = root.getElementsByTagName("title"); NodeList list1 = root.getElementsByTagName("content:encoded"); //System.out.println(list);
int i=0; while(i < list.getLength()) { //데이터의 개수가 안 맞을 때 출력을 같이 시키면 Nullpoint 예외가 발생할 수 있다. //그럴 때는 개수를 세어서 아래와 같이 두번째 데이터가 같이 시작하기 전을 따로 빼어서 코드를 짜고 //else로 같이 시작하도록 해주면 된다. if(i == 0) { Node item = list.item(i); Node child = item.getFirstChild(); String title = child.getNodeValue(); //첫번째 자식을 찾는 이유는 부모는 첫째만 찾기 때문에 첫째가 아닌 형제들을 찾을 수 있는 첫째가 있어야 하기 때문다. //그리고 Node에서 getFirstName()을 해서 나오는 값은 자바가 임의로 넣어둔 값이다. //쓸 일이 거의 없고 그냥 구분을 위해서 넣어둔 값이다. System.out.println("<<<"+item+">>>"); } else { Node item = list.item(i); Node item1 = list1.item(i-1); //첫번째 자식 찾기 Node child = item.getFirstChild(); Node child1 = item1.getFirstChild(); //데이터 찾기 String title = child.getNodeValue(); String title1 = child1.getNodeValue(); System.out.println(title + " : " + title1); } i = i + 1; } } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } } }; th.start(); } }
|
** HTML
- json 이나 xml 형태로 데이터가 제공되지 않는 경우에 웹 페이지에서 원하는 부분의 데이터를 직접 읽어와서 파싱하는 것
- jsoup 를 이용해서 합니다.
- json parsing 처럼 외부 라이브러리를 이용합니다.
- 데이터를 파싱할 때는 Jsoup.parse(html 문자열)을 호출하면 Document 타입의 객체가 리턴됩니다.
- Document 타입의 객체를 가지고 getElementsByTagName, getElementsClass 메소드나 getElementsById 메소드를 호출하게 되는데 id를 제외하고는 중복될 수 있습니다.
- getElementsById는 Element 1개를 리턴하지만 나머지 메소드는 Elements라고 하는 Element 타입의 배열 형식을 리턴합니다.
- 각 Element는 다시 위의 메소드들을 호출해서 안쪽으로 찾아갈 수 있습니다.
- Element 인스턴스가 text()를 호출하게 되면 태그 안의 문자열을 리턴합니다.
1. Jsoup
** 메일 보내기
- java에서는 Commons Email API를 이용해서 이메일 전송이 가능함.
- 메일 전송하는 프로그램을 만들기 위해서는 메일을 보낼 수 있는 서버가 있어야 함.
- 메일 서버가 없는 경우엔 daum이나 naver 메일 계정을 이용할 수 있음
- 네이버 메일 서버 : smtp.naver.com 포트번호 : 587
- 최근에는 직접 서버를 구축을 안하고 서버 없이 메일을 보낸다던가 데이터를 저장한다던가 하는 형식으로 서버를 대신하는 경우가 많습니다.
- 아마존의 AWS 나 Google의 Firebase 등이 대표적인 서비스입니다.
** 실습 : 네이버 메일 서버를 이용한 메일 보내기
1. commons Email 라이브러리를 프로젝트의 빌드패스에 추가
package mail_test; import org.apache.commons.mail.SimpleEmail; public class MailSend { public static void main(String[] args) { try { //텍스트 메일을 보낼 수 있는 클래스의 객체 만들기 SimpleEmail email = new SimpleEmail();
//서버 설정 email.setAuthentication("knock_otd999", "!tosemdnl0893"); email.setHostName("smtp.naver.com"); email.setSmtpPort(587); //메일 보안 설정 옵션 : 메일이 암호화 되서 전송됨 email.setTLS(true); email.setSSL(true); email.setFrom("knock_otd999@naver.com", "관리자"); email.setCharset("utf-8");
//받는 설정 email.addTo("anjeundeun@gmail.com"); email.setSubject("메일 보내기 연습"); email.setMsg("정말로 메일이 갈까?");
//보내기 email.send(); System.out.println("메일 보내기 성공"); }catch(Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } } }
|
'Front End' 카테고리의 다른 글
0809 HTML&JSP (0) | 2018.12.19 |
---|---|
0813 HTML, CSS, JavaScript (0) | 2018.10.22 |
HTML5 의 Web Push (0) | 2018.09.11 |
Proxy (0) | 2018.09.11 |
maven (0) | 2018.09.11 |