Programming/Note

[개발노트] 영화 커뮤니티 웹사이트

Yejii 2021. 3. 3. 12:10

My Note

1. 오라클 + 스프링 부트 + JPA 연동 해결 : ar-tec.tistory.com/55

2. 스프링 시큐리티+ JWT + REACT(SPA) 인증(로그인) 기능 진행 상황 : ar-tec.tistory.com/68

 

References

1. 자바 ORM 표준 JPA 프로그래밍 : ultrakain.gitbooks.io/jpa/content/

2. 리액트 + Spring : www.youtube.com/watch?v=hdsALpVJwgU&list=PL93mKxaRDidEfLM0I_FFb-98vfAQgXT82

3. 스프링 시큐리티 : www.youtube.com/watch?v=GEv_hw0VOxE&list=PL93mKxaRDidERCyMaobSLkvSPzYtIk0Ah

4. 인스타 클론코딩 (Spring + JPA) : https://github.com/codingspecialist/Springboot-Jpa-Instagram-v2

 

 

 

SCHEDULE

[각 스프린트 당 6일] 개발, 테스트, 정리
[스터디 방식] 프로젝트 시작 때 '어제 개발한 부분 + 앞으로 할 부분 공유' (+문서화)

[배포방식 논의] Docker, AWS

더보기

SPRINT 1 (3/2~3/12 목) : 개발환경 세팅, 로그인/회원가입 기능, 메인 페이지 라우팅 설정

  • 프로젝트 환경 설정
    • SpringBoot, Spring Security, Hibernate
    • Oracle
    • React
  • Front
    • 로그인
    • 회원가입
    • 로그인 인증 토큰 처리
  • Back
    • 회원 생성, 조회, 수정, 삭제
    • 시큐리티 로그인 설정
  • 보완할 점
    • 테스트
    • Front
      • 회원가입시 기입할 정보 수정
        • 프로필 사진 추가
        • 불필요한 정보 삭제 : 생년월일, 핸드폰 번호, 주소
        • 추가 정보 : 웹사이트, 자기소개
      • 회원가입 시 아이디, 비밀번호, 이메일 검증
      • 로그인 인증 토큰 저장 장소 변경
    • Back
      • 소셜 로그인 기능
      • 권한 인가 설정하기 (시큐리티 필터에 url 권한 등록)

 

SPRINT 2 (3/13~3/17 ) : 게시물 작성

  • API 규칙 세팅
    • 'api/review' 
  • Front 
    • 게시물 작성 모달창
      • 영화 정보 실시간 검색창
      • 별점 라디오 버튼
      • 이미지 업로더
      • 서버에 데이터 전송 및 기타 설정
  • Back 
    • REVIEW, IMAGE 엔티티 연관 관계 설정
    • 리뷰 생성
      • 이미지 파일 메모리에 저장
      • REVIEW, IMAGE 테이블에 저장
  • 보완할 점
    • 테스트 
    • Back
      • 영화 고유 ID 설정
    • Front
      • 이미지 업로드 안했을 경우 선택한 영화 포스터 자동으로 등록

 

SPRINT 3 (3/18~3/23 화) : 게시물 표시

  • API 규칙 세팅
    • 리뷰 수정, 삭제
    • 댓글 생성, 수정, 삭제
    • 좋아요 생성, 삭제
  • Front
    • 리뷰 출력
      • 리뷰 화면
      • 수정 버튼
      • 좋아요 버튼
      • 댓글 창, 버튼
  • Back
    • REVIEW, COMMENT, LIKE, MEMBER 엔티티 연관관계 설정
    • 리뷰 수정, 삭제
    • 댓글 생성, 수정, 삭제
    • 좋아요 생성, 삭제
  • 보완할 점
    • 게시물 이미지 사이즈 조정

 

SPRINT 4 (3/24~4/4 일) : 검색, 박스 오피스, 마이 페이지

  • API 규칙 세팅
    • 리뷰 조회(전체, 회원명으로, 영화명으로)
    • 박스오피스 조회
  • Front
    • 리뷰
      • 검색창
      • 전체 리뷰 게시물 스크롤 처리
      • 리뷰 게시물 생성, 수정, 삭제 후 렌더링
    • 박스오피스
      • 순위, 영화명, 전일 대비 순위 변동 정보 출력
    • 마이 페이지
      • 내 리뷰 게시물 모아보기
        • 리뷰의 첫번째 이미지, 좋아요 개수, 댓글 개수 출력
      • 회원 수정
        • 이름, 이메일, 웹사이트, 자기소개 변경
      • 회원 탈퇴
        • 비밀번호 재입력하여 검증
  • Back
    • 리뷰 조회
      • 페이징 처리
      • 전체, 회원명, 영화명에 따라 
    • 마이 페이지
      • LIKE, COMMENT 리포지토리에 count 필드 생성
    • 박스오피스
      • 박스오피스 순위 자동 업데이트
  • 보완할 점
    • 테스트
    • 프론트 코드 정리
    • 검색창
      • 스크롤
      • UI 디자인
    • 리뷰 출력
      • 생성, 삭제 후 렌더링

 

 

SPRINT 5  : 상영중인 영화

- [API 규칙 세팅]
- [view]
- [vo, repository, service, controller]
- [test]
- [문서정리] 스토리 보드 구체화, 개발할 때 이슈 정리

 


5주차(3/29~4/4)

4/4 (일)

Today's task 

1. 소셜 로그인(진행중)

2. 회원가입 수정(완료)

- UI 수정

- 아이디, 비밀번호, 이메일 정규식 검증

 

Today I Learn

  1. 소셜로그인
  • Build.gradle oauth 라이브러리 추가(완료)
  • Application.yml 구글만 (완료)
  • Member 엔티티 수정(완료)
    • String Provider
    • String ProviderId
  • PrivncipalDetail 수정(완료)
    • 다중 상속 : OAuth2User
    • 필드에 추가
    • Oauth 로그인시 사용할 생성자 추가
  • PrincipalService 동일(완료)
  • Provider 디렉토리 생성
    • OAuth2UserInfo 인터페이스(완료)
    • GoogleUserInfo 생성. 인터페이스 상속받아서(완료)
  • PrincipalOauth2UserService 생성 (완료)
    • DefaultOAuth2UserService 상속
  • Securityconfig 설정

결과  ===> REDIRECT FILTER에 처리필요한 둣

 

4/2 (금)

Today's task 

1. 마이 페이지

- 로그인 후 profile 페이지에 필요한 정보 스토리지에 저장? or didupdate때 불러오게?

 

2. Member 엔티티 수정

- 프로필 이미지

- 아이디

- 이메일

- 이름

- 자기 소개

- 웹 사이트

 

4/1 (목)

Today's task 

1. 마이 페이지

- Back 

    - 내 게시물 모아보기

    - 회원 수정

    - 회원 탈퇴

 

3/30 (화)

Today's task 

1. 서버 코드 리팩토링

- ROLE_TYPE ENUM으로 변경

- 엔티티 int, long=> Integer, Long 타입으로 변환

- sequence allocation size 50이나 100으로 변경

- 엔티티 순환참조 문제 

   - @jsonIgnoreProperties

2. develop과 merge

3. 피드백 받은거 고치기

- 상수 사용

- Like 메서드 분리

 

 

4주차(3/22~3/28)

3/28 (일)

Today's task 

1. 서버 코드 리팩토링

2. 테스트

 

Today I Learn

1. 멤버 엔티티 수정 

  • Model : Pk id Long타입으로 변환
  • Repository : Repository Long타입으로 변경
    •  이유 : 1) 양수 범위 늘어남, null 처리 

