오늘은
다음주 월요일부터 새로운 팀 프로젝트의 시작입니다
팀원도 정해졌고 주제도 정해진 듯 합니다
앞으로 있을 팀 프로젝트에 기획을 잘 짜서
수월하게 진행되기를 바라는 마음입니다
Spring 공부
<날씨 정보 - 기상청 Data 연동>
공공데이터 포털
기상청 단기 예보 - 오픈 API - 기상청 단기예보 - 하단 오픈API - 활용신청 - 사유 작성 - 활용신청
<데이터 포맷>
= JSON + XML
* Json 방식 * xml 방식
{ <person>
"name": "이순신" <name>이순신</name>
"gender": "남" <gender>남</gender>
} </person>
* JSON 데이터 컨트롤
$.getJSON(){}
document.getElementById("아이디선택자").innertText = "내용" // = js 방식
$.ajax({
선택자 $(".result").text() // = jquery 방식
})
* Main.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>오늘의 날씨</title>
</head>
<script
src="https://code.jquery.com/jquery-3.7.1.js"
integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4="
crossorigin="anonymous"></script>
<body>
<h1>오늘의 날씨</h1>
<h3 class="result">
<!-- 20240125, 0600, -9.1 -->
</h3>
<script>
// 날짜를 변수화
const date = new Date();
console.log(date);
let year = date.getFullYear(); // 2024
let month = '0' + date.getMonth()+1; // 1
let day = '0' + date.getDate(); // 25
month = month.substring(1) // substring(인덱스)인덱스부터 끝까지 추출
day = day.substring(1);
let today = year + month + day;
$.ajax({
type: "GET",
url: "https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst?serviceKey=Czv3Me9Ivw6piA470yefflffDGzAsw9tObOp4T5OariNl8C3CGpaUt9JHcev%2BlOlh8%2FTj2fcYguzY86yh87F%2Fg%3D%3D&pageNo=1&numOfRows=1000&dataType=JSON&base_date=" + today + "&base_time=0600&nx=55&ny=127",
// data: ,
success: function(data){
console.log(data);
console.log(data.response.body.items.item[3].obsrValue);
let item = data.response.body.items.item[3];
let content = "날짜: " + item.baseDate +
", 발표시각: " + item.baseTime +
", 기온: " + item.obsrValue;
$('.result').text(content);
},
error: function(error){
console.log(error);
}
});
</script>
</body>
</html>
<REST API 개발>
= HTTP의 하나의 서비스임
= Respresentational State Transfer
= 안정적이고 표준화된 클라이언트/서버 통신을 통해 전송되는 문서
Restfull API
* Form 방식
=> @Controller + @ResposeBody
From이 있음 - GET/POST
- @GetMapping, @PostMapping
* rset방식
=> @RestController
Form이 없음 - GET/POST/PUT/DELETE
- @GetMapping, @PostMapping, @PutMapping, @DeleteMapping
* PostMan(포스트맨)
= GET/POST/PUT/DELETE 방식 모두 테스트 할 수 있는 Http 요청 프로그램
@RequestBody (반환)
@RequestBody - 입력 데이터(파라미터)
* UserController
package cohttp://m.khit.board.controller;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import cohttp://m.khit.board.entity.User;
import cohttp://m.khit.board.service.UserService;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Controller
public class UserController {
private final UserService service;
// 회원가입
// 포스트맨에 json형태의 자료를 입력 받아서 DB에 저장
@PostMapping("/user")
@ResponseBody
public String insertUser(@RequestBody User user) {
service.save(user);
return "회원 가입 성공";
}
// 회원 목록 보기
@GetMapping("/user/list")
@ResponseBody
public List<User> getList(){
List<User> userList = service.findAll();
return userList;
}
// 회원 상세 보기
@GetMapping("/user/{id}")
@ResponseBody
public User getUser(@PathVariable Integer id) {
// 검색된 회원이 없을 경우 예외 반환
return service.findById(id);
}
}
* UserService
package cohttp://m.khit.board.service;
import java.util.List;
//import java.util.function.Supplier;
import org.springframework.stereotype.Service;
import cohttp://m.khit.board.entity.User;
import cohttp://m.khit.board.exception.CustomException;
import cohttp://m.khit.board.repository.UserRepository;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository repository;
public void save(User user) {
repository.save(user);
}
public List<User> findAll() {
return repository.findAll();
}
public User findById(Integer id) {
// 검색된 회원이 없는 경우는 람다식으로 예외 처리
User getUser = repository.findById(id).orElseThrow(()->{
return new CustomException(id+"번 회원이 없습니다");
});
return getUser;
// User getUser = repository.findById(id).get().orElseThrow(new Supplier<CustomException>() {
//
// @Override
// public CustomException get() {
// return new CustomException(id+"번 회원이 없습니다");
// }
//
// });
//
// return getUser;
}
}
* UserRpository
package cohttp://m.khit.board.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import cohttp://m.khit.board.entity.User;
public interface UserRepository extends JpaRepository<User, Integer>{
// save(), findAll(), findById(), deleteById()
}
<예외 처리>
* CustomException
=> 우클릭 - source - generate constrictors from superclass - (String)체크
package cohttp://m.khit.board.exception;
// 사용자 정의 exception 예외 처리 클래스
public class CustomException extends RuntimeException{
public CustomException(String message) {
super(message);
}
}
* CustomExceptionHandler
package cohttp://m.khit.board.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
@ControllerAdvice // 예외처리 역할을 하는 클래스(controller 보조 역할)
@RestController // 문자를 반환하는 클래스
public class CustomExceptionHandler {
@ExceptionHandler(value = Exception.class)
public String globalExceptionHandler(Exception e) {
return "<h2>" + e.getMessage() + "</h2>";
}
}
React 공부
<<프로젝트 기초 공사>>
1. 상태 관리 세팅하기
=> 프로젝트 전반적으로 사용될 일기 데이터 State 관리 로직 작성하기
* 상태관리
<App /> <----- 일기 데이터 State
|
<ReactRouter />
<Home /> <New /> <Edit /> <Diary />
| | | |
일기 리스트 일기 생성 로직 일기 수정 로직 일기 하나의 데이터
* App.js
import { useReducer, useRef } from "react";
const reducer = (state, action) => {
let newState = [];
switch (action.type) {
case "INIT": {
return action.data;
}
case "CREATE": {
// const newItem = {
// // reducer에서 받는 action 객체에서는
// // spread 연산자를 이용하여 newItem 생성
// ...action.data,
// };
// newState = [newItem, ...state];
// newItem 대신 action.data를 직접 넣어줌
newState = [action.data, ...state];
break;
}
case "REMOVE": {
// targetId를 필터링 한 나머지 요소들을 배열로 만들어서 newState를 바꾼다
newState = state.filter((it) => it.id !== action.targetId);
break;
}
case "EDIT": {
newState = state.map((it) =>
// 전달된 action.data의 id가 일치하는 요소를 찾아내서
// 그 일치하는 요소에 action.data를 전달하도록 한다
it.id === action.data.id ? { ...action.data } : it
);
break;
}
default:
return state;
}
return newState;
};
function App() {
const [data, dispatch] = useReducer(reducer, []);
// dispatch 함수 만들기
const dataId = useRef(0);
// CREATE
const onCreate = (date, content, emotion) => {
// 시간, 내용, 감정 -> 데이터로 전달
dispatch({
// 이런식으로 데이터 전달
type: "CREATE",
date: {
id: dataId.current,
date: new Date(date).getTime(),
content,
emotion,
},
});
dataId.current += 1;
};
// REMOVE
const onRemove = (targetId) => {
dispatch({
type: "Remove",
targetId,
});
};
// EDIT
const onEdit = (targetId, date, content, emotion) => {
dispatch({
type: "EDIT",
date: {
id: targetId,
date: new Date(date).getTime(),
content,
emotion,
},
});
};
}
export default App;
2. 프로젝트 State Context 세팅하기
=> 일기 데이터 State를 공급할 Context를 생성하고 Provider로 공급하기
* App.js
import React, { useReducer, useRef } from "react";
// context 생성 = State Context setting
export const DiaryStateContext = React.createContext();
function App() {
return (
// context의 data를 공급하기 위해서
// component 트리의 전체를 DiaryStateContext의 Provider로 감싸준다
// value={data}로 데이터 공급
<DiaryStateContext.Provider value={data}>
<BrowserRouter>
<div className="App">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/new" element={<New />} />
<Route path="/edit" element={<Edit />} />
<Route path="/diary/:id" element={<Diary />} />
</Routes>
</div>
</BrowserRouter>
</DiaryStateContext.Provider>
);
}
export default App;
3. 프로젝트 Dispatch Context 세팅하기
=> 일기 데이터 State의 Dispatch 함수들을 공급할 Context를 생성하고 Provider로 공급하기
* App.js
import React, { useReducer, useRef } from "react";
// context 생성 = Dispatch Context setting
export const DiaryDispathContext = React.createContext();
function App() {
return (
// 최상위 문맥 : value={data}로 데이터 공급
<DiaryStateContext.Provider value={data}>
{/* 두번째 문맥 : data state를 변화시킬 수 있는
dispatch함수들을 객체로 공급 */}
<DiaryDispathContext.Provider value={{ onCreate, onEdit, onRemove }}>
<BrowserRouter>
<div className="App">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/new" element={<New />} />
<Route path="/edit" element={<Edit />} />
<Route path="/diary/:id" element={<Diary />} />
</Routes>
</div>
</BrowserRouter>
</DiaryDispathContext.Provider>
</DiaryStateContext.Provider>
);
}
export default App;
2023. 01. 25 (목)
프로그래밍 도전기 109일차 (2) | 2024.01.30 |
---|---|
프로그래밍 도전기 108일차 (2) | 2024.01.28 |
프로그래머 도전기 106일차 (2) | 2024.01.23 |
프로그래머 도전기 105일차 (2) | 2024.01.22 |
프로그래머 도전기 104일차 (0) | 2024.01.18 |