1. 어려웠던 부분 : 백엔드는 거의 기능구현이 완료되서 오늘 패키지를 어떻게 분리하는게 좋을지 팀원들과 논의해보는 시간을 가졌다. 아직 우리가 구현한 서비스의 스코프가 작다보니 계속 사용해오던 계층형 구조를 사용하는게 좋겠다는 생각을 했다. 그러나 한가지 더 고민 됐던 부분은 S3나 이메일 인증, 그리고 카카오로그인과 같은 기능구현들은 따로 패키지를 빼는게 좋을지 고민하게 되었다. 일단 우리는 다음 프로젝트때 코드 재사용과 이해하는데 유용하게 사용하기 위해 common이라는 패키지안데 각각의 기능들을 담은 패키지를 배치하였다. 근데 이게 좋은 방법인지는 잘 모르겠다.

 

2. 느낀 점 : 거의 다 끝났다고 생각했지만, 끝날때까지 끝난게 아니라는 말이 딱 맞다. 프론트엔드와 코드를 합치면서 자잘하게 수정해야할 사항들이 계속 생긴다. 오늘은 비회원 전용 API를 추가로 구현하여 프론트엔드와 맞춰보았다. 그래도 지난주에비해 이런 협업 작업들이 익숙해 지는 것 같다. 그리고 백엔드끼리 서로 구현하는 부분에 발생한 문제들을 같이 고민하고 해결하는 과정이 참 좋은 것 같다. 나중에 회사에 가더라도 이렇게 물어보고 같이 고민할 수 있는 동료가 있으면 좋겠다고 생각했다.

 

3. 새로 알게 된 내용 : 오늘 자잘한 오류중 하나가 LocalDateTime이 원래는 문자열 형태로 반환되었는데, 갑자기 배열 형태로 나타나는 문제였다. 일단 구글링 검색을 통해 @JsonFormat 어노테이션을 사용하여 문자열로 다시 바꿔주긴 했는데, 기술매니저님께 물어보니 어쩌면 배열로 나오는 타입이 프론트엔드에서 처리하기 더 편할 수도 있으니 이 부분은 상황에 맞게 대처하는게 좋다는 피드백을 주셨다.

 

4. 셀프칭찬 (오늘 잘한 일) : 처음으로 패키지 구조에대해 생각해보는 시간을 가졌다. 추가로 자바 언어공부도 진행하였다. 시간에 여유가 있어서 쉬고 싶은 마음도 있었지만, 그 시간을 이용해 자바공부를 진행해 하루를 알차게 보낸 나를 칭찬한다.

 

5. 내일 할 일 : 클론프로젝트 트러블슈팅 정리, 발표 준비, 깃헙 리드미작성, 서비스아키텍쳐 만들기 ! 


[오늘 공부한 부분] 

 

 

[32] JAVA 입출력 스트림

스트림이란? 자바에서 데이터는 스트림(Stream)을 통해 입출력 된다. 스트림이란 단일 방향으로 연속적으로 흘러가는 것을 의미하는데, 데이터가 출발지에서 도착지로 흘러가는 것을 의미한다.

leejincha.tistory.com

 

계층구조 참고 자료  : https://hyeran-story.tistory.com/160

 

스프링 패키지 구조(Spring Package Structure) - 계층형 vs 도메인형

주절주절,,🗣 회사 프로젝트가 기존에는 모두 계층형이었으나, 이번에 한 프로젝트를 전체 리팩토링 하면서 도메인형으로 변경하게 되었다. 이로써 이제 계층형과 도메인형도 혼합되어 존재하

hyeran-story.tistory.com

 

스트림이란?

자바에서 데이터는 스트림(Stream)을 통해 입출력 된다.

스트림이란 단일 방향으로 연속적으로 흘러가는 것을 의미하는데, 데이터가 출발지에서 도착지로 흘러가는 것을 의미한다.

  • 입력 스트림(InputStream) : 프로그램으로 데이터를 읽어드리는 스트림. 프로그램이 도착지인 경우 사용
  • 출력 스트림(OutputStream) : 프로그램으로 데이터를 내보내내는 스트림. 프로그램이 출발지인 경우 사용

 