2. 정보 수정 시나리오

  • Front : 입력한 password 가지고 있음
  • Back : 입력한 password 암호화한 결과가 db 일치하는지 확인
  • Front : password, name, email, address, phone 기존 + 변경된 전체 보내기
  • Back : set으로 다시 세팅
    • 기존 password 다시 한번 인증
    • 인증 확인되면 정보 변경
  • 시큐리티 기능 적용 (완료)

 

3. 리뷰 기능

  • Controller 시큐리티 적용 (완료)
  • Dto 생성 (완료)
    • 리뷰 생성, 리뷰 수정 DTO
    • Default @ResponseBody 아니라 @ModelAttribute
  • Service 레이어 분리(완료)
  • 테스트
    • 생성
      • 이미지 없이 생성 

 

  • 이미지 포함 생성

 

  • Update 
    • 없는 리뷰 게시물 수정

 

  • 있는 리뷰 게시물 수정
    • 없는 리뷰 id 리뷰 수정 요청

 

  • 없는 이미지 id 이미지 삭제 요청

  • 권한 없는 review id( 게시물이 아닌 이미지들) 이미지 삭제 요청

 

  • 있는 이미지 id 이미지 삭제 요청

 

 

 

  • 새로운 이미지 추가 요청

 

  • 존재 안하는 게시물 수정

  • 권한 없는 리뷰에 대한 수정 요청

  • Delete 
    • 없는 리뷰 게시물 삭제

 

  • 권한 없는 리뷰 게시물 삭제

  • 권한 있는 사람이 게시물 삭제

 

 

4. 좋아요 기능(완료)

  • Likes, Review 연관관계 설정(완료)
    • Review id member id Likes 찾아옴
  • SERVICE, CONTROLLER(완료)
    • 클릭하면 추가하고 LIKE 반환
    • 다시 클릭하면 삭제하고 UNLIKE 반환

 

5. 댓글 기능

  • Review, Comment, Member 연관관계 설정
    • Comment라는 테이블 생성 불가. Comments라고 해야됨
  • 댓글 추가 (model 받으려면 post body form-data 보내야 한다. )

  • 댓글 수정(dto 클래스에 세터 없으면 null 반환)

 

 

  • 댓글 삭제

 

6. 리뷰 삭제시 디렉토리에 저장된 이미지 파일도 삭제 (완료)

7. saveImage 뭔가 개선할 있을 거같다.

    • 아이디어 : DTO 자체를 OPTIONAL 만든다음에 saveFiles에서 직접 catch 잡아주고 ifPresent안에서 처리하기

8. 리뷰 조회

  • Like, comment, review 전체 뿌려주기
    • 순환 참조 문제 해결하기

 

9. @ModelAttribute null 문제

  • Content type application/json으로 보내면 안됨

 

  • RESTFUL 정의가 뭘까?
    • DTO 써야 RESTFUL 프로그램이라 하는 거지?

 

 

3/27 (토)

Today's task 

1. 서버 코드 리팩토링

- 리뷰 생성, 수정, 조회, 삭제

- JSONObject로 결과 반환하기

 

Today I Learn

1. JPARepository에서 detele 메서드 호출할 때 엔티티 없어도 오류 발생시키지 않는다

2. 조회 + 페이징 처리 : https://www.baeldung.com/spring-data-jpa-pagination-sorting

 

 

 

3/26 (금)

Today's task 

1. 서버 코드 리팩토링

- 리뷰 생성, 수정 컨트롤러 메서드 리팩토링(파람말고 바디로 주고받게 변경)

 

Today I Learn

1. 파일을 포함한 데이터 받기

  • 방법 1 : @RequestParam(required=false)
  • 방법 2 : @RequestBody (ReviewDTO) => 안됨.

1) 리뷰 수정 : 삭제할 이미지의 IDX와 새로 추가할 이미지 파일 포함

 

  • 오류1 : Null 받아오는 문제
  • 오류2 : 파싱 에러

  • 참고 : https://repacat.tistory.com/31
  • 여전히 같은 에러가 뜬다 => 파싱 에러
  • @RequestBody 받아와서 DTO 사용하면 POSTMAN 사용할 계속 에러난다;;
    • 해결 : @ModelAttribute로 받아오면 ㄱㅊ다. 왜 그런지 찾아봐야될듯

 

2. 자식 엔티티에게 영속성 전이 설정

  • 연관관계 부모에서 cascade 설정하기
  • 연관관계 끊어진 자식 엔티티 자동삭제 기능

 

 

 

3/25 (목)

Today's task 

1. 서버 코드 리팩토링

- Service 인터페이스 제거

 

 

3/24 (수)

Today's task 

1. 서버 코드 리팩토링

- MEMBER, REVIEW, IMAGE, LIKE, COMMENT 연관관계 재설정

 

 

3/23 (화)

Today's task 

1. 스프린트 회고 준비

2. back

- refresh token

3. front

- edit, delete 기능

- 별점 1점 ~10점으로 수정

4. 기타

- 디렉토리, 컴포넌트 네이밍 수정

Today I Learn

1. Edit 기능

  • 리뷰 모달창의 버튼 분리하기
    • 자식에게 데이터 전송

  • 부모로 부터 받아온 isOpen close 찍어보기

 

  • Edit 버튼 누르면 현재 있는 게시물의 위치까지 reviewbox 실행됨..
    • 원인 : ReviewList > ReviewBox > ReviewBody(edit button) 의 의존관계를 가짐. 이 때 스크롤 내릴 시 매번 새로운 review box가 생성되고 해당 박스에 대한 body가 생성되어 무한 루프에 빠짐. 
    • 해결 : 리뷰 박스에 유니크한 키값을 주어, 한 번 생성되면 다시 생성되지 않게 변경하면 해당 구조로 사용해도 가능

TODO

1. JPA 공부하고 코드 리팩토링

 

 

 

3/22 (월)

Today's task 

1. BACK

    • 토큰 처리하는 로직 다시 원래대로 => refresh token 사용해보기

2.  Front

  • 구조 파악
    • Header : writername, createdate
    • Body : title, content, rating, images
    • Footer : 댓글
  • 수정에 필요한 value 사실상 body에 존재. Header body 구분하면 데이터 주고 받는 로직 더러워 질거같음
    • Controller에서 Rating 타입 오류 문제 해결 => parseInt
    • 이미지 전송 문제 => Pictures 배열 초기화
    • 현명 오빠 코드 merge 실행 안됨(해결) =>  안됬었는지 알수가 없네 ㅇㅂㅇ
    • EDIT 기능
  • DELETE 기능
  • 제안 => 디렉토리 네이밍 변경. 헷갈려 ㅇㅂㅇ

 

Today I Learn

1. 이미지 있는 게시물 업로드 다시 모달창 열어서 이미지 없는 게시물 업로드 시도 => 오류

  • 분명 이미지 없는 거로 업로드 요청했는데 url api/review/img 세팅된다.
    • Pictures 배열에 요소가 존재한다는 의미
  • 원인은 reviewWriteBox 컴포넌트의 생성주기.
    • 모달창을 새로 open 때마다 컴포넌트가 생성되는 것이 아니기 때문에, handleClose()호출 전에 pictures 배열을 clear한뒤에 모달창을 닫아야 한다.

2.  Rating(평점) string value 전송되는데, controller에서 int값으로 받기 때문에 발생하는 오류

  • 평점이 소숫점이 되면 string value로 세팅된다 => 처리해줘야 할듯
  • 서버에서 발생하는 오류 메세지 :org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'int'; nested exception is java.lang.NumberFormatException: For input string: "4.5"]
  • 시도 1 : StarBoxComponent에서 parseInt value값을 세팅한  부모로 전달했다.
    • 그래도 안됨…  전달된 값이  string으로 세팅된다.

 

 

 

