▶[서론]
○● 0305 새로웠던 것
1. xml과 json의 차이점
XML(Extensible Markup Language)과 JSON(JavaScript Object Notation)은 모두 데이터를 표현하는 데 사용되는 형식이지만, 다음과 같은 차이점이 있습니다:
- 구문(Syntax):
- XML은 태그를 사용하여 데이터를 표현합니다. 태그는 시작 태그(<tag>)와 종료 태그(</tag>)로 이루어져 있으며, 태그 사이에 데이터가 위치합니다.
- JSON은 중괄호({})와 대괄호([])를 사용하여 데이터를 표현합니다. 중괄호는 객체를 나타내고, 대괄호는 배열을 나타냅니다. 객체는 "key": "value" 쌍으로 이루어져 있습니다.
- 가독성(Readability):
- JSON은 구조가 간단하고 직관적이기 때문에 일반적으로 XML보다 더 가독성이 높습니다.
- XML은 여는 태그와 닫는 태그가 있기 때문에 데이터를 이해하기 위해 더 많은 시각적 잡음이 발생할 수 있습니다.
- 크기(Size):
- JSON은 XML에 비해 데이터를 더 적은 문자로 표현할 수 있습니다. 이는 JSON이 더 간결하고 경량이기 때문입니다.
- XML은 더 많은 태그와 구문을 사용하기 때문에 더 많은 용량을 차지할 수 있습니다.
- 확장성(Extensibility):
- XML은 이름 공간(namespace)을 지원하여 데이터의 확장성을 높일 수 있습니다. 이를 통해 다양한 종류의 데이터를 구조화하고 표현할 수 있습니다.
- JSON은 XML에 비해 확장성이 제한적이지만, 더 간단하고 직관적인 구조로 인해 작은 규모의 데이터나 웹 애플리케이션에 적합합니다.
- 데이터 타입(Data Types):
- JSON은 기본적으로 문자열, 숫자, 불리언, 배열, 객체, null을 지원합니다.
- XML은 데이터를 표현하는 데 필요한 태그를 사용하므로 JSON에 비해 데이터 타입이 더 유연하고 다양할 수 있습니다.
- 웹 애플리케이션에서의 사용:
- JSON은 JavaScript의 일부이기 때문에 JavaScript에서 쉽게 처리할 수 있습니다. 따라서 웹 애플리케이션에서는 JSON이 더 널리 사용됩니다.
- XML은 HTML과 같은 마크업 언어이기 때문에 웹 문서를 작성하는 데 주로 사용되지만, 최근에는 JSON의 인기로 인해 데이터 교환 형식으로서의 사용이 줄어들고 있습니다.
요약하면, JSON은 더 간결하고 가벼우며 직관적인 데이터 형식으로서 많은 웹 애플리케이션에서 선호되지만, XML은 확장성과 다양성 측면에서 더 유연한 데이터 표현 방식입니다.
2. xml파일인 api를 썼는데 로그가 json이랑 비슷하게 나와서 에러가 안떴음.
다만 한글로 된 부분이 깨져서 그부분은 디코딩하니까 보임
// UTF-8로 디코딩하여 문자열을 제대로 표시
String decodedResult = new String(result.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
3. api쪽에서 파일이 잘못 되서도 안 불러와 질 수 있다는 걸 알게 됐음.
▶[본론]
○● 0305 내용 정리
● JSON
○○○●●● 랜덤 고양이 사진 api
function showCat() {
$.ajax({
type: "GET", → GET방식
url: "https://api.thecatapi.com/v1/images/search", → API 주소 입력
data: {}, → GET방식에선 {} 비워두기
success: function (response) { → response는 API 주소에서 나온 값(JSON 방식)
let imgUrl = response[0]['url']; → response의 첫번째 값의 url값을 imgUrl이라고 하자
$("#img-cat").attr("src", imgUrl); } }) } → img-cat이라는 id를 가진 요소에 "src" 속성을 추가하고 값은 imgUrl로 한다
(기존의 src="주소"의 값이 대체된다)
++ get과 post 방식의 차이점
HTTP 프로토콜에서 GET과 POST는 서버로 데이터를 전송하는 두 가지 주요 방법입니다. 이 두 방식은 목적과 사용하는 상황에 따라 다르며, 다음은 각 방식의 주요 차이점입니다:
- 데이터 전송 방식:
- GET: 데이터를 URL의 쿼리 문자열에 포함하여 전송합니다. 이는 주로 검색 쿼리와 같은 간단한 데이터 전송에 사용됩니다.
- POST: 데이터를 HTTP 요청의 본문(body)에 포함하여 전송합니다. 이 방식은 주로 민감한 정보(비밀번호, 신용 카드 정보 등)나 대량의 데이터를 전송할 때 사용됩니다.
- 데이터 길이 제한:
- GET: URL의 길이에 제한이 있으므로 전송할 수 있는 데이터의 양에 제한이 있습니다. 대개 약 2048자(브라우저마다 상이)로 제한됩니다.
- POST: HTTP 요청 본문에 데이터를 포함하므로 데이터의 길이에 대한 제한이 없습니다. 따라서 더 많은 양의 데이터를 전송할 수 있습니다.
- 보안:
- GET: 데이터가 URL에 노출되므로 보안에 취약합니다. 예를 들어, 사용자 이름과 비밀번호를 URL에 포함하는 것은 보안 상의 위험을 초래할 수 있습니다.
- POST: 데이터가 HTTP 요청의 본문에 포함되므로 URL에 노출되지 않습니다. 따라서 보안적으로 더 안전합니다.
- 캐싱:
- GET: 동일한 URL에 대한 GET 요청은 캐시될 수 있으므로 동일한 요청에 대해 서버에 다시 요청하지 않고 캐시된 응답을 사용할 수 있습니다.
- POST: POST 요청은 보안 및 무결성 문제로 인해 캐시되지 않으므로 항상 서버로 전송됩니다.
- Idempotent:
- GET: 동일한 요청을 여러 번 보내더라도 동일한 결과를 반환해야 합니다. 즉, 여러 번 요청해도 서버 상태가 변경되지 않아야 합니다.
- POST: 요청을 여러 번 보내더라도 서버의 상태가 변경될 수 있습니다. POST 요청은 일반적으로 서버의 상태를 변경하기 위해 사용됩니다.
이러한 차이점들을 고려하여 데이터를 전송하는 방식을 선택할 수 있습니다. 일반적으로는 데이터의 양이 적고 보안적인 이슈가 없는 경우에는 GET을 사용하고, 보안적인 이슈가 있거나 대량의 데이터를 전송해야 할 때는 POST를 사용하는 것이 좋습니다.
○○○●●● 국립중앙의료원_전국 약국 정보 조회 서비스 api
사용하려고 했으나......데이터 중에서 데이터 타입이 맞지 않아서 500 error가 떴는데 수정할 수가 없어서
다른 api 활용할 예정
api에서 제공하는 데이터 타입은 xml
{
"dutyAddr": "서울특별시 강남구 선릉로86길 17 (대치동)",
"dutyName": "테헤란건강약국",
"dutyTel1": "02-556-4166",
"dutyTime1c": 2200,
"dutyTime1s": "0900",
"dutyTime2c": 2200,
"dutyTime2s": "0900",
"dutyTime3c": 2200,
"dutyTime3s": "0900",
"dutyTime4c": 2200,
"dutyTime4s": "0900",
"dutyTime5c": 2200,
"dutyTime5s": "0900",
"dutyTime6c": 2000,
"dutyTime6s": "0900",
"dutyTime7c": 1930,
"dutyTime7s": 1530,
"dutyTime8c": 1930,
"dutyTime
": 1530,
"hpid": "C1100829",
"postCdn1": "061",
"postCdn2": "92 ",
"rnum": 6,
"wgs84Lat": 37.5035670052591,
"wgs84Lon": 127.051066236605
},{
"dutyAddr": "서울특별시 강남구 역삼로 310 (역삼동)",
"dutyEtc": "공휴일은 운영여부 개인사정으로 변동될 수 있어 전화확인 후 방문부탁드립니다.",
"dutyMapimg": "선릉역3번출구e마트2층",
"dutyName": "한솔인유로온누리약국",
"dutyTel1": "02-3453-8171",
"dutyTime1c": 2000,
"dutyTime1s": "0900",
"dutyTime2c": 2000,
"dutyTime2s": "0900",
"dutyTime3c": 2000,
"dutyTime3s": "0900",
"dutyTime4c": 2000,
"dutyTime4s": "0900",
"dutyTime5c": 2000,
"dutyTime5s": "0900",
"dutyTime6c": 1630,
"dutyTime6s": "0900",
"dutyTime7c": 1300,
"dutyTime7s": 1000,
"dutyTime8c": 1300,
"dutyTime8s": 1000,
"hpid": "C1100257",
"postCdn1": "062",
"postCdn2": "17 ",
"rnum": 26,
"wgs84Lat": 37.49923572317221,
"wgs84Lon": 127.0484199572856
},
GuestController.java
package com.peisia.spring;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import javax.servlet.http.HttpSession;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.client.RestTemplate;
import com.peisia.dto.GuestDto;
import com.peisia.service.GuestService;
import com.peisia.spring.atmosphere.AtmosphereDto;
import com.peisia.spring.mi.vo.kw.KWeatherDto;
import com.peisia.spring.pharmacy.PharmacyDto;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
@Log4j
@RequestMapping("/guest/*")
@AllArgsConstructor
@Controller
@SessionAttributes("x") // 1. 이 어노테이션을 붙이고
public class GuestController {
private GuestService service;
private final ResourceLoader resourceLoader;
@GetMapping("/getList")
public void getList(@RequestParam(value="currentPage", defaultValue="1") int currentPage, Model model) {
ArrayList<GuestDto> list = service.getList(model, currentPage);
int totalPage = service.getTotalPage(); // 총 페이지 수 가져오기
model.addAttribute("list", list);
model.addAttribute("totalPage", totalPage);
}
@GetMapping({"/read", "/modify"})
public void read(@RequestParam("bno") Long bno, Model model) {
log.info("컨트롤러 ==== 글번호 ==============="+bno);
model.addAttribute("read",service.read(bno));
}
@GetMapping("/del")
public String del(@RequestParam("bno") Long bno) {
log.info("컨트롤러 ==== 글번호 ==============="+bno);
service.del(bno);
return "redirect:/guest/getList?currentPage=1"; // 책 p.245 참고
}
@PostMapping("/write")
public String write(GuestDto gvo) {
service.write(gvo);
return "redirect:/guest/getList?currentPage=1"; // 책 p.245 참고
}
@GetMapping("/write") // 책 p.239 /write 중복이지만 이건 글쓰기 화면을 위한 url 매핑
public void write() {
}
@PostMapping("/modify")
public String modify(GuestDto gvo) {
service.modify(gvo);
return "redirect:/guest/getList?currentPage=1";
}
@GetMapping("/aaa")
public void sessionExample(HttpSession session) {
session.setAttribute("cat","고양이");
}
// 스프링 세션 사용하기
@GetMapping("/a")
public void a(HttpSession s, Model m) {
s.setAttribute("a", "개");
// 2. 모델에 x 키로 고양이 저장. ( 세션에도 x 키로 고양이가 저장됨 )
m.addAttribute("x","고양이");
}
@RequestMapping("/weatherList")
public void w(Model m) {
//// 우리나라 공공 api ////
//인코딩 인증키
String API_KEY = "QFOfiZ8YJEQdpbWKTs92CQy3%2BGIv8uusBFVx9FEd4A%2Fn9cxgi3F2E4lnC%2F%2FbUWtk01Gb5OYaHyxVqKfVARKBmQ%3D%3D";
//페이지 개수 많은 목록
String API_URL = "http://apis.data.go.kr/1360000/AsosDalyInfoService/getWthrDataList?numOfRows=10&pageNo=1&dateCd=DAY&startDt=20240303&endDt=20240303&stnIds=108&dataCd=ASOS&dataType=JSON&serviceKey=" + API_KEY;
// * 주의 * https 아님 http 임. https 는 인증관련 복잡한 처리를 해야함.
RestTemplate restTemplate = new RestTemplate();
//// **** 중요 **** uri
URI uri = null; //java.net.URI 임포트 하셈
try {
uri = new URI(API_URL);
} catch (URISyntaxException e) {
e.printStackTrace();
}
// String s = restTemplate.getForObject(uri, String.class); //
// log.info("====== 우리나라 날씨 잘 나오나? "+s);
KWeatherDto kw = restTemplate.getForObject(uri, KWeatherDto.class); // 자기 클래스로 바꾸시오..
log.info("==== json ==== : 우리나라 날씨 잘 나오냐? : "+kw.response.body.dataType);
String location = kw.response.body.items.item.get(0).stnNm;
String tMin = kw.response.body.items.item.get(0).minTa;
String tMax = kw.response.body.items.item.get(0).maxTa;
String ddara = String.format("==== json ==== : 어제의 날씨입니다~ 어제 %s 의 최저기온은 %s 도 최고 기온은 %s 였습니다. 날씨였습니다.", location, tMin, tMax);
log.info(ddara);
m.addAttribute("location", location);
m.addAttribute("tMin", tMin);
m.addAttribute("tMax", tMax);
// return "redirect:/guest/wea";
}
//약국 정보 불러오는 api 설정
@RequestMapping("/pharmacy")
public void pharmacy(Model m){
//// 우리나라 공공 api ////
//인코딩 인증키
String API_KEY = "QFOfiZ8YJEQdpbWKTs92CQy3%2BGIv8uusBFVx9FEd4A%2Fn9cxgi3F2E4lnC%2F%2FbUWtk01Gb5OYaHyxVqKfVARKBmQ%3D%3D";
String API_URL = "http://apis.data.go.kr/B552657/ErmctInsttInfoInqireService/getParmacyFullDown?pageNo=1&numOfRows=30&serviceKey=" + API_KEY;
RestTemplate restTemplate = new RestTemplate();
// URI로 변환
URI uri;
try {
uri = new URI(API_URL);
} catch (URISyntaxException e) {
e.printStackTrace();
return; // 예외 발생 시 종료
}
// RestTemplate을 사용하여 API에 GET 요청을 보내고 응답을 받습니다.
String result = restTemplate.getForObject(uri, String.class);
// UTF-8로 디코딩하여 문자열을 제대로 표시
String decodedResult = new String(result.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
log.info("====== 잘 나오나? "+decodedResult);
PharmacyDto ph = restTemplate.getForObject(uri, PharmacyDto.class); // 자기 클래스로 바꾸시오..
String dutyName = ph.response.body.items.item.dutyName;
String dutyAddr= ph.response.body.items.item.dutyAddr;
//월요일 진료시간(c)
int dutyTime1c = ph.response.body.items.item.dutyTime1c;
//화요일 진료시간(c)
int dutyTime2c = ph.response.body.items.item.dutyTime2c;
//수요일 진료시간(c)
int dutyTime3c = ph.response.body.items.item.dutyTime3c;
//목요일 진료시간(c)
int dutyTime4c = ph.response.body.items.item.dutyTime4c;
//금요일 진료시간(c)
int dutyTime5c = ph.response.body.items.item.dutyTime5c;
//토요일 진료시간(c)
int dutyTime6c = ph.response.body.items.item.dutyTime6c;
//일요일 진료시간(c)
int dutyTime7c = ph.response.body.items.item.dutyTime7c;
//공휴일 진료시간(c)
int dutyTime8c = ph.response.body.items.item.dutyTime8c;
//////ssssssss
//월요일 진료시간(s)
String dutyTime1s = ph.response.body.items.item.dutyTime1s;
//화요일 진료시간(s)
String dutyTime2s = ph.response.body.items.item.dutyTime2s;
//수요일 진료시간(s)
String dutyTime3s = ph.response.body.items.item.dutyTime3s;
//목요일 진료시간(s)
String dutyTime4s = ph.response.body.items.item.dutyTime4s;
//금요일 진료시간(s)
String dutyTime5s = ph.response.body.items.item.dutyTime5s;
//토요일 진료시간(s)
String dutyTime6s = ph.response.body.items.item.dutyTime6s;
//토요일 진료시간(s)
int dutyTime7s = ph.response.body.items.item.dutyTime7s;
//토요일 진료시간(s)
int dutyTime8s = ph.response.body.items.item.dutyTime8s;
//예외 설정(s)
int dutyTime = ph.response.body.items.item.dutyTime;
//약국 세부 사항
String dutyInf = ph.response.body.items.item.dutyInf;
//
// String phar = String.format("==== json ==== : 약국 데이터 어제 %s 의 최저기온은 %s 도 최고 기온은 %s 였습니다. 날씨였습니다.", location, tMin, tMax);
// log.info(phar);
m.addAttribute("dutyName", dutyName);
m.addAttribute("dutyAddr", dutyAddr);
m.addAttribute("dutyTime1c", dutyTime1c);
m.addAttribute("dutyTime2c", dutyTime2c);
m.addAttribute("dutyTime3c", dutyTime3c);
m.addAttribute("dutyTime4c", dutyTime4c);
m.addAttribute("dutyTime5c", dutyTime5c);
m.addAttribute("dutyTime6c", dutyTime6c);
m.addAttribute("dutyTime7c", dutyTime7c);
m.addAttribute("dutyTime8c", dutyTime8c);
m.addAttribute("dutyTime1s", dutyTime1s);
m.addAttribute("dutyTime2s", dutyTime2s);
m.addAttribute("dutyTime3s", dutyTime3s);
m.addAttribute("dutyTime4s", dutyTime4s);
m.addAttribute("dutyTime5s", dutyTime5s);
m.addAttribute("dutyTime6s", dutyTime6s);
m.addAttribute("dutyTime7s", dutyTime7s);
m.addAttribute("dutyTime8s", dutyTime8s);
m.addAttribute("dutyTime", dutyTime);
m.addAttribute("dutyInf", dutyInf);
}
}
pharmacy.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="cp" value="${pageContext.request.contextPath}" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
약국 데이터 불러왔어요.
<!-- dutyName-기관명 -->
<!-- dutyAddr-주소 -->
<!-- dutyEtc-비고(외래 진료 시간) -->
기관명:${dutyName} 주소:${dutyAddr}
<hr>
월요일 진료 시간(c):${dutyTime1c}
<hr>
화요일 진료 시간(c):${dutyTime2c}
<hr>
수요일 진료 시간(c):${dutyTime3c}
<hr>
목요일 진료 시간(c):${dutyTime4c}
<hr>
금요일 진료 시간(c):${dutyTime5c}
<hr>
토요일 진료 시간(c):${dutyTime6c}
<hr>
일요일 진료 시간(c):${dutyTime7c}
<hr>
공휴일 진료 시간(c):${dutyTime8c}
<hr>
월요일 진료 시간(s):${dutyTime1s}
<hr>
화요일 진료 시간(s):${dutyTime2s}
<hr>
수요일 진료 시간(s):${dutyTime3s}
<hr>
목요일 진료 시간(s):${dutyTime4s}
<hr>
금요일 진료 시간(s):${dutyTime5s}
<hr>
토요일 진료 시간(s):${dutyTime6s}
<hr>
일요일 진료 시간(s):${dutyTime7s}
<hr>
공휴일 진료 시간(s):${dutyTime8s}
<hr>
공휴일 진료 시간(s) 예외:${dutyTime}
<hr>
약국 정보:${dutyInf}
<hr>
<a href="${cp}/">뒤로가기</a>
</body>
</html>
▶[결론]
* JSON 기초 강의 수강
*작업파일
● 0305
1) JSON 기초
'개발 회고' 카테고리의 다른 글
[솔데스크] 풀스택 과정 14주-5 총62회차 ‘회고’ | JSON(0308) (2) | 2024.03.08 |
---|---|
[솔데스크] 풀스택 과정 14주-4 총61회차 ‘회고’ | JSON(0307) (0) | 2024.03.07 |
[솔데스크] 풀스택 과정 13주-4 총58회차 ‘회고’ | JSON(0229) (0) | 2024.03.05 |
[솔데스크] 풀스택 과정 13주-3 총57회차 ‘회고’ | 스프링(0228) (1) | 2024.03.05 |
[솔데스크] 풀스택 과정 13주-2 총56회차 ‘회고’ | 스프링(0227) (3) | 2024.03.05 |