Max 4주차: 23-03-27 ~ 23-03-31
Max 5주차: 23-04-03 ~ 23-04-07
앞으로 5주동안 Spring으로 카페를 구현하는 미션을 하게된다.
4주차 미션은 1단계 회원 관련 기능, 2단계 게시글 관련 기능을 구현하는 것이다.
5주차 미션은 DB 연동 및 AWS 배포이다.
처음 스프링을 맛본 1주일 동안 정말 많은 고민과 삽질을 했고,
해결된 부분도 있고 해결이 되지 않은 부분이 있다.
본글은 미션을 진행한 과정을 기록하고자 한다.
상세 내용은 Github에서 확인 가능하다.
이번 미션은 Spring에 대한 이해도가 없기 때문에
Java 미션하는 것처럼 설계에 대한 고민보다는 일단 작동하게 하는 것에 대해 중점을 두었다.
또한 리뷰어가 붙는 미션이기에 공부한 과정, 공부한 내용, 문제 해결한 내용 등
미션을 어떻게 진행했는지 상세하게 기록하려고 했다.
그래야지 리뷰어가 코드를 읽기 더 쉽고,
현재 내 상황에 맞는 피드백을 해줄 수 있을 것으로 생각했기 때문이다.
Template
경로 매핑이 안되는 이슈cannot resolve mvc view 'index'
이슈 발생
Template Engine 미설정으로 인해 발생
Template Engine
설정application.properties
혹은 yml
에 template 경로 설정을 해주는 방법이 있음💡참고:
스프링부트의 ViewResolver 디폴트 경로는src/main/resources/templates/
를 탐색하기 때문에
templates가 아닌 다른 곳에 정적 리소스를 저장 할 시application.properties
혹은yml
에 설정을 해줘야한다.spring.thymeleaf.prefix=classpath:/저장소 이름/
Template Engine
적용 후 CSS가 적용이 안되는 이슈CSS 적용하는 경로를 상대경로로 설정해서 발생
Template Engine
으로 타임리프를 사용했는데,templates/
이하 경로이기 때문에 /css/파일이름.css
으로 수정💡 참고:
css 파일이resources/static/css
밑에 있는데/static
이 아니라/css
로 시작하는 이유는 뷰 리졸버가 기본적으로 /templates 이하 폴더를 먼저 탐색하고 없을 경우 static 폴더를 탐색하기 때문이다.
@GetMapping
어노테이션에 대해 구글링하며 두가지 케이스를 봤다.
무슨 차이인지 보이는가?
@GetMapping("/article/write")
public String articlePage() {
return "/article/form";
}
@GetMapping("/article/write")
public String articlePage() {
return "article/form";
}
경로 맨 앞에 /
유무의 차이이다.
어떤 경우에 /
가 붙는지 궁금해져 찾아보았다.
자세한 내용은 Thymeleaf(타임리프) 작동 원리 - 경로 맨 앞에 "/"가 언제 붙어야 할까? 블로그 글로 정리했다.
✏️ 표시한 내용은 꼭 공부해보자.
- DTO 사용 목적에 대해 생각해보라.
- DTO라고 해서 네이밍이 꼭 xxDTO일 필요는 없다. 다양한 네이밍을 고려해보라
머리가 그렇게 좋지는 않아서 xx 객체는 xxDTO로 명시되어야 머리속에서 잘 매핑된다...🥲- 이메일, 비밀번호 유효성 검증에 대해 고민해보라.
- 메서드 파라미터에 final 키워드를 사용한 이유가 무엇인가.
- 생성자가 하나만 있을 때는 Autowired를 생략해도 된다.
- ✏️ 어느 레이아웃에서 어떤 방식으로 DTO <-> 도메인 객체를 변환하면 좋을지 고민해보라
- ✏️ WebMvcConfigurer 관련 공부한 내용을 설명해보라.
- 왜 WebMvcConfigurerAdapter가 deprecated 되었는지
- 해당 인터페이스가 없다면 어떤 점이 불편할지
- 어떤 목적으로 인터페이스에있는 메서드들을 오버라이딩하는지
- 힌트: interface default method
- ✏️ spring6부터 trailing slash match가 deprecate되어 스프링 부트 3점대 버전 사용하는 경우 /가 중요한 역할을 할 수 있어 특정 상황에 에러가 뜰 수 있다. (참고)
- ✏️
ApplicationContext
와Dependency Injection
에 대해서도 공부해보라.
- 주입 관련 키워드 공부 (추천 자료)
- constructor injection
- field injection
- setter injection
- ✏️
Optional
을 사용하면 좋은 경우와orElse
vsorElseGet
의 차이 등에 대해서 공부해보라.- 불변 리스트가 어느 범위까지 불변성을 보장해주는 생각해보라
- 예: 반환된 리스트에 객체 추가,삭제가 가능한지 / 리스트 내부 객체 필드값 변경이 가능한지
- 커스텀 예외 사용하는 것을 고려해보라.
DB 연동, AWS 배포 모두 환경 설정에 시간을 많이 쏟아야 했고,
환경 설정 과정은 기록해두면 좋을 것 같아 블로깅해두었다.
Trouble Shooting 했던 내용도 같이 정리했다.
각 단계별 미션을 진행하면서 생긴 고민들이 있다.
해당 고민은 레포지토리 README 또는 PR에 적어두고 계속 고민했다.
그중 해결된 고민을 정리해보겠다.
계속 고민되던 부분이다.
파라미터가 많아서 가독성도 좋지 않고, 순서를 기억하기 어렵다.
@PostMapping("/user/create")
public String create(UserDTO userDTO) {
User user = new User();
user.setUserId(userDTO.getUserId());
user.setPassword(userDTO.getPassword());
user.setName(userDTO.getName());
user.setEmail(userDTO.getEmail());
userService.join(user);
return "redirect:/users"
}
어떻게 해결할 수 있을까?
PR 이후 다른 코드스쿼드 PR 리뷰를 보러 돌아다니다가 많은 리뷰어가 "빌더 패턴"에 대해 언급한 것을 봐서 공부해보고 적용해보았다.
빌더 패턴을 적용하면 기존 코드가 이렇게 변경된다.
public User toEntity() {
return new User.Builder()
.userId(userId)
.password(password)
.name(name)
.email(email)
.build();
}
내가 생각하는 Builder 패턴의 장점은 다음과 같다.