2. Git

  • Staged 파일 확인하기

 

  • 원격 저장소에 update 내용이 있고, 나도 add하여 push 내용이 있는 경우.
    • 우선 push 명령어를 사용하면 pull하라는 이야기를 한다. 이미 원격 브랜치에 업데이트 내용이 있기 때문ㅇ

 

  • 바로 git pull 시도하면 다음과 같은 에러가 뜬다. 내가 intellij 수정(사실 커밋을 했는데?) 부분을 stash 임시저장소로 옮긴 뒤에 하라는 . 오버라이팅 있기 때문에!

 

  • 그래서 우선 나의 작업 내용을 stash 임시 저장소에 저장했다.

 

  • 그런 뒤에 pull

 

 

  • 임시 저장해 놓은 commit 다시 빼냈다.

 

  • 그런 다음 push => 정상 작동띠

 

3. 궁금한거 =>picture배열 초기화가 필요할까?

  • 모달창 생성자 언제 호출되는지 확인해보자.
  • 모달창 여러 껏다켰는데 호출 1번만 . 결국 picture 초기화 필요할듯? 일단 실험

  • 맞네 pictures 배열 초기화 안해주면. 계속 파일 추가됨( 전에 파일 2 추가했고, 이번에는 1개만 추가했는데 배열 크기 3으로 뜬다.)

 

 

  • 해결띠

 

 

TODO

1. 스프린트 회고 준비

2. back

- refresh token

3. front

- edit, delete 기능

- 별점 1점 ~10점으로 수정

4. 기타

- 디렉토리, 컴포넌트 네이밍 수정

 

 

3주차(3/15~3/21)

3/21 (일)

Today's task 

1. 리 작성 

    • 프론트
      • Controller에서 파일 없어도 저장되게 처리 o
      • 파일 여러  전송 가능하게 하기
      • Review 별점 저장할 필드 만들기 o

Today I Learn

1. 이미지 업로드 라이브러리

TODO

1. BACK

    • 토큰 처리하는 로직 다시 원래대로 => refresh token 사용해보기

2.  Front

  • 구조 파악
  • EDIT 기능
  • DELETE 기능
  • 제안 => 디렉토리 네이밍 변경. 헷갈려 ㅇㅂㅇ

 

3/20 (토)

Today's task 

1.  게시물 작성 : 네이버 API와 연동

  • 별점 모달창
  • Placeholder
  • 이미지 다수로

Today I Learn

1. 모달창과 검색창 기능 합치기

  • 참고 : https://ichi.pro/ko/reactlo-silsigan-jadong-wanseong-saengseong-jeonche-gaideu-63375445320588
  • 모달창과 검색창 기능 합쳐서 구현할 방법
    • This.selected 분명히 들어가서 영화이름 세팅되는데, 부모로 보내질 못햇다.
    • 1 시도 : js 메서드를 jsx 가져와서 세팅한 this.state.selected 확인
      • 결과 : 그래도 handle change호출을 안한다?
      • 분명 onchange 등록되어 있는데..
      • 모르겠지만 div 넣고 중간에 텍스트를 넣는거는 태그 자체의 value 변경되는게 아니다(input value자체가 변하기 때문에 그랬던 )
    • 모달창에 title 세팅하는방법
      • Title 세팅!
    • 명시적으로 안불러주면 전송 안된다.
    • 알아낸 <input onchange={handler}> input태그의 value 변경될 때마다 handler 호출되는 것이고 <div onchange={handler}> or <p>{value} </p> </div> 이런식으로는 써도 태그 내부의 value 변하는 것이 아니라 그냥 태그가 감쌀 뿐이므로  handler 작동 안한다.;;;;
      • 그러니까 이런 경우에는 콜백 함수말고 직접적으로 호출해서 써야 한다. (js 넣을 없었던 핵심이유…;;)
      • 진짜.. 겨우했다^^ 개어렵다 진심
  • This.props.변수명으로 바로 접근하면 undefined 뜬다
  • 대신 this.props.부모에 등록한 콜백메서드 명시적으로 호출해주면 .
  • 이렇게 부모의 함수를 호출할 있는 이유는 부모 컴포넌트에서 다음과 같은 설정을 했기 때문
  •    
  • 자식 컴포넌트에서 안하면 사용불가
    • (설정 안한 경우)
  • 주의할 !!
  • 자식에서 부모를 부를 사용하는 callbackfromparent 자식 컴포넌트를 배치시킬 때 고정한 이름 때문에 바꿀 없다. (내가 지정한 이름인줄 알고..)

 

 

2.  토큰 자동 갱신 작업

  • 오래있다가 다시 보내니까 TokenExpiredException 발생
  • 일단 다시 로그인해서 토큰 받아와보았음
    • 이건 된다.
    • 나중에 토큰 처리할 방법도 생각해야 할 듯

 

3. 일단 여태까지 로직으로 db저장되는지 보자

  • 파일 저장 루트 설정
  • 저장완료

 

 

3. 문제상황 케이스

  • 사진 없으면 터지는 문제
    • 서버에서 터짐 => 컨트롤러에 해당 파라미터로 매칭되는 메서드 없기 때문
    • 오류 메세지 : 2021-03-20 22:40:45,586 WARN  org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present]

 

  • 영화이름 세팅 안해도 들어감(다른 영화 이름으로 들감)
    • 기입 안한 경우 안잡아주기 때문에 모달창 껏다켜도 전에 선택했던 영화 리뷰로 들어감

 

TODO

1. 리뷰 작성 

  • 프론트
    • 모달창 별점
    •   확인
    • Review 별점 저장할 필드 만들기
    • Controller에서 파일 없어도 저장되게 처리

 

 

3/19 (금)

Today's task

1.  게시물 작성 : 네이버 API와 연동

  • 네이버 API에서 정보 받아와서 파싱
  • 실시간 렌더링 검색창 구현
  • 별점 모달창
  • Placeholder
  • 이미지 다수로

 

Today I Learn

 

1. 값이 null이거나 undefined인지 검증하기 위해 if(변수명)을 사용할 수 있다.

 

2. Status 코드로 오류의 종류를 구분하기

- 400번대 에러

- 500번대 에러

 

3. 깃

성공..

[참고] http://minsone.github.io/git/how-do-i-clone-all-remote-branch

 

 

 

4. 인텔리제이 에러

 

갑자기 can not resolve ~ 에러가 뜨면서 스프링 인식이 안되었다.

File > Invalidate Caches/restart 로 해결

참고 : https://hyesun03.github.io/2019/08/27/intellij-cannot-resolve-symbol-error/

5.  Naver api 연동

 

TODO

1.  게시물 작성 : 네이버 API와 연동

  • 별점 모달창
  • Placeholder
  • 이미지 다수로

 

 

3/18 (목)

Today's task 

 

1. 프론트

 

2. 백

 

  • 당장 해야하는 작업
    • 회원아닌 사람이 로그인 요청 O
    • 비밀번호 틀릴 O

 

3. 기타

  • 문서 합치기
    • 스토리 보드
    • Api 문서

 

Today I Learn

 

1. Git

  • 협업 방식 FIX
    • Fork 해서 개발 후에 pr 하는 방식은 오픈소스 컨트리뷰트할 사용
    • 기본적인 협업에는 하나의 리포지토리 안에서 브런치를 나눠서 개발 => 이걸로 FIX!
  • 원격 브랜치 가져와서 반영시키기

