My project/inflearn_clone?
Spring Interceptor, @SessionAttribute 사용하기
문제 상황 로그인 후 웹 사이트를 이용할 때 로그인이 유지가 되었는지 확인하기 위해 같은 코드를 거의 모든 컨트롤러 메서드에 반복 작성했다. 쓰면서도 이건 뭔가 잘못됐다,,,라고 생각했다. 메서드로 빼려고 하니 모든 컨트롤러에서 사용돼서 아닌 것 같고, 클래스로 따로 만들어 메서드를 작성하자니 기능이 애매해서 나중에 공부하다 보면 방법이 무조건 나올 거 같아서 참아보고 있었다. 심지어 인텔리제이도 몇 번째 같은 코드를 작성 중이라고 표시도 해주었다. HttpSession session = request.getSession(false); if (session == null) { return "redirect:/login"; } User loginUser = (User) session.getAttribute..
BindingResult, Bean Validation 사용하기, 오류 코드
BindingResult와 Validation을 배워서 적용해 보았다. 역시 예상치 못한 상황이 여럿 있었으니 그때 상황으로 고고고~ 기존 코드! 기존에는 따로 검증 코드를 작성해주지 않았다. 태그에 required를 사용해서 로그인, 회원가입등 상황에서 입력을 받도록 하였다. 검증을 어디서 해야 할까? 백엔드를 처음 시작하고부터 내가 많이 했던 질문 중 하나이다. "백엔드에서 처리해야 해? 프론트엔드에서 처리해야 해?" 이런 궁금증을 일으키는 상황이 많았다. 검증 역시 마찬가지이다. required만 붙이면 입력하라고 alert창까지 처리해 주는데? 최고인데?라고 생각했지만 그럴 리가 없었다 역시.. 항상 예상치 못한 경우가 생기기 때문에 이러면 안 된다. 포스트맨으로 json 값을 임의로 보내거나, ..
@ModelAttribute 동작 방식, 타임리프 th:object th:field 사용하기, dto에 setter 사용
김영한님 강의를 듣고 view에 form 부분을 th:object, th:filed를 사용해서 리팩토링 중 예상치 못한 오류를 맞이했다. 클라이언트한테 입력을 받는 상황 중 회원 가입을 예시로 글을 작성할 예정이다. 그럼 바로 그 당시 상황과 해결 방법으로 고고고~ th:object, th:field 클라이언트가 회원 가입 페이지 url을 클릭한 경우 기존에는 컨트롤러에서 html 페이지만 return 해주었다. th:object를 사용하기 위해서는 컨트롤러에서 비어있는 dto 객체를 model에 담아서 전송해 준다. 비어있는 객체를 보내주기에 기본 생성자로 새 객체를 만들어 담아주었다. (이때 기본 생성자를 사용하는 과정에서 이후에 오류가 발생한다. 기억해 두자.) model에 담아 보내준 user 객..
다대다 관계 해결하기. (@ManyToMany, @JoinTable, 연결 테이블 기본키)
베타 버전에서는 다대다 관계 (@ManyToMany)를 사용하지 않고 일대다 관계를 사용하였기에 course는 각각 1개의 category만 가질 수 있었다. 이를 해결하기 위해 리팩토링을 진행하였다. 간단한 설명과 과정을 작성해 보겠다. 다대다 관계 왜 안돼? 나는 spring과 관계형 데이터베이스인 mysql을 사용하고 있다. 기본적으로 관계형 데이터베이스에서는 다대다 관계를 표현할 수 없다.라고 많이 나와있다. 왜 안 되는 것일까? 이것은 내가 전에 정리했던 연관 관계 글을 보면 힌트를 얻을 수 있다. 기본적으로 일대다, 다대일 관계에서 '다'가 연관관계의 주인이며 외래키를 갖고 있는다. 이유는? '일'에서 외래 키를 갖고 있으려면 필드가 1개일 수 없다. course가 category를 여러 개 ..
스프링 부트 상태코드 999??? (에러페이지, 쉬어가는 타임)
이번 글은 에러 페이지를 만들던 중 맞이한 띠용하는 상황을 간단하게 적어 볼 예정이다. 가볍게 보자. repository에서 쿼리 메서드를 사용한 경우 Optional 타입을 값을 반환받는 경우가 있다. 원래는 그럴 일 없어. 라 생각하고 무조건 .get()으로 꺼내서 사용했다. 하지만 리팩토링을 진행하면서 이 부분을 확인하는 코드를 작성하여 null일 경우 따로 작성한 error 페이지로 이동하도록 하였다. error 페이지는 간단하게 error임을 알려주고 main화면으로 돌아가는 버튼을 넣어 두었다. 이때 처음보는 것을 봤다. 이름하여 상태 코드 999,,, 처음 보는 상태 코드에 당황한 나는 여러 검색을 해보았다. 하지만 999의 의미는 없고 커스텀한 가능성이 높다고 했다. 하지만 나는 상태 코드..
Repository와 Service 분리하기 (단일 책임 원칙)
우당탕탕 베타 버전을 완성시킬 때 동작 여부를 확인하는데 급급해서 servcie를 따로 만들지 않고 Repository에서 메서드를 직접 사용해 Controller를 작성했다. 이것만 하고 Service단을 만들어야지 하다가 걷잡을 수 없이 많아져서 미루다가 미래의 내가 고생했다.. 핑계를 말해보자면 명확하게 비즈니스 로직을 설계하지 않아서 그때그때 기능 구현을 하다 보니.. 핑계 접어두고 시작하겠다. entity, repository, service, controller, view의 기본 구조가 필요하다는 것을 알고 repository와 service를 무의식적으로 만들다가 이 김에 왜 필요한지 정리하려한다. 왜냐면 내가 처음 작성했던 것처럼 바로 repository에서 메서드를 가져와 써도 동작하기 ..
@Transactional 이해하고 사용하기 (트랜잭션이란?)
데이터 베이스보다 jpa를 먼저 공부했었던 나는 여러 위기가 있었다. jpa를 사용해서 데이터베이스에 저장하고 정도만 알고 쿼리를 볼 줄 몰라서 로그를 봐도 update, insert, delete 영어 뜻으로만 알고 무엇인지 알 수 없었다. 또한 @Transactional을 언제 써야 하는지도 정확히 몰라 느낌상 데이터 베이스에 값을 저장할 때 붙여 주었다. 학교 수업시간에 데이트베이스를 배우니 외래키, join 등도 쉽게 이해할 수 있었고 쿼리도 읽을 수 있었고 더불어 jpql도 사용할 수 있었다. 하지만 아직 한발 남았다. 기말고사 끝나고 보강 수업으로 트랜잭션 영상이 올라와 있었다. 당연히 안 봤다. 하지만 이번에 코드 뚜닥이면서 한번 정리하고 넘어가야겠다 생각해서 이러닝에 올라온 영상을 한번 보..
절대 경로 VS 상대 경로 (a 태그 href 속성에 /를 작성해야 할까?)
사건 번호 156923.. 웬만한 위기는 다 넘겼다고 생각하고 열심히 코딩 중에 있었다. 강의 신청 결과 view를 처리하고 아무 생각 없이 nav의 Home을 클릭하였는데 (Home을 누르면 메인 페이지로 이동해야 한다.) 그런데..... 초반에 만들었던 nav였고 잘 작동했는데 오류가 났다.... 잘 살펴보니 URL이 'localhost:8080/main'으로 이동하였는데 사진을 보면 'localhost:8080/course/main'으로 나타난다. 당시에는 오류에 흥분하여 코드부터 다시 보다가 나중에 url을 보게 되었다. url을 보니 '아 무엇인가 상대 경로, 절대 경로 문제겠구나'라고 바로 생각했다. 왜냐면 이 개념을 완벽히 잡지 않고 애매하면 무조건 절대 경로를 사용했기 때문에 언젠가 나한테..
JpaRepository Query Method (엔티티 필드에 _가 들어있으면?)
이번 글은 레포지토리를 작성하면서 있었던 일이다. 사실 처음에는 직접 구현하고 싶어서 EntityManager를 사용하여서 개발했다. em.persist()등을 직접 사용하고 있었다. 모든 repository를 직접 개발하려 했으나 개발 바닥 톡방에서 남들이 쓰고 간단한 건 빠르고 간결하게..라는 조언을 받았다. 그래서 하나의 repository만 직접 구현했고 그것도 나중에는 jparepository로 바꾸었다ㅎ.. JpaRepository를 상속 받으면 쿼리 메서드들을 작성, 구현하지 않고 사용할 수 있다. 대표적으로 save(), delete()등을 바로 사용할 수 있어서 insert, update, delete 쿼리를 우리가 따로 작성하지 않아도 편리하게 사용할 수 있다. select를 하려면 우..
DTO? DTO 필요한 이유, DTO 사용해 보기!(VO?)
이 프로젝트를 진행하기 전에 가장 적용하고 싶었던 것들 중에 하나가 DTO이다. 전에 구글링을 하던 중 DTO가 정말 많이 사용되던 것을 보았어서 적용해 보아야겠다고 생각했다. 그때는 정의만 보고 와닿지 않았지만 사용해 보니 이유를 알게 되었다. 본인은 user의 로그인, 회원 가입, 정보 수정 같은 값을 받아올 때 사용했다. (물론 많은 검색과 이해를 통해 이 글을 작성한다. 하지만 이해를 쉽게 해주기 위해 나의 생각이 많이 들어가서 조금 부정확할 수 있다.) DTO (Data Transfer Object) DTO는 이름 그대로 데이트 전송 객체 즉 데이터를 옮겨 주는 객체이다. 데이터를 전달하는 것이 핵심이다. 사용해 보기 전에는 이 정의만 보고 그게 왜 필요하지?라는 생각이 들었다. 예제를 보겠다!..