https://kerpect.tistory.com/52

 

입출력 스트림의 종류

  • 바이트(Byte)기반 스트림: 그림, 멀티미디어 등의 바이너리 데이터를 읽고 출력할 때 사용
  • 문자(Character)기반 스트림: 문지 데이터를 읽고 출력할 때 사용
구분 바이트 기반 스트림 문자기반 스트림
입력 스트림 출력 스트림 입력 스트림 출력 스트림
최상위 클래스 InPutStream OutputStream Reader Writer
하위 클래스(예) XXXInPutStream
( FileInPutStream )
XXXOutputStream
( FileOutputStream )
XXXReader
( FileReader )
XXXWriter
( FileWriter )

 

바이트 출력 스트림 : OutputStream

  • OutputStream은 바이트 기반 출력 스트림의 최상위 클래스로 추상클래스 이다.

 

https://www.javadeploy.com/java-streams/module2/input-output-stream-subclasses.jsp

 

  • OutputStream의 주요 메소드
리턴타입 메소드 설명
void write(int b)  1byte를 출력합니다.
void write(byte[ ] b)  매개값으로 주어진 배열 b의 모든 바이트를 출력합니다.
void write(byte[ ] b, int off, int len)  매개값으로 주어진 배열 b[off]부터 len개까지의 바이트를 출력합니다.
void flush()  출력 버퍼에 잔류하는 모든 바이트를 출력합니다.
void close()  출력 스트림을 닫습니다.

 

바이트 입력 스트림 : InputStream

  • InputStream은 바이트 기반 출력 스트림의 최상위 클래스로 추상클래스 이다.
  • InputStream의 주요 메소드
리턴 타입 메소드 설명
int read()  1byte를 읽고 읽은 바이트를 리턴합니다.
int read(byte[ ] b)  읽은 바이트를 매개값으로 주어진 배열에 저장하고 읽은 바이트 수를 리턴합니다.
int read(byte[ ] b, int off, int len)  len개의 바이트를 읽고 매개값으로 주어진 배열에서 b[off]부터 len개까지 저장합니다. 그리고 읽은 바이트 수를 리턴합니다.
void close()  입력 스트림을 닫습니다.

 

문자 출력 스트림 : Writer

 

https://xzio.tistory.com/312

 

  • Writer는 문자 기반 출력 스트림의 최상위 클래스로 추상 클래스이다.
  • Writer 클래스의 주요 메소드
리턴 타입 메소드 설명
void write(int c)  매개값으로 주어진 한 문자를 보냅니다.
void write(char[ ] cbuf)  매개값으로 주어진 배열의 모든 문자를 보냅니다.
void write(char[ ] cbuf, int off, int len)  매개값으로 주어진 배열에서 cbuf[off]부터 len까지의 문자를 보냅니다.
void write(String str)  매개값으로 주어진 문자열 보냅니다.
void write(String str, int off, int len)  매개값으로 주어진 문자열에서 off 순번부터 len개까지의 문자를 보냅니다.
void flush()  버퍼에 잔류하는 모든 문자를 출력합니다.
void close()  출력 스트림을 닫습니다.

 

문자 입력 스트림 : Reader

  • Reader는 문자 기반 입력 스트림의 취상위 클래스로 추상클래스 이다.
  • Reader의 주요 메소드