2. JPA

  • 엔티티 DB 반영 안될 경우 => 연관관계 설정을 살펴봐라

 

3. 토큰 문제 해결방법

  • 원인
    • Back : 노출 헤더를 지정해 주지 않았기 때문에, response 받은 쪽에서 지정된 헤더들만 열람할 있는 문제가 있었다.
    • Front : response header token 담아서 전송했는데, response body 열람하여 token 가져오려 했기 때문에 제대로 token 저장할 없었다.
  • 해결
    • Back : CorsConfig.java 노출 헤더를 설정해주어. 지정된 헤더를 응답 받은 쪽에서 있게 설정하였다.
    • Front : response header에서 authorization으로 token get하여 local storage 저장하였다.

4. 로그인 유무에 따른 메뉴 navbar 분리

  • 메뉴 뷰를 위한 js 만들기 (완료)
    • 로그인된 유저용 MenuForAuthorized.js
    • 로그인 안된 유저용 MenuForUnauthorized.js
  • App.js 라우팅 (완료)
    • Undefined 아닌 null이다. [코드를 제대로 확인하자!]
    • (access === null) ? <로그인 x/> : <로그인 o/>

  • (참고) undefined null 차이: 두 타입 모두 js에서 값이 비어있음을 나타낸다.
    • undefind : 값이 할당되지 않은 변수
      • 변수 선언만 하더라도 undefined 할당됨
      • 타입: undefined
      • : undefined
    • null : 값이 비어있음을 나타냄
      • 변수로 선언한 후에 null 값을 바꿈
      • 타입 : null
      • : null

 

 

5. 없는 아이디로 로그인 경우 처리

  • 기존 로직
    • InternalAuthenticationServiceException 발생

  • 우선 loadUserByUsername에서 멤버 네임 db쿼리

  • 없을 경우 InternalAu~던지게 처리

 

  • unsuccessfulAuthentication() 메서드 발견
    •  Catch문으로 잡아주면 동작안하고, catch 없을 때는 unsuccessful 동작 => 그냥 안쓰는게 나을듯

 

  • This.setState 함수 안에서 사용하는 변수는 const 선언할 필요없다.

 

  • 로컬 스토리지
    • localStorage 저장해 놓은 토큰(로그인 정보) 없애려면?
    • (참고) https://www.zerocho.com/category/HTML&DOM/post/5918515b1ed39f00182d3048
      • 브라우저 저장소 종류
        • 지속적으로 필요한 데이터(자동 로그인) 등을 담는다.
        • 잠깐 동안 필요한 정보(일회성 로그인..) 담는다. 비밀번호 같은 중요한 정보는 저장하기 말아라! 클라이언트에 저장하는 것이기 때문에 언제든 털릴 있다.
          • 로컬 스토리지 : 사용자가 지울 때까지 브라우저에 남아있음
          • 세션 스토리지 : 윈도우나 브라우저 탭을 닫을 경우 제거
    • Front/back 서버를 내렸다 다시 올리는 것은 상관이 없다.
      • localStorage 브라우저에 내장된 저장소의 일종이다.
      • 따라서 캐시를 삭제해야 한다.

 

TODO

1. 게시물 작성 : 네이버 API 연동

  • 네이버 API에서 정보 받아와서 파싱
  • 실시간 렌더링 검색창 구현
  • 별점 모달창
  • Placeholder
  • 이미지 다수로

 

 

3/17 (수)

Today's task 

1. 로그인 토큰으로 인증해서 파일 전송 저장

  • 파일 전송
  • Db 저장(Images, Review)

 

Today I Learn

[TASK1 디버깅 과정]

1. Db 저장 기능

 

2. 테이블 모델링

  • Order Item사이에 OrderItem 놓았듯이,Review Image사이에 ReviewImages 놓아서 사용해야 .
  • 리뷰는 Image 아니라 ImageList 가지고 있게끔
    • => 로그 보니 JPA 자동으로 테이블 만들어서 Insert

 

3. VIEW에서 토큰 가져올 수 없는 문제

  • 원인
    • back : (cors 관련 이슈) response 받는 측에서 header값을 읽을 수 없도록 default 설정되어 있음
    • front : response header에서 authorization이라는 key값으로 value가져와서 저장해야하는데, body에서 찾고 있었음
  • 해결
    • back : cors허용추가(현명님 코드 참고)
    • front : response.headers['authorization']으로 가져와서 세팅하기

 

 

TODO

1. [서버-클라이언트 통신문제] Cors 문제에 대해 확실히 알고 넘어가야 할 것같다.

2. [JPA 설정 문제] CASCADE에 대해 확실히 알고 넘어가야 할 것 같다.

 

3/16 (화)

Today's task 

1. [View] 로그인/회원가입 기능 완성

2. [BACK] 리뷰 업로드 기능 완성

  • TASK1 : 리뷰 엔티티 변경 O
    • 프론트로부터 받은 이미지를 담기 위해서 FILE 엔티티 하나  필요(1-리뷰 : -FILE)
  • TASK2 : 파일 업로드 기능 O
    • application/json 아닌 form-data형식으로 받아와야함
    • Json 이미지를 전송할  없음.
    • 가져온 파일은 resources 폴더에 저장
    • 저장 처리
  • TASK3 : 세션 처리O
    • 권한 있는 사람만 url 요청할  있게 해야하고
    • 파일과 함께 받은 토큰으로 membername 세팅해야한다.

 

Today I Learn

1. VIEW

  • 문제 1 : 리액트에서 문제 있으면 프로젝트 빌드 불가
    • 해결 : npm start로 View단 문제 해결한 뒤에 다시 올려야 함
  • 문제 2 : 로그인한 상태에서 또 다시 회원가입 신청하면 오류남
    • 이유 : 모르겠음====> 해결필요!!!!!!!!!!!!!!!!!!
  • 추가하고 싶은 기능
    • 회원가입에서 중복체크 완료되면 버튼 못누르게 처리하기
    • localStorage에 안전성 이슈가 있다. 캐시에 저장하는 방법 찾기

 

2. GIT

  • 문제 1
    • 원인 :  저장소에 있는거 조직에 PULL REQUEST 하려했음. 그런데 file conflict 발생함. 어차피 조직 저장소에 있는 파일은 사용할 코드가 없었기 때문에 조직 저장소 파일 conflict 나는 파일을 삭제함.
    • 결과:  다 꼬였다….  ==========> 해결필요
    • 배운거
  • 알게 된 것들
    • 인텔리제이에 브랜치 체크아웃한거 반영 안되면 reload from the disk
    • Pull request에서 merge conflict나면 커맨드 라인 추천 참고해라
    • Reset revert 차이(되돌리기)
    • 리포지토리 특정랜치만 가져오기 : git pull 저장소명런치명

 

3. BACK

 

[TASK1 디버깅 과정 (완료)]

 

1. Member - review - image 테스트 : pk 모두 id 놓으면??

  • 컬럼명 id 나옴 => 그래도 구분 가능할둣?

2. Review에서 member로의 @JoinColumn 설정

  • 시도1 : Member 테이블에서 id라고 설정해줬기 때문에 @Joincolumn(id) 설정했다.
    • 결과 : id (should be mapped with insert="false" update="false")
  • 시도 2 : 유튜브를 참고하니 Member 테이블에서 설정한 변수명과 상관없이 @JoinColumn(memerId) 설정하는 것을 보았다. 따라해보았다.
    • 결과 : 성공!
    • 이유 : 해당 테이블에서의 pk 컬럼명을 적는 것이 아니라, 현재 테이블에서 fk 어떤 컬럼명으로 설정할지를 적는 것이다.

