상세 컨텐츠

본문 제목

프로그래밍 도전기 107일차

프로그래머가 될거야!

by Choyee 2024. 1. 25. 21:05

본문

오늘은

 

다음주 월요일부터 새로운 팀 프로젝트의 시작입니다

팀원도 정해졌고 주제도 정해진 듯 합니다

앞으로 있을 팀 프로젝트에 기획을 잘 짜서

수월하게 진행되기를 바라는 마음입니다

 

 

 

 

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 (목)

관련글 더보기