전체 글
[Effective Java] Item02. 생성자에 매개변수가 많다면 빌더(Builder)를 고려하라
Item02. 생성자에 매개변수가 많다면 빌더(Builder)를 고려하라 - 정적 팩터리 메서드와 생성자는 선택적 매개변수가 많을 때 적절히 대응하기가 어렵다. - 이를 보완하기 위해 많은 개발자들은 다음과 같은 방식을 사용했다. 1. 점층적 생성자 패턴(telescoping constructor pattern) - 필수 매개변수만 받는 생성자 / 필수 매개변수 + 선택적 매개변수 1개를 받는 생성자 / 필수 매개변수 + 선택 매개변수 2개를 받는 생성자 / ... 와 같이 점층적인 형태의 생성자를 여러 개 늘리는 방식 - 단점 : 선택적 매개변수에도 기본값을 지정해야한다, 매개변수 개수가 많아지면 코드 작성, 읽기에 어렵다(각 값의 의미가 뭔지 모름) 2. 자바빈즈 패턴(JavaBeans pattern..
[Effective Java] Item01. 생성자 대신 정적 팩터리 메서드를 고려하라
Item01. 생성자 대신 정적 팩터리 메서드를 고려하라 클래스가 인스턴스를 얻는 전통적인 수단은 public 생성자이다. public class Foo { private String name; // 생성자를 통한 인스턴스 생성 public Foo(String name) { this.name = name; } } 하지만 전통적인 수단인 생성자와 별도로 정적 팩터리 메서드(static factory method)를 통해서도 인스턴스를 생성할 수 있다. 해당 방식은 단점도 존재하지만, 장점이 많으므로 쓰임새에 따라 유리할 경우 사용하는 것이 좋다. public class Foo { private String name; // 생성자를 통한 인스턴스 생성 public Foo(String name) { this...
username만 매칭되면 user 세션 생성 되는 문제 해결 - AuthenticationProvider를 통한 password 기반 인증
발생한 문제 : DB에 존재하는 user의 username(아이디)만 일치하면 user session이 생성되어 index page에서 로그인 처리가 되는 문제. 원인 : UserDetailsService를 구현한 클래스의 loadUserByUsername 메서드에서 username을 통한 user의 존재여부만을 판단하고, 존재 시 user 세션을 생성하면서 password에 대한 인증이 없어 발생한 문제이다. @RequiredArgsConstructor @Service public class PrincipalUserDetailsService implements UserDetailsService { private final UserRepository userRepository; private final ..
로그인 성공 시 이전 페이지로 이동 - Referer 헤더와 AuthenticationSuccessHandler extends
발생한 문제 : 게시판 웹사이트에서 댓글 작성 페이지 -> 로그인 페이지로 redirect 된 후, 로그인 성공 시 댓글 작성 페이지로 되돌아오는 것이 아닌 index page ("/")로 돌아오게 된다. 해결 : 1. 스프링 시큐리티는 권한이 없는 페이지에 대해서 login form 페이지로 redirect 된다. 2. 이 때 이전 페이지에 대한 url을 Referer 헤더로 request에 가지고 있다. 3. Referer 헤더값(이전 페이지에 대한 url)을 Session에 저장한다. 4. 로그인 성공 시 동작하는 AuthenticationSuccessHandler를 상속받아 구현한다. 5. 이 때 Referer 헤더값을 Session에서 꺼내서 해당 url로 redirect한다. 위 순서대로 ..
Entity 삭제 시 JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation 오류 발생
Spring을 통해 장소와 해당 장소에 대한 이벤트를 CRUD하는 API를 설계하던 중 발생한 문제이다. Entity 연관관계 구성 Place Entity와 Event Entity가 1:N 양방향 연관관계로 구성되어 있다. Entity 설계 - Place @Getter @ToString @NoArgsConstructor(access = AccessLevel.PROTECTED) @Entity public class Place { // 내용과 관련있는 프로퍼티만 설명함. @Id @GeneratedValue @Column(name = "place_id") private Long id; @ToString.Exclude @OrderBy("id") @OneToMany(mappedBy = "place") privat..
[Java] 배열 (Array)
자바에서 배열의 선언 // 배열의 선언 방식 int[] arr; int arr2[]; type, 변수명 구분 없이 [] 키워드를 넣을 수 있다. 배열의 생성, 초기화 int arr[] = new int[5]; // 크기 5의 int 배열 선언 및 생성 arr[0] = 1; // 배열의 초기화 arr[1] = 2; arr[2] = 3; int arr2[] = new int[]{1, 2, 3} // 크기 3의 int 배열 선언, 생성 및 초기화 int arr3[] = {1, 2, 3} // 위와 같은 배열을 가짐. new 키워드를 통해 배열 객체를 생성한다. 이 때 대괄호([]) 안에 배열의 사이즈를 넣는다. 값의 초기화, 변경은 일반적인 배열의 형태와 같이 arr[index] = value 형태로 가능하다..
[Java] 자바의 특징
Java의 특징 1. 운영체제에 독립적으로 동작 *자바가상머신(JVM, Java Virtual Machine)을 통해 JVM이 설치되어 있는 OS에서는 모두 자바로 작성된 프로그램이 실행 가능하다. 그래서 자바 언어를 Write once, run anywhere (한 번 작성하면, 어디서나 실행된다.)로 표현하기도 한다. * 자바로 작성된 프로그램을 실행 할 수 있는 가상의 컴퓨터이다. JVM의 경우는 기존의 하드웨어로 구성된 컴퓨터를 소프트웨어적으로 구현한 것으로, 자바로 작성된 프로그램은 모두 이 JVM을 통해 실행되므로 자바 프로그램을 실행하기 위해서는 JVM이 설치되어 있어야 한다. (JVM에 대한 내용은 추후 자세히 다뤄보도록 하자.) 2. 객체지향언어 (OOP, Object - Oriented..
[Android, Kotlin] Bottom Navigation View + Jetpack Navigation 바텀 메뉴 클릭 시 프래그먼트 재생성 막기
문제 : 위 사진(카카오톡)과 같이 바텀 메뉴 클릭 시 최초 클릭 시에는 프래그먼트가 생성되어 화면이 로딩되고, 이후 클릭 시에는 기존 생성된 프래그먼트가 유지되었으면 한다. 그러나 기본적인 Jetpack Navigation + Bottom Navigation View의 경우에는 바텀 메뉴를 클릭 할 때마다 프래그먼트가 재생성된다. 1 - 최초 생성 2 - 한번 더 BookFragment 바텀 메뉴 클릭 3 - 다른 바텀 메뉴로 갔다가 다시 BookFragment 메뉴 클릭 위와 같이 어떤 경우에서든지 메뉴를 클릭하기만 하면 해당 메뉴와 연결된 프래그먼트가 재생성된다. 1 - 최초 생성의 경우에만 프래그먼트가 생성되고, 2와 3의 경우에는 기존 프래그먼트를 hide - show 하는 방향으로 하여 카카오..
백준[3980] - 선발 명단 (Kotlin)
import java.io.BufferedReader import java.io.BufferedWriter import java.io.InputStreamReader import java.io.OutputStreamWriter import kotlin.math.max fun main() { val br = BufferedReader(InputStreamReader(System.`in`)) val bw = BufferedWriter(OutputStreamWriter(System.out)) val stat = Array(11) { emptyArray() } val selected = Array(11) { 0 } var max = Int.MIN_VALUE val N = br.readLine().toInt() ..
[Android, Kotlin] Firebase DB에서의 각 Listener별 차이점 (Value, Single, Child)
Firebase Realtime DB를 사용 할 때, 리스너를 등록하여 DB 내 값이 변경 될 때마다 해당 변경 사항을 동기화시켜 리사이클러뷰 등의 리스트를 업데이트 할 일이 잦다. 이 때 등록 할 수 있는 리스너는 3가지 종류가 있다. 1. ValueEventListener 2. SingleValueEventListener (DatabaseReference.addListenerForSingleValueEvent(ValueEventListener) 형태로) 3. ChildEventListener 리스너를 사용 중 각 리스너 별 동작에 따른 차이점과 사용 형태가 궁금해져 직접 3가지 형태의 리스너를 달고 데이터가 추가 되었을 때의 결과를 확인해보았다. 먼저, 초기에 구성되어 있는 기본 DB 상태이다. "U..