리턴 타입 메소드 설명
int read()  1개의 문자를 읽고 리턴합니다.
int read(char[ ] cbuf)  읽은 문자를 매개값으로 주어진 문자 배열에 저장하고 읽은 문자수를 리턴합니다.
int read(char[ ] cbuf, int off, int len) len개의 문자를 읽고 매개값으로 주어진 문자 배열에서 cbuf[off]부터 len개까지 저장합니다. 그리고 읽은 문자 수를 리턴합니다.
void close()  입력 스트림을 닫습니다.

 


 [ 키워드 정리 ] 

  • 입출력 스트림 : 자바에서 데이터는 스트림을 통해 입출력됩니다. 프로그램이 출발지냐 또는 도착지냐에 따라서 사용하는 스트림의 종류가 결정됩니다. 프로그램이 도착지이면 흘러온 데이터를 입력받아야 하므로 입력 스트림을 사용합니다. 반대로 프로그램이 출발지면 데이터를 출력해야 하므로 출력 스트림을 사용합니다.
  • InputStream : 바이트 기반 입력 스트림의 최상위 클래스로 추상 클래스입니다. 모든 바이트 기반 입력 스트림은 InputStream 클래스를 상속받아서 만들어집니다. InputStream 클래스에는 바이트 기반 입력 스트림이 기본적으로 가져야 할 메소드가 정의되어 있습니다.
  • OutputStream : 바이트 기반 출력 스트림의 최상위 클래스로 추상 클래스입니다. 모든 바이트 기반 출력 스트림 클래스는 OutputStream 클래스를 상속받아서 만들어집니다. OutputStream 클래스에는 모든 바이트 기반 출력 스트림이 기본적으로 가져가야 할 메소드가 정의되어 있습니다.
  • Reader : 문자 기반 입력 스트림의 최상위 클래스로 추상 클래스입니다. 모든 문자 기반 입력스트림은 Reader 클래스를 상속받아서 만들어집니다. Reader 클래스에는 문자 기반 입력 스트림이 기본적으로 가져야 할 메소드가 정의되어 있습니다.
  • Writer : 문자 기반 출력 스트림의 최상위 클래스로 추상 클래스입니다. 모든 문자 기반 출력 스트림 클래스는 Writer 클래스를 상속받아서 만들어집니다. Writer 클래스는 모든 문자 기반 출력 스트림이 기본적으로 가져야 할 메소드가 정의되어 있습니다.

출처 : 혼자 공부하는 자바 - 신용권 지음

'Coding > Java' 카테고리의 다른 글

[33] JAVA 보조 스트림  (2) 2023.01.24
[31] JAVA LIFO와 FIFO 컬렉션  (0) 2022.12.25
[30] JAVA 컬렉션 프레임워크  (0) 2022.12.25
[29] JAVA 스레드 제어  (0) 2022.12.21
[28] JAVA 멀티스레드  (0) 2022.12.21

 

1. 어려웠던 부분 : 오늘 메인페이지의 주요 기능들을 프론트엔드와 합쳐보는 작업을 했다. 지난주 경험 덕분에 훨씬 수월하긴 했으나, 역시나 맞춰보면서 수정해야할 부분들이 계속 생겼다. 예를 들면, 좀더 프론트에서 처리하기 쉬운 반환타입으로 코드를 바꿔주는 작업이라 던가, 필요한 API를 추가한다던가 하는 작업이 있었다. 아무래도 빠른 시간 내에 코들르 구현해서 수정해야하다보니 그 부분이 어려웠던 것 같다.

 

2. 느낀 점 : 백지장도 맞들면 낫다, 집단 지성, 이 두 문장을 정말 팀원들가 많이 얘기하는 것 같다. 좋은 팀원들을 만나서 에러가 터질때마다 같이 알아보고 연구하고 어떤게 좋은 방법일지 토론해 보는 시간이 참 좋은 것 같다.

 

3. 새로 알게 된 내용 : 필터링 기능 구현을 Spring JPA Data가 제공하는 쿼리만으론 해결할 수 없어서 @Param과 native query 사용해서 해결을 했다. 팀원들 덕분에 이메일 인증구현이 어떻게 돌아가는지, 필터링 기능은 어떻게 되는지, 그리고 Swagger를 사용하는 법과 사용시 이점을 배울 수 있었다.

 

4. 셀프칭찬 (오늘 잘한 일) : 다른 팀원의 에러를 같이 해결하기위해 열심히 구글링하고 도와준 나를 칭찬한다.

 

5. 내일 할 일 : 코드 전체 리팩토링, 새로운 기능 코드 리뷰, 유의미한데이터 DB에 넣어 놓기, 마지막 프론트랑 합치기 !! 


[오늘 공부한 부분] 

 