[예시1 : 직접   설정  x ( 자동으로   해당  table 명 _ 컬럼명으로   설정하는   듯 )]

 

[예시2 : 직접   설정  (m_id)]

 

3. Review Image 연관관계 설정하기

  • 하나의 게시물이 가진 이미지를 조회하는 기능이 필요(R --> I)
  • 하나의 이미지가 어떤 게시물의 이미지인지 조회? 필요없(I -X-> R)
    • 하나의 게시물이 여러개의 이미지를 가진 1대다 연관관계이다.
    • 단방향 연관관계이다.
    • , '' 이미지가 fk 가지게끔 Image 클래스에 Review 추가한다.
    • 결과 : 성공!!

4. 커밋하는데 갑자기 프론트쪽안된다.

오류 메시지 :npm ERR! code ENOENT

npm ERR! syscall open

npm ERR! path C:\Users\anyej\Downloads\movie_community/package.json

npm ERR! errno -4058

npm ERR! enoent ENOENT: no such file or directory, open 'C:\Users\anyej\Downloads\movie_communnpm ERR! enoent ENOENT: no such file or directory, open 'C:\Users\anyej\Downloads\movie_commun

ity\package.json'

npm ERR! enoent This is related to npm not being able to find a file.

npm ERR! Enoent

 

Enoent: 말 그대로 파일 또는 디렉토리가 없을 경우 나오는 에러이다

    • Package.json 지우고 다시깔라는 글을 봤다…. 이게 뭐지?
      • package.json은 프로젝트 정보와 의존성(dependencies)을 관리하는 문서입니다.
      • 이미 작성된 package.json 문서는 어느 곳에서도 동일한 개발 환경을 구축할 수 있게 해줍니다.
      • JSON 포맷으로 작성해야 하며, 다음과 같은 옵션들이 추가될 수 있습니다.
    • 그럼 설정 다시 해줘야 되는 부분..? 는 바보였따……
    • 해결 : frontend 밑에서 npm start해줘야되는데… 다른 디렉토리에서 실행해서 나온문제 ㅠㅠㅠ 그대로 경로 잘못되서 그런거였음.. 바보멍청아!!!

 

[TASK2 디버깅 과정 (완료)]

1. 파일 업로드 방법?  [참고 : https://caileb.tistory.com/152]

  • 스프링 프레임워크 환경의 서버라면, 스프링에 제공하는 MultipartFile 클래스와 MultipartHttpServletRequest 클래스를 사용해서 File 업로드 기능을 구현할 있다. (Content-Type : multipart/form-data)
  • 3가지 방법
    • @RequestParam MultipartFile 타입 사용
    • SevletRequest 혹은 MultipartHttpServletRequest 타입 사용
    • 사용자 정의 class 타입 사용
  • 1번째 방법의 특징 => 레퍼런스가 있으므로 이걸 써보겠따.
    • 1번째 방법 : 요청파라미터 타입을 @RequestParam 어노테이션과 함께 사용하는 경우
    • (장점) 서버는 클라이언트의 HTTP 요청 메세지에 포함된 파라미터들을 모두 분리해서 컨트롤할 있기 때문에, 요청 파라미터 타입 MultipartFile타입에 해당하는 한가지를 직접 골라서 file데이터를 다룰 있다.
    • (단점) file데이터 외에 다른 파라미터들 (String, Integer, MultipartFile) 몇가지 추가해서 함께 받는 다면 코드가 조금 지저분해질 수도 있다.
  • 3번째 방법의 특징 => 이것도 가눙한가?
    • 해당 클래스를 정의할 File 받을 있는 MultipartFile 타입 변수를 클래스내에 함께 작성해두면 된다.
    • 3번째 방법: 요청파라미터 타입을 사용자가 정의한 클래스 타입(커맨드 객체)으로 사용하는 경우.
      • 서버는 클라이언트의 HTTP 요청 메세지에 포함된 파라미터들이 모두 자동으로 사용자가 정의한 클래스의 구조에 맞게 파싱되기 때문에, 개발자는 하나의 Command Object 컨트롤할 있다.
      • (장점) 요청 파라미터를 여러 받는 것다 코드가 훨씬 깔끔해질 있다. 선호하는 사람 많음

2. Getinthere 따라하기 [https://blog.naver.com/getinthere/221735956499]

 

  • 저장 성공
    토큰 없이 멤버 직접 생성해서 리뷰저장 성공
    • 그런데 생각해보니까 image 엔티티만 만들어놓고 엔티티를 다룰 repository 안만들어

 

4. 이미지와 리뷰? 양방향이다.

  • 리뷰에서도 이미지 가지고 있어야 .

5. Arrays.asList 쓰니까 이상한 들어간다.

  • 그냥 new 생성해줘서 해결

 

[TASK3 디버깅 과정]

1. 토큰 인증으로 로그인해서 리뷰 저장하기

  • 실행 결과 : detached entity passed to persist: com.codeworrisors.Movie_Community_Web.model.Member
  • 토큰으로 인증하는 코드에서 db 해당 멤버 정보를 넣으려하는 같다.
  • 연관관계 설정 문제임

 

TODO

1. 토큰 인증 로그인 완료하기

- 테이블 재설계(각 객체 연관관계 설정) 

- CASCADE?

 

 

 

3/15 (월)

Today's task 

1. 로그인, 회원가입 UI

2. 스토리지 저장기능 연동

3. 로그아웃 기능

4. 로그인, 회원가입 로직 수정하기

  • CASE
    • 중복체크 이후에 다른 아이디 입력하고 가입하는 경우
    • 정보 : id 찾아서 set 호출하
    • 비밀번호 문자, 숫자, 특수문자 포함 확인
  • UI 수정
    • 중복 체크 버튼 크기
    • 필수 사항에 빨간 체크
    • 비밀번호 확인 이후 초록색으로 변경

 

Today I Learn

1. 에자일개발론, 스크럼개발론, MVP개발방식

  • 에자일 방식
    • 짧은 단위의 작업 계획 구축 : (~4/3 까지)
    • 가지 기능에 대한 시제품을 만들어 나가는 사이클을 반복 : 기능별로 스프린트 나눠서 개발
  • 스크럼 개발방법론(애자일 개발과정의 하나) https://medium.com/dtevangelist/scrum-dfc6523a3604
    • 제품 백로그 : 개발할 제품의 전체 요구사항
    • 스프린트 : 계획, 개발, 리뷰 작업 단계를 포함하는 하나의 사이클(보통 1~4)
    • 일일 스크럼 회의 : 매일 어제 한일, 오늘 할일, 해결해야 장애/문제 요소를 공유하는 회의(매일 15 정도 수행)
    • 스프린트 리뷰 : 스프린트 마지막날 개발자가 개발한 내용을 시연하고 검토( 스프린트마다 1 4시간)
    • 스프린트 회고 : 스프린트 마지막날 좋았던 , 개선할 점을 도출하고 나은 방향으로 개선

2. 로그인, 회원가입 UI [코드 참고 : https://www.remotestack.io/react-bootstrap-login-register-ui-templates/]

 

 1) 부트스트랩 사용하기

  • npm install bootstrap --save
  • Src/App.js import 하기

2) LoginComponent.jsx 로그인 페이지 구현

  • loginApp 안써도 될듯.
  • LoginComponent App.js 연결됨

3) SignupComponent.jsx [서비스 따로 두지 않기->로그인처럼 인증관련 서비스 많지 않기 때문]

  • 회원가입
    • Input tag onchange={changeHandler}에서 Name 기준으로 현재의 value값을 넣어준다.
    • onChange 이벤트가 발생하면, e.target.value 값을 통하여 이벤트 객체에 담겨있는 현재의 텍스트 값을 읽어올 수 있습니다.

 

