자바finalstaticequals / hashCode / toStringconstructor웹htmlcssjavascript스프링스프링부트스프링 mvc스프링 데이터 JPA(스프링 시큐리티)JPAtransient / persistent / detached / delet
프로젝트 만들기 java version 8, maven, jar을 사용함! Spring Configuration Processor: application.properties 파일에다가 에다가 원하는 커스터마이징, 추출해서 사용할 수 있음 Account 도메인 클래
Bootstrap네비게이션 바 폼 만들기ThymeleafSignupForm 타입 객체를 폼 객체로 설정하기웹(html, css, javascript)제약 검증 기능 사용하기 닉네임(3-20자, 필수 입력) 이메일(이메일 형식, 필수 입력) 패스워드(5-80자, 필
JSR 303 애노테이션 검증값의 길이, 필수 값 폼 값을 입력하고 전송 버튼을 누르면 폼 데이터들이 서버로 전송되는데, 사용자가 이때 유효하지 않는 값들을 입력하고 전송할 수도 있다. 이런 유효하지 못한 값들이 전송되었을 때 해당 데이터들을 검사해서 부적합하다고 판단
이메일, 스프링 이메일 모듈을 추가해놨기 때문에 이메일 관련된 기본 설정도 적용이 되어있다. 주입 받아서 사용할 순 있지만, 지금은 일단 가짜 객체를 만들어서 사용해보도록 하겠다. 나중에 진짜 구현하도록 하다. 가짜 객체를 만들어 콘솔에다가 출력하는 sender을 만듦
그래야 코드를 변경한 이후에 불안하지 않다. 변경한 코드가 무언가를 깨트리지 않았다는 것을 확인할 수 있음폼에 이상한 값이 들어간 경우 다시 폼이 보여지는가?폼에 값이 정상적인 경우 \- 가입한 회원 데이터가 존재하는가?이메일이 보내지는가?메소드의 길이코드를 읽기 쉬
Account 엔티티를 저장할 때 패스워드 인코딩하기!평문을 했을 때 해쉬가 일치했는지 보면 된다. 단방향으로 ? 변경해서 저장하면 된다. PasswordEncoderFactories.createDelegatingPasswordEncoder()여러 해시 알고리듬을 지원
Get "/check-email-token" token=${token} email=${email} 요청 처리이메일이 정확하지 않은 경우에 대한 에러 처리토큰이 정확하지 않은 경웨 대한 에러 처리이메일과 토큰이 정확한 경우 가입 완료 처리 \- 가입 일시 설정이메일 인
error 프로퍼티가 model에 들어있는지 확인view 이름이 account/checked-email인지 하ㅗㄱ인모델에 error가 없는지 확인 모델에 numberOfUser가 있는지 확인모델에 nickname이 있는지 확인뷰 이름 확인동일한 이유, 트랜잭션이 없어서
회원 가입 완료시 자동 로그인이메일 인증 완료시 자동 로그인스프링 컨텍스트가 ContextHolder를 들고 있다. 현재 토큰을 만들어서 SimpleGrantedAuthority 까지 주입을 해서 사용함. 인코딩 한 패스워드밖에 접근하지 못하기 때문이다. 정석적인 방법
인증 정보가 없는 경우인증 정보가 있는 경우 현재는 로그인 했을때와 안했을 때와 뷰가 같다. 유용한 디펜던시 추가하기! 타임리프가 스프링 시큐리티를 지원하는 ..! 😮😮 로그인과 가입 버튼은 인증을 하지 않았을 때만 보여줘야 한다. 이런 식으로 sec:authori
현재 우리는 단일 어플리케이션, 프론트와 백이 다 있다. 현재 쓰고 있는 프론트엔드 관련 라이브러리들은 부트스트랩, jquery 이다. 매번 cdn 으로 불러서 사용할 수는 있겠지만 프론트엔드 라이브러리들을 프로젝트 안에다가 패키지화 시킬 수도 있다. 그러기 위해서는
Thymeleaf는 HTML, XML, JavaScript, CSS 및 일반 텍스트를 처리 할 수있는 웹 및 독립형 환경 모두를위한 최신 서버 측 Java 템플릿 엔진Thymeleaf의 주요 목표는 우아하고 유지 관리가 쉬운 템플릿 생성 방법을 제공하는 것이다. 이를
네비바에 fontawesome으로 아이콘 추가이메일 인증을 마치지 않은 사용자에게 메시지 보여주기identicon 으로 프로필 기본 이미지 생성npm install font-awesomenpm install jdenticon원하는 아이콘을 가져다가 사용하면 된다. In
스프링 시큐리티의 스프링 웹 MVC 지원 @AuthenticationPrincipal 핸들러 매개변수로 현재 인증된 Principal을 참조할 수 있다 Princial을 어디에 넣었더라? Princial은 우리가 인증할 때 Authentication에 들어있는 첫번째
가입 확인 이메일을 재전송할 수 있는 기능 제공너무 자주 전송 시 리소스 낭비할 수도 있는 문제 발생1시간에 한번만 인증 메일 전송할 수 있도록 제한가입 확인 이메일을 전송한 이메일 주소를 화면에 보여줌재전송 버튼 보여주기재전송 버튼 클릭시 get "/resend-co
로그인 뷰는 우리가 만들겠지만, 로그인 처리는 스프링 시큐리티에게 맡길 것 param에 error가 있으면 .. 아래와 같은 정보를 보여줌. param.error은 null이 아니면 true 이다. 계정을 찾지 못하는 경우에는 /find-passsword 로 갈 수 있
쿠키에 인증 정보를 남겨두고 세션이 만료 됐을 때에는 쿠키에 남아있는 정보로 인증한다.어떤 애플리케이션에 로그인을 한다. 계정을 만들고, 로그인을 하면 세션 아이디가 생긴다. jsessionid는 웹브라우저와 서버의 연결고리이다. 이 아이디에 해당하는 서버쪽에 세션이라
listgroupgridaccount 의 프로필 이미지가 비어있으면 Jdenticon 으로 생성을 한다. account 의 프로필 이미지가 비어있지 않으면 (있으면) account의 profileImage를 보여준다. 해결해야 할 버그가 남아있음! 😭출처 : 인프런
가입을 하고 회원 인증을 했음에도 불구하고 가입 날짜가 업데이트 되지 않았다. 객체의 변경사항이 db에 반영이 안되었다. 왜일까? account.completeSignUp(); 를 보면 트랜잭션이 없다. 컨트롤러에서 데이터를 변경했다. 트랜잭션 범위 밖에서 일어난 일
어떤 유저의 프로필을 보여줄지는 굳이 url을 명시할 필요는 없다. 수정할 수 있는 것은 오직 자기 자신의 프로필일 뿐이다. 현재 유저 정보를 가져오면 된다. Profile.java 를 만들어줌, 수정 뷰에서 필요하므로! profile 이 선택되어진 상태! 출처 : 인
폼처리 비어있는 값을 허용. (기존에 있던 값을 삭제하고 싶을 수도 있기 때문) 중복된 값을 고민하지 않아도 된다. 확인할 내용은 입력 값의 길이 현재 CurrentUser 정보를 변경할 것이고 form에서 입력한 값들은 model attribute를 이용하여 Pro
Cropper.JS 이미지 영역을 잘라서 지정할 수 있다. (마우스 휠을 이용해서)Cropper.JSnpm install croppernpm install jquery-cropper?. 은 user가 null이 아닌 경우에 네비게이션 하는 것 프로필 이미지가 비어있지
패스워드 변경 뷰 passwordForm 을 처리할 때 initBinder 사용하기 passwordEncoder 를 설정해줘야 함. 패스워드 변경
단위테스트! 출처 : 인프런 백기선님의 스프링과 JPA 기반 웹 애플리케이션 개발
Form특정 웹 서비스 이벤트(스터디 생성, 참가 신청 결과, 참여중인 스터디)에 대한 정보를 이메일로 받을지, 웹 알림 메시지로 받을지 선택하는 기능. 물론 둘 다 받을 수도 있음SettingsController.javaaccount 를 보여주고, form을 채울 객
ModelMapper http://modelmapper.org/ 객체의 프로퍼티를 다른 객체의 프로퍼티로 맵핑해주는 유틸리티 Why? 이런 부분들을 ModelMapper 를 사용하여 간결하게 줄여보자! 😎😎 의존성 추가 여러번 매번 만들어서 사용할 필요가 없
실제 db에 저장되어 있는 정보에 대응하는 인증된 authentication이 필요WithMockUser로는 처리 불가The user with the username "user" does not have to exist since we are mocking the us
계정관리 탭에서는 닉네임 수정과, 계정 삭제가 있음 닉네임은 특정 패턴("^ㄱ-ㅎ가-힣a-z0-9\_-{3,20}$")의 문자열만 지원 함.중복 닉네임 확인.NicknameForm.java : 폼 데이터 객체NicknameValidator.java " NicknameF
패스워드를 잊은 경우에는 “로그인 할 수 있는 링크”를 이메일로 전송한다.이메일로 전송된 링크를 클릭하면 로그인한다.보내는 이메일도 너무 자주 보내면 안된다. 1시간 뒤에만~!GET /email-login이메일을 입력할 수 있는 폼을 보여주고, 링크 전송 버튼을 제공한
엔티티: 독자적인 식별자를 갖고 있는 것엔티티와 밸류의 차이점: 벨류는 엔티티에 속해있음. 엔티티다. 왜? 태그 독자적인 라이프사이클이 있고 다른 곳(Study)에서도 참조할테니까.Tag 엔티티IdTitle (unique)어떤 유저가 어떤 테그를 가지고 있느냐에 더 관
SettingsController.java 에 컨트롤러 추가, tag.html 파일 추가 update는 application을 실행할 때 엔티티 맵핑 정보를 보고 없는 컬럼을 추가해준다거나 그런식으로 동작한다. 기존에 알고 있는 update의 의미가 아니다. 기존에 있
뷰 화면에서 ajax 처리시 tagTitle를 사용했으므로 tagTitle를 받아줄 수 있는 아주 간단한 TagForm을 만들었다. 타임리프 자바스크립트 템플릿 https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf
tag를 입력할 수 있는 form을 보여줄 때 아무런 데이터 정보를 넘겨주지 않고 있다. account 정보만 넘겨주고 있음! 실제로 form을 입력하는 뷰에서 이미 우리가 등록했던 다른 tags 정보들을 조회할 수 있어야 한다. 따라서 accountService의 g
DB에 없는 태그라면, Bad Request로 응답하고DB에 있는 태그라면 Account에서 삭제 (DB에서 태그 정보를 삭제 하는게 아니라 연관관계만 삭제하는 것임)출처 : 인프런 백기선님의 스프링과 JPA 기반 웹 애플리케이션 개발
Tagify의 whitelist를 사용한다.https://yaireo.github.io/tagify/기존에 있는 태그들을 선택할 수 있는 편의성을 제공하기 위해! 트롤러에서 뷰를 보여줄 때 태그 목록을 모두 whitelist로 제공해야 한다. 따라서 다 가져온
AccountService.java 중복 부분 발생! 기본값에 해당하는 것을 셋팅하고 있다. passworEncoder 업데이트, 기본값들은 account의 기본값으로 셋팅..?! builder를 사용하지 않고, modelMapper을 사용할 것이다. signUpF
지역은 태그와 마찬가지로 밸류가 아닌 Entity! (JPA 관점에서)CityLocalNameOfCity Province (주 이름) list of cities in south korea 구글 스프레드, paste of value? 하면 데이터가 잘 들어온다. zone
태그 관리와 차이점은 미리 제공하는 데이터에서만 선택할 수 있다는 점.Zone.java영문이름(한글이름)/province 이런 식으로 보이도록 하기 위해 toString()을 구현한다. 객체가 가지고 있는 정보나 값들을 문자열로 만들어 리턴하는 메소드이다. Settin
맨 위에다가 @Controller@RequestMapping(ROOT + SETTINGS)Controller에 붙여놓은 RequestMapping 와 조합해서 url이 생성된다. 출처 : 인프런 백기선님의 스프링과 JPA 기반 웹 애플리케이션 개발
지금까지 db를 인메모리로 사용했다. 그리고 application.properties에서 profile.actvie를 local로 설정했다. JavaMailSender 를 진짜로 메일을 전송하도록 할 것이다. dev로 설정하기! sts에서는 이렇게 하는구나...
구글 Gmail을 SMTP 서버로 사용하기 https://support.google.com/mail/answer/185833 App 패스워드 발급 받을 것 출처 : 인프런 백기선님의 스프링과 JPA 기반 웹 애플리케이션 개발
간단한 문자열로 메시지를 전송했는데, 이제 클릭만 하면 인증이 되도록 하려고 한다. 그러기 위해서는 html로 메일을 보내야 한다. 타임리프의 가장 핵심적인 클래스는 TemplateEngine이다. 첫번째 파라미터는 simple-link, 두번째 파라미터는 contex
Long IdSet managers만드는 사람은 당연히 매니저가 되고 스터디를 관리할 수 있는 매니저의 권한을 위임할 경우를 대비해서 만드는 중, 매니저는 여러명 있을 수 있도록 .. Set members...Set tagsSet zonesStudy에서 Account
기본값을 셋팅해줌 스터디 개발 뷰 에디터 https://summernote.org/ 부트스트랩과 연동이 편리함. 한국 개발자들의 오픈 소스. npm install summernote
메서드를 호출하는 게 가능하다. 타임리프가 지원한다. 얼마든지 Study에다가 method를 구현해서 사용할 수 있다. principal 정보는 Useraccount 이기 때문에 이 타입으로 받을 수 있다. 이 타입으로 받으면 Useraccount에는 account를
불린 값으로 매니저인지 아닌지를 준다. 뱃지를 달아주느냐, 아니냐에 변화가 생김!출처 : 인프런 백기선님의 스프링과 JPA 기반 웹 애플리케이션 개발
StudySettingsController.java 를 추가하자! @RequestMapping으로 같은 경로의 중복을 줄일 수 있기 때문이다. 😎스터디 매니저만 스터디 설정 기능을 사용할 수 있다.가져올 때 해야할 일이 많기 때문에 studyService 쪽으로 빼낸
데이터를 필요한 만큼만 읽어오기. 태그와 지역 정보를 Ajax로 수정할 때 스터디 (+멤버, +매니저, +태그, +지역) 정보를 전부 가져올 필요가 있는가? 스프링 데이터 JPA 메소드 작명, @EntityGraph와 @NamedEntityGraph 활용하기 With
스터디가 처음 만들어지면 드래프트 상태이다. 이것을 변경할 수 있는기능을 해보자! StudyService.java클래스를 컨트롤러에서 바로 호출 안하고 왜 서비스 계층에서 감싸서 호출할까? -> 꼭 알아야 함! 😎😎 도메인만 컨트롤러에서 호출해서는 안된다. 객체
form에서 들어오는 데이터를 검증할 때 지금까지는 Validator 만들고 initBinder에 등록했는데, 다른 방법을 사용할 수도 있다. study/study.htmlStudySettingsController.java데이터를 @RequestParam newPath
StudyControllerTest.javaprotected를 붙여주었다. 왜? \-> StudySettingsControllerTest 가 StudyControllerTest를 메서드, 필드들을 상속 받아서 사용하도록 하기 위해 😀StudySettingsContr
출처 : 인프런 백기선님의 스프링과 JPA 기반 웹 애플리케이션 개발
새 모임 만들기 뷰 타임리프 뷰에서 enum 값 선택하는 폼 보여주기 DateTime 입력 포맷 한 화면에 여러개의 에디터인데 그 여러개에 다 적용해야 할 때는 id를 사용하기 힘들다. (id를 다 공유해야 하니까) 그래서 class를 적용, editor를 클래
화면 뷰를 만들었으므로 데이터를 추가하는 handler를 추가하자!Repository : @Transactional(readOnly = true) Service : @Transactionalform vaildation을 할 때 이렇게 하면 부족하다. 날짜들은 상관관계가
참가 신청 버튼은 현재 유저가 이벤트의 관계에 따라 달라진다. 이때 spring expression 을 사용해서 event의 method를 호출 후 판단해서 보여준다. 현재 가입 신청이 가능한 상황일 경우에는 참가신청 버튼참가 신청 취소기 가능한 상황이면 참가 신청 취
Event.java쿼리가 5번 발생, 이것은 big-O 에서 5N에 해당한다. 😧이벤트를 조회할 때도 쿼리가 3번 발생한다 . 이벤트 조회, 스터디 조회, enrollment 목록 조회 4개: 스터디 조회, 이벤트 목록, 첫번째 모임의 enrollment 조회, 두번
모임 수정 뷰 모임 수정 로직 모집 방법은 수정할 수 없다. (관리자/선착순) 모집 인원은 확정된 참가 신청 수 보다는 커야 한다. 예) 5명의 참가 신청을 확정 상태로 변경했다면, 모임을 수정할 때 모집 인원 수가 5보다는 커야 한다. 3으로 줄이면 안된다. 최대
POST “/study/{path}/events/{id}/delete”DELETE “/study/{path}/events/{id}HTML의 FROM은 method로 GET과 POST만 지원한다. DELEET는 지원하지 않는다.일관성을 지키기 위해서는 PostMappin
이 때 조회하는 스터디는 관리자 권한 없이 읽어올 수 있어야 하며 (스터디 관리자가아니어도 참가 신청이 가능해야 하니까) 데이터를 필요한 만큼만 가져오도록 주의 할 것.선착순 모임이고 현재까지 수락한 참가 신청 개수와 총 모집 인원수를 확인한다면,가능하다면 해당 참가
현재 controller 에서 get 요청으로 처리했으나 post로 바꿀 수도 있음.front view에서 줄 맞춰서 보이기 위해 get 요청으로 처리한 것일 뿐임, 정석은 post 요청오류참석을 완료했으면 참가 신청 취소를 할 수 없게 해야 함isEnrollableF
원래 event/{id}를 조회하면 (자세히보기)를 누르면 화면이 떠야 하는데 다음과 같은 에러 페이지가 발생했다! 컨트롤러에 문제가 있는지 살펴봤는데 문제가 없었음. event/view.html 파일도 마찬가지 😭😭 어제 에러를 해결하고 싶어서 낑낑거리다가 도저히
ObjectMother를 적용하자 https://martinfowler.com/bliki/ObjectMother.html 테스트에 필요한 데이터를 만드는데 도움을 주는 유틸티리 > OBJECT MOTHER 패턴은 이와 같은 픽스처 생성과 관련된 문제를 해결하기 위해
테스트 DB를 운영용 DB와 같은 유형으로 바꾸자. JPA 또는 하이버네이트가 만들어주는 쿼리가 각 DB밴더에 따라 다르다. 하지만 테스트용 DB를 운영하는 것은 번거롭다. CI 환경은? 그래서 TestContainers를 사용한다. https://www.testcon
테스트 DB를 PostgreSQL로 전환하던 도중 발생한 오류이다. 테스트 db를 운영용 db와 같은 유형으로 바꾸기 위해 TestContainers을 사용했다. 강의대로 따라했는데 50개의 test 중 11개만 통과되고 39 개의 test가 fail 되었다. 우선 강
제목링크짧은 메시지확인 여부누구에게 (Account)언제알림 타입 (새 스터디, 참여중인 스터디, 모임 참가 신청 결과)출처 : 인프런 백기선님의 스프링과 JPA 기반 웹 애플리케이션 개발
스터디가 만들어지거나 스터디에 대한 정보가 바뀌거나 참가 신청했던 것에 대한 변경이 생길 시 추가적인 알람을 보내는 것이다. 알림을 받을 때 웹, 이메일 등으로 받을 수 있다. 근데 이 일 자체가 부가적인 일이고, 메인 로직에 영향을 주고싶지 않다. 응답 시간에도 영향
핸들러 처리 이후, 뷰 랜더링 전에 스프링 웹 MVC HandlerInterceptor로 읽지 않은메시지가 있는지 Model에 담아준다. (뷰를 렌더링하기 전에 model에다가 데이터를 하나 더 넣어준다. 현재 읽지 않는 노티가 있느냐 없느냐를 넣어준다. https&#
읽지 않은 알림 메시지만 보여준다.알림 메시지를 카테고리 별로 나눠서 Model에 담아주고 뷰에서 보여준다.모든 읽지 않은 알림 메시지를 읽은 메시지로 수정한다.읽은 알림 메시지를 보여준다.읽은 알림 메시지를 삭제한다.deleteByAccountAndChecked ,
스터디 소개를 수정 했을 때스터디 종료시스터디 팀원 모집 시작 / 중지StudyService.javaeventPublisher 를 통해 event 를 던짐! 4개의 이벤트를 4곳에서 StudyUpdateEvent를 던지도록 하였음, 그리고 이에 대한 처리로 Study
새 모임 추가모임 변경모임 취소참가 신청 수락참가 신청 거절EnrollmentEvent 를 만들고 아래와 같은 방법을 취함! 출처 : 인프런 백기선님의 스프링과 JPA 기반 웹 애플리케이션 개발
스터디를 만들때가 아니라 공개할 때 알림 알림 받을 사람: 스터디 주제와 지역에 매칭이 되는 Account 알림 제목: 스터디 이름 알림 메시지: 스터디 짧은 소개 QueryDSL 설정 http://www.querydsl.com/ 타입 세이프하게 JPA 쿼리를 작성할
GET “/search/study” keyword 입력 받아서 스터디 검색 스터디 제목, 태그 이름, 도시 로컬 이름에 해당하는 키워드를 가지고 있는 공개된 스터디 조회 페이징 없이 정렬 조건 없이 로그인 없이도 사용 가능 보여줄 내용 검색 키워드와 결과 개수, 없으면
스터디 목록 조회하는 쿼리 발생 스터디 마다 쿼리가 3개씩 태그 조회, 지역조회, 멤버 조회 3n+1 스터디가 9개가 있으면 3*9+1 = 28 개 JPA를 쓰면서 성능이 느려지는 이슈중 하나이다. left (outer) join + fetchJoin + dist
고전적인 방식의 페이징 SQL의 limit과 offset 사용하기 스프링 데이터 JPA가 제공하는 Pageable 사용하기 page와 size sort도 지원한다. 기본값 설정하는 방법 @PageableDefault 이전에 emtpy 콜렉션을 Model에 넣을 때 발생
부트스트랩 https://getbootstrap.com/docs/4.4/components/pagination/ 정렬 조건 추가 스터디 공개 일시 멤버수 키워드 하이라이팅 mark.js https://markjs.io/ 출처 : 인프런 백기선님의 스프링과 JPA 기반
최근 9개의 스터디를 조회해서 화면에 보여줄 것. (공개했고, 아직 종료하지 않은 스터디중에서)페이징 X, List로 조회쿼리 만들지 말고, 스프링 데이터 JPA 쿼리 메소드로 만들어 볼 것.뷰 코드는 최대한 재사용 할 것.😙😙 재사용하기!!!!!출처 : 인프런 백
Todo N+1 Select 문제 없이, 쿼리 6개를 사용해서 만들기 계정 조회 (관심 주제, 지역 정보 포함) 참석할 모임 조회 ㅇㅇ 내가 참가 신청을 했고 이게 수락이 된, enrollment를 조회해야 한다. 나의 주요 활동 지역과 관심 주제에 해당하는
Spring @ControllerAdvice 어노테이션을 이용한 에러 처리 클라이언트가 잘못된 요청을 보내오는 경우 404 에러 페이지로 보낸다. 잘못된 요청의 예 없는 스터디 페이지 조회 시도 없는 프로필 페이지 조회 시도 무작위 이벤트 조회 시도 허용하지 않는
환경(프로필)에 따라 각기 다른 설정 파일 제공하는 방법로깅패키징배포 방법배포 시 주의해야 할 것은 설정파일! 😉여러가지 환경에 따라 각기 다른 설정을 해줘야 하는데 스프링, 스프링 부트에서는 스프링 부트가 제공하는 profile 별 application.proper