[05] Spring 페이징처리 + 키워드 검색기능 구현

 

[05] Spring 페이징처리 + 키워드 검색기능 구현

Controller //숙소 전체 조회 @GetMapping("/rooms") // size '/api/rooms?page=0&size=3' public ResponseEntity getRooms(@AuthenticationPrincipal UserDetailsImpl userDetails, @PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) Pageable p

leejincha.tistory.com

[06] Spring 이메일 인증 구현

 

[06] Spring 이메일 인증 구현

build.gradle // 이메일 인증을 위한 설정 implementation 'org.springframework.boot:spring-boot-starter-mail' EmailConfig package com.cloneweek.hanghaebnb.util.email; import org.springframework.beans.factory.annotation.Value; import org.springframew

leejincha.tistory.com

[07] Swagger

 

[07] Swagger

Swagger란? API에 대한 정보를 전달하기 위해 일일이 문서화하는 것은 매우 번거로운 작업이다. 매번 Rest API를 개발하고 수정하면서 API문서를 변경하는 것은 개발자의 생산성 또한 떨어뜨린다. Swagg

leejincha.tistory.com

 

User Entity

  • 일반 로그인 회원가입 엔티티에 kakaoId 추가

 

  • 그리고 아래에 카카오로그인과 업데이트에 사용할 생성자도 추가해 준다.

 

UserController

  • kakaoService 의존성 주입

 

  • kakao login Controller 부분

 

UserRepository

 

KakaoUserInfoDto

 

KakaoService

build.gradle

// s3 설정 관련
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

 

1. Amazon3SConfig

  • S3의 accessKey와 seceretKey, region, bucket 이름은 properties에 저장되어 있다.
  • 이 정보들이 깃헙에 유출되지 않도록 gitignore 설정에 properties를 추가해 주는 것을 잊지 말자! 

 

2. AmazonS3Controller

  • 이미지 업로드 확인을 위한 컨트롤러이기 때문에, 실제 서비스에선 사용하지 않는 파일이다. (그래서 빨간줄이 뜸)

 

3. AmazonS3Service

  • 1개 이상의 이미지가 담겨있는 multipartFileList를 for문을 돌려 이미지가 있을 시 convert 메소드를 통해 파일을 전환시켜 준다.
  • 그리고, new ImagFile 안에서 아래의 upload 메소드를 사용해 이미지 파일과, 폴더명, 유저 정보, 룸 정보를 담아준다. 
  • 다음 imageFileRepository에 저장한다.

 

  • 위에서 사용된 upload 메소드 부분이다. 
  • S3에 저장될 파일이름을 fileName 에 담아준다.
  • 다음, 이미지 파일과 파일 이름을 아래 putS3 메소드를 이용하여 S3에 업로드해준다.
  • 다음 아아래에 있는 removeNewFile 메소드를 이용해 로컬에 저장된 이미지파일을 삭제한다.

 

  • S3로 이미지 파일을 업로드하는 메소드이다.
  • putObject 메소드를 이용하여 지정된 버켓에 파일이름과 이미지파일을 저장해주고
  • return값으로 이미지 url을 String 타입으로 반환하다.

 

  • 위에 선언된 removeNewFile 메소드 부분이다.
  • 로컬에 저장된 파일을 삭제하는 역할을 한다.

 

  • 파일을 전환하는 convert 메소드 부분이다.

 

  • 이 부분은 RoomService에서 숙소정보글을 삭제할 때, 해당 글의 이미지 파일을  삭제해주는  메소드이다.

 

게시글 등록 부분

S3를 반영한 게시글 CRUD 부분은 아래를 참조해주세요 : )

 

Airbnb Clone Coding (Main CRUD)

 

Airbnb Clone Coding (Main CRUD)

전체 코드 중 주요 기능으로 잡은 에어비엔비 Room CRUD 부분을 정리해보려 한다. + 추가기능 ( 페이징 처리, 검색어 입력, S3, 게시글 좋아요, 비회원처리 ) Dto, Entity 등은 제외하고 Controlle / Repository

leejincha.tistory.com

 

+ Recent posts