TODO

1. [View] 로그인/회원가입 기능 마무리

 

 

 

2주차 (3/8~3/14)

3/14 (일)

Today's task

1. 게시물 작성 백엔드 기능

- Review 엔티티 만들기

- DB 저장

- 테스트 코드 

 

Today I Learn

1. GIT

1) 브랜치 지우기

- 로컬 브랜치 지우기 : git branch -d feature/createboard

- 원격 브랜치 지우기 : git push origin --delete feature/createboard

 

2. 백단

1) 회원가입 로직 수정 필요성

- 다른 아이디로 중복확인하고, 새로운 아이디로 회원가입 가능함(db에 이미 있는 id면 가입 제대로 안될 것)

- 주소 API 사용하기 

- 빨간색으로 필수로 넣어야할 영역 표시하기 

- 아이디 중복확인 버튼 오른쪽으로 밀기

- 생년월일/휴대폰번호에 문자 들어가면 안되게 하기

- 잘못된 이메일 형식 막기

- 새로고침? X (form으로 되어있기 때문)

 

2) 리뷰게시물 CRUD 로직 (멤버와 1:N)

- Review 엔티티 생성하기 => 시퀀스 생성오류

  • 내용 : @GeneratedValue(GenerationType.IDENTITY) 라인에서org.hibernate.dialect.identity.IdentityColumnSupportImpl does not support identity key generation 오류 발생
  • 해결방법
  • 문제원인
    • 첫번째 해결방법 설명 : 사용중인 Oracle10g 버전에서는 해당 어노테이션 지원불가
    • 현명님 설명 : IDENTITY는 MY SQL등 AUTO INCREMENT가 가능한 시스템에서 사용하는 방식이다. 오라클은 사용할 수없?  

3) 생성자 어노테이션 사용법

  • allArgumentConstructor => 전체 생성자
  • NoArgumentConstructor => 디폴트 생성자
  • Required =>생성자에서 필요한 의존성 주입

4) JUnit 테스트

  • 코드 참고 : https://stackoverflow.com/questions/41315386/spring-boot-1-4-datajpatest-error-creating-bean-with-name-datasource
  • 설명 참고 : https://4whomtbts.tistory.com/128
  • 1) 테스트 러너 설정 : @RunWith(JUnit 기본 러너 대신 사용할 러너를 지정)
    • 러너 : 테스트 실행 프로세스를 계획하고 실행시키는 주체
    • SpringRunner : SpringJUnit4ClassRunner의 단축어
      • 특징 : 유닛 테스트 전에 Spring container를 시작하는 작업을 포함하기 때문에 오버헤드가 크다.
      • 써야하는 상황
        • 컴포넌트 주입이 필요할 때
        • 설정 데이터 주입이 필요할 때
        • 따라서 스프링과 관계없는 기능을 테스트할 때는 사용을 지양하자.
  • 2) @RunWith와 @SpringBootTest의 차이
    • 전자가 더 가볍다. 일부 스프링 기능만을 사용
    • 후자는 ApplicationContext를 모두 적재하기 때문에 시간이 오래걸린다.
  • 3) @DataJpaTest
    • JUnit4를 사용하면 @DataJpaTest를 사용할 때 반드시 @RunWith(SpringRunner.class)를 해줘야 한다.
  • 4) @AutoConfigureTestDatabase 속성
    • Replace.None : 프로퍼티스 파일에 설정해놓은 DB
    • Replace.ANY : 내장 DB
  • 5) @DataJpaTest : 각 테스트 메서드마다 테스트 따로 실행가능하다.
  • 6) 생성자 주입한 경우 테스트 사용방법 구현해보았다.

5) Review CRUD기능

 

  • 1) 서버
    • @RequestBody를 메서드 인자에 넣어줘야 클라이언트로부터 값을 받을 수 있다.
    • JPARepository CRUD 메서드
      • CREATE : 모든 컬럼값이 있어야 정상적으로 삽입가능
      • UPDATE : PK값만 있으면 업데이트 가능
        • 프론트에서 이전의 상태까지 모두 가지고 있다가, 수정된 부분만 수정해서 전체 내용 보내줘야 제대로 수정가능할 듯? 아니면 save() 호출하면서 다른 부분 다 NULL될 거 같다.
      • DELETE : PK값만 있으면 삭제가능. 
        • 존재하지 않는 PK값으로 호출해도 exception 안던진다.
  • 2) 클라이언트
    • 삽입 Request 보낼 때 모든 컬럼값을 key로 설정해줘야 (따로 세팅을 하지 않는다면) null로 삽입되지 않는다.
      • {
      •    "content" : "time need?",
      •    "movieTitle" : "zxcv",
      •    "imageUrl" : "zxcv",
      •     "createDate" : "" // 어차피 timeStamp 찍지만 써줘야 된다.
      • }

6)  DATA JPA CRUD TEST 참고 자료

 

TODO

1. 시큐리티 마무리

- UI 변경

   - 로그인

   - 회원가입

   - 스토리지에 토큰 저장

 

2. 애자일 방식 적용해보기

 

 

 

 

3/13 (토) => 코테

Today's task

Today I Learn

TODO

 

3/12 (금)

Today's task

1. 프로젝트에 적용하기

- 백단 : 시큐리티로 로그인 처리, 인가 처리

 

 

Today I Learn

1. 시큐리티 노트에 써놓음 

 

 

TODO

1. [시큐리티]UI 변경

2. [게시물 작성] 스프린트 시작

- API 설정

- 역할 나누기 전에 먼저 현명님이랑 조금씩 진행

   - 뷰/백

 

3/11 (목)

Today's task

1. 시큐리티 플젝 따라하면서 공부 (데어프로그래밍) (완료)

- JWT 플젝 실습 (완료)

2. 프로젝트에 적용하기

- 백단 : 시큐리티로 로그인 처리, 인가 처리 (미완)

 

Today I Learn

1) 회원가입 완료되어 있는 아이디로 로그인 요청시 401 unAuthorized error 발생

- '/join'을 처리하는 메서드가 Controller에 없었기 때문에 `asdf`, `asdf`로 직접 암호화를 하여 DB에 INSERT를 했다. 

- DB에 직접 저장한 비밀번호와 클라이언트로부터 받아와서 BCyrpt~얘로 암호화한 값이 달라서 생기는 문제였다. 

- DB를 클리어하고, '/join' 메서드를 만들어 서버에서 회원가입이 되도록한 뒤에 요청하니 해결되었다. 

 

1-1) 에러

 

회원가입되어 있는 ID,PWD로 요청
콘솔 에러

 

1-2) 해결 :  서버에서 회원가입 후 로그인 시도

 

response로 회원가입 완료 msg 받았다.
서버 : 인증 성공 메세지
일부러 db와 일치하지 않는 password로 로그인 요청을 보내 보았다. 아까와 동일한 403에러가 발생.

 

 

 

2) @RequiredArgsConstructor 어노테이션 쓰임

- 클래스에 선언해 놓은 인스턴스 변수에 대한 생성자가 필요할 때 코드를 작성할 필요없이, 필요한 파라미터 값을 모두 가진 생성자를 자동생성해주는 어노테이션

 

@RequiredArgsConstructor를 사용해서 ... @Autowired이거 안써도 하튼 필드에 있는 인스턴스 변수 생성자 만들어주는듯...? (약간 확실치 않음)

 

 

3) jwt + 시큐리티 프로젝트 실습

 

이 부분 주석 안하면 요청 제대로 안간다

 

 

 

TODO

1. 프로젝트에 적용하기

- 백단 : 시큐리티로 로그인 처리, 인가 처리

 

 

3/10 (수)

Today's task

1. 전체 프로젝트 진행방향 회의 (완료)

 - 시큐리티 (~3/11 목) 

 - 다음 스프린트 6일씩 잡고, 매 스프린트마다 `api 설정`, `뷰`, `백`, `테스트`, `문서 정리` 로 진행

2. 시큐리티 플젝 따라하면서 공부 (데어프로그래밍)

- OAuth 2.0 플젝 실습 (완료)

- JWT 실습 전 기본 지식 (완료)

- JWT 플젝 실습 (미완)

 

Today I Learn

1) [JPA] JPA의 등장 배경 : sgc109.github.io/2020/07/26/jpa-basic/

-  SQL 작성 안하게

- 코드가 DB에 의존하지 않게 => 따라서 upload와 같은 테이블 엔티티도 필요한 것

 

2) [GIT] 새로 생성한 로컬 저장소 원격 저장소와 연결하기

 

 

 

TODO

1. 시큐리티 플젝 따라하면서 공부 (데어프로그래밍) 

- JWT 플젝 실습 

2. 프로젝트에 적용하기

- 백단 : 시큐리티로 로그인 처리, 인가 처리 

 

3/9 (화)

Today's task

1. 사용자 도메인 수정 -> (현재) api/members/join에서 아이디 중복체크 -> (변경 후) api/members/checkid로 중복체크 후 join으로 바로 가입 (완료)

2. [Front]

- fetch -> axios로 변경 (미완)

- feature/logjoin develop에 머지하기 (완료)

- feature/Client에 백단 로직 반영하기 (완료)

3. 전체 프로젝트 계획 세우기(~4/3) 

4. 스프링 시큐리티 공부 방향 잡기

- 기본 흐름 잡기 (테코톡) (완료)

- 시큐리티 플젝 따라하면서 공부 (데어프로그래밍) (미완)

 

Today I Learn

1. [GIT] branch merge 방법 (빨리감기)

- logjoin브랜치 일단 devleop pull 해서 똑같이 만든 후에 develop에 merge

- fast forward 식 merge

   - backlog.com/git-tutorial/kr/stepup/stepup2_4.html

 

2. [Back]

1) 클라이언트에서 JSON값 받아올 때 모든 요청은 (@RequestBody Member member)로 받아오는 것이 낫다.

- (String id)로 받아오게 되면, parsing  따로 해줘야하기 때문에 귀찮아진다.

2) 생성자 주입 쓰는 경우에 testcode? 

- 참고 : velog.io/@noyo0123/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-%EB%94%B0%EB%9D%BC%ED%95%98%EA%B8%B0-2.-spring-boot-JPA%EB%A1%9C-API-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EA%B8%B0-f8k3xweeka

 

3. [Front]

1) memberPassword2 undefined 에러.

- 비밀번호 확인 기능 넣으면서 생성자의 this.state= {}에 해당 변수를 초기화하지 않았다.

 

생성자에서 초기화 해주면 undefined 아니라서 해결

 

 

2) App.js 에 오탈자 제거

 

이상해졌다
여기 오타가 잇었군.
해결

 

 

3) 자바스크립트에서 json 타입의 변수는 일반변수와 선언방식이 다르다!!

- const {data} = {}가 아니라 const data = {}

 

 

 

 

4) memberIdIsPossible 변수 value 변화 안됨.

- fetch()는 비동기로 처리되기 때문에 setState()는 값이 담기기전에 처리되서 response로 받아온 값으로 초기화가 안되었다.

 

 

 

 

5) fetch 안에서 바로 setstate() 못하는 문제

- 다음과 같이 that이라는 지역변수를 사용해서 해결했다.

stackoverflow.com/questions/49684217/how-to-use-fetch-api-in-react-to-setstate

 

 

 

TODO

1. 전체 플젝 방향 회의

2. 스프링 시큐리티 공부 방향 잡기

- 기본 흐름 잡기 (테코톡) (완료)

- 시큐리티 플젝 따라하면서 공부 (데어프로그래밍)

 

3/8 (월)

Today's task

1. [피드백] @Data 어노테이션 대체하기

2. [피드백] @Autowired 생성자 DI 주입

3. [Back] 사용자 도메인 - 수정, 삭제 기능 추가

4. [Front] 아이디 중복확인, 비밀번호 일치여부 확인, 공백 체크 기능 추가

 

Today I Learn

1. [Back]

A) lombok : JPA와 같은 ORM을 사용할 때, @Data 어노테이션을 사용하면 안되는 이유

- 참고 : velog.io/@jayjay28/%EC%9E%90%EC%A3%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-Lombok-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98

   - @Data 어노테이션은 @toString을 포함한다.

   - 객체가 서로를 참조하고 있을 때 toString이 호출되면, 무한 루프에 빠지게 된다. 

public class Member {
  private String id;
  private String pw;
  
  private Address addr;
  
  @Override
  public String toString() {
    
    return "Member [id=" + id + ", pw=" + pw + ", addr=" + addr + "];"// Address의 인스턴스를 참조
  }
}

public class Address {
  private String zipcode;
  private Member member;
  
  @Override
  public String toString() {
    
    return "Address [zipcode=" + zipcode + ", member=" + member + "]";    // Member의 인스턴스를 참조

  }
}

 

B) Spring Framework : 의존성 주입시 필드/세터 주입보다 생성자 주입을 권장하는 이유

- 참고 : madplay.github.io/post/why-constructor-injection-is-better-than-field-injection

- 순환 참조 방지 : 프로젝트가 커지면 여러 컴포넌트 간에 의존성이 생긴다. 비즈니스 로직으로 인하여 서로의 메서드를 순환 참조하는 형태의 코드가 짜질 수 있다(객체 지향적인 관점에서 아주 안 좋음). 필드/세터 주입에서는 오류 없이 동작하지만 stackoverflow 런타임에러가 발생한다. 생성자 주입에서는 BeanCurrentlyInCreationException 예외가 발생하여 어플리케이션 자체가 구동되지 않는다. 따라서 발생할 수 있는 오류를 사전에 체크할 수 있다.

- 테스트에 용이 : 매우 간단하게 테스트코드를 작성할 수 있다.

SomeObject someObject = new SomeObject();
MadComponent madComponent = new MadComponent(someObject);
madComponent.someMadPlay();

- 불변성 : 필드 주입과 세터 주입은 해당 필드를 final로 선언할 수 없기 때문에, 초기화 이후에도 Bean 객체가 변경될 여지가 있다. 하지만 생성자 주입은 필드를 final로 선언할 수 있기 때문에, 런타임 환경에서 객체가 변경될 때(일어나기 힘든 경우지만) 발생할 수 있는 오류를 사전에 방지할 수 있다.

@Service
public class MadPlayService {
    private final MadPlayRepository madPlayRepository;

    public MadPlayService(MadPlayRepository madPlayRepository) {
        this.madPlayRepository = madPlayRepository;
    }
}

 

 

2. [Front] React

- input 태그의 value get : const {name} = this.state;

- this.state 인식 못함 => bind 문제 (constructor에서 bind)

 

 

- 비밀번호 일치 체크 : onkeyup 이벤트 사용

 

 

-아이디 중복체크 : JSON 반환값 처리

 

button에 콜백메서드 등록
application/json으로 전송후 json으로 accept. stringify로 반환값 변환

 

- submit 전 공백 체크

 

 

 

- e.preventDefault()란? 기본적으로 정의된 이벤트를 작동하지 못하게 한다. 

form에서 onSubmit()을 통해 submit을 하면 이벤트 완료 후 refresh가 된다.

하지만 리액트로 만드는 SPA 앱에서 원하는 이벤트가 아니다.

따라서 e.preventDefault()를 활용하여 추가로 이벤트를 전파하지 않고 취소하게끔 설계하는 것이다. 

**checkID로 아이디 중복체크하는 함수에서도 써줘야 함

 

- 코드 수정이 브라우저에서 반영안될 경우 => 캐시 삭제해보기

 

 

 

 

3. [GIT] 잘못된 브랜치에서 작업하고 있었을 때 checkout 시도 => overwritten 경고 오류 해결

- 참고 : blog.hodory.dev/2020/02/18/error-Your-local-changes-would-be-overwritten-by-merge/

- git stash : 현재 staging 영역에 있는 파일의 변경사항을 스택에 넣어둔다.

- git checkout origin feature/logjoin : 이동

- git stash pop : stash 명령어로 스택에 넣어둔 변경 사항 auto 적용시킨다

- intellij 의 resolve conflict로 사용할 코드 선택

- git commit 

- git push origin feature/logjoin

 

*아이텀 : git bash 명령어 자동완성

**logjoin에 frontend 디렉토리 ...

 

 

 

Todo

1. 사용자 도메인 수정 -> (현재) api/members/join에서 아이디 중복체크 -> (변경 후) api/members/checkid로 중복체크 후 join으로 바로 가입 

2. [Front]

- fetch -> axios로 변경

- feature/logjoin develop에 머지하기

- feature/Client에 백단 로직 반영하기

3. [GIT] intellij git authorization 문제 해결

4. 전체 프로젝트 계획 세우기(~4/3)

 


1주차

 

3/5 (금)

Today's task

1. 회원가입, 로그인 로직 (사용자 기능 로직 짜기) *spring data jpa로 

- 패키지 구조, 클래스명 다르니까 merge시 conflict 발생했다.

2. git branch : master > dev > feature/members... 로 파서 진행 => 제대로 정리하기 

3. 프로젝트용 오라클 접속 계정 만들기 

 

 

Today I Learn

1) [GIT] 자주쓰는 명령어

- 원격저장소에 새로 등록된 브랜치 로컬저장소로 가져오기 : git remote update

- 현재 branch에 새로 update된 내용 가져오기 : git pull

- dev에서 분기해서 feature/xx 작업하기 : git checkout -b feature/login dev

- feature/xx 작업 완료 이후 dev에 반영하기 

- merge conflict 날 때 해결방법 : intellij에서 unstashchanges 체크하고 다시 merge

 

 

 

 

2. [Oracle] 접속 계정 생성(develop , 1234)

otrodevym.tistory.com/entry/oracle-%EA%B3%84%EC%A0%95-%EB%A7%8C%EB%93%A4%EA%B8%B0-%EB%B0%8F-sql-developer-%EC%83%88-%EC%A0%91%EC%86%8D-%ED%95%98%EA%B8%B0

 

3. postman 사용법

testmanager.tistory.com/342

 

join 예시

 

 

Todo

- 회원 수정, 삭제 기능 추가

- 게시글 생성 기능

 

 

 

3/4 (목)

Today's task

1. [완료] oracle - spring 연동 문제 해결

1. [미완] spring data jpa로 변경

2. [완료] join/login/front 머지하기

 

Today I Learn

1) git dev 아래 feature/join 넣는 법 => checkout 옵션=> 정리*************

 

 

Todo

- 구조도 다시 짜기 (머지하니까 다 겹쳐...conflict 대박임)

- 현명님이랑 나눠서 구조 다시?

- spring data jpa로 변경

 

3/3 (수)

Today's task

1.[완료] 회원가입 기능 버그 고치기

- 문제원인 : <createUserFrom.html> input 태그에 'name'값을 VO의 변수명과 동일하게 설정해야 한다. 'id'값이 아님

2.[완료] oracle 11g - spring - jpa 연동

3.[완료] git branch 따로 파서 작업하기 [master -> dev -> feature/join]

 

Today I Learn

1) [해결] 회원가입 기능 디버깅

- createUserForm.html에서 submit한 이후부터 정상적으로 작동하지 않았다. (500 error - whitelabel...)

- join()과 관련 메서드는 이미 단위 테스트를 했기 때문에 백단의 문제는 아니었다.

- 콘솔에 찍어보니 html파일에서 값을 제대로 받아오지 못했다. 

- 문제는 input 태그에 name 속성을 주지 않았기 때문이었다. id를 name과 혼동했다.

- Spring은 input의 'name'을 기준으로 VO의 변수명과 대조해보고 객체를 만들어 반환하기 때문에 반드시 name 속성을 줘야 한다.

2) [해결] 깃 작업 브랜치 분기

- 내가 작업할 브랜치를 생성하고 체크아웃하면 생성한 브랜치(내 작업 브랜치)로 이동한다.

- 작업한 결과를 커밋, 푸시하면 원격 저장소에 있는 해당 작업 브랜치에만 작업 결과가 반영된다. (아직 merge, pull request.. 할 필요없음)

3) oracle 11g + spring 연동

- sql developer나 intellij의 datasource에서 접근하는 건 문제 없었다.

- 근데 spring 프로젝트가 db에 접근을 못한다. 왤까....

- 현명님이 docker 환경에서 실행하신건 괜찮았눈데, 고쳐봐야겠답.

4) [해결] oracle ID, PWD 헷갈려 ㅇㅂㅇ

- id: system, pwd: 1220

5) [해결] Oracle 예약어 컬럼명으로 설정할 경우 에러

- USER 테이블의 PK를 'UID'라는 컬럼명으로 설정하기로 했다. 그런데 'UID' 오라클 예약어이기 때문에 오류가 있었다. 예약어 잘 알아보고 컬럼 설정해야할 듯

- UID(시퀀스) 컬럼을 굳이 둘 필요없이 USER_ID(VARCHAR2)를 PK로 두면 될 것같다. (참고. www.gurubee.net/article/66137)

6) 프로세스 id 찾기

- netstat -ano | findstr 8080

 

 

Todo

- 회원가입 기능 oracle+spring data jpa로 변경

- login/join/front 머지해보기

 

3/2 (화) 

Today's task

1. 회원가입 기능 구현 *인프런 김영한 스프링 기본 참고 (완료)

- 요구사항 : 스프링 부트, MVC 패턴

 

Today I Learn

1) [해결] Intellij가 종종 Spring 라이브러리를 제대로 인식하지 못하는 문제가 있었다. 

- 해당 프로젝트 내의 .idea 디렉토리를 설치한 뒤에 인텔리제이를 시작해서 라이브러리를 다시 설치하게 해서 문제를 해결했다.

2) [해결] thymeleaf 템플릿엔진으로 html을 랜더링 한 뒤에, 사용자로부터 정보를 받아와서 map형태로 저장하는 기능을 구현했다. 하지만 memory 저장이 안되는 문제가 있었다. 

- input 태그에 'name'값을 VO이름과 동일하게 설정해야 한다. 'id'값이 아님

 

Todo

- 회원가입 기능 버그 고치기 (html로부터 읽어들인 내용 map에 저장 안되는 문제)

- 오라클 설치하고 spring에 설정파일 입력

- git branch -> dev -> function/join 에서 작업하기