Build Tool : Gradle Spring Booot Version : 2.7.6 Spring Security Version : 5.7 DB Version : MySQL 5.7 DB 연동 : MyBatis Gradle 빌드툴 사용하였고 SpringBoot 2.7.6으로 스프링 시큐리티5 버전의 세팅이다. DB연동은 MyBatis이다. 1. 빌드 추가 implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5' testImplementation 'org.springframework.security:spring..
스프링 시큐리티 첫 적용하면서 뻘짓하며 시간을 날려먹은거에 대한 기록입니다. 1. custm login폼 사용시 name 설정 스프링 시큐리티는 로그인폼을 커스텀하여 사용하면 기본폼에서 사용하던 아이디가 username이 아닐수 있다. 나는 email을 사용해서 input태그도 아래 처럼 변경하였다. 하지만 로그인시 호출되는 매개변수 String email 값이 절대로 안넘어 오는 것이 었다. 그 이유는 스프링 시큐리티는 input 태그의 name이 꼭 username 이어야 위 파라미터 값을 가져오는 것이였고 간단하게 설정하려면 input type의 name만 username만 바꿔도 되지만 찜찜해서 email로 꼭 바꾸고 싶었다. 변경방법은 filterChain에서 formLogin 설정에서 user..
아래 Controller를 만들고 CreateAddressRequest 클래스에 boolean isDefault 필드를 만들어서 RequestBody 매핑을 시키려 하였다. 하지만 Postman 전송 시 "isDefault" 값을 아무리 true로 던져도 값은 false로 받아지고 이름도 isDefault가 아닌 default로 이름이 바뀌어있었다. 문제는 자바 클래스에서 boolean 필드는 앞에 자동으로 is를 붙여준다는 점이었다. 그리고 boolean 필드는 앞에 이름 get을 붙이지도 않는다. 앞에 is만 붙는다 여기서 이름의 혼선이 생겨 문제가 있었고 해결하기 위해 앞에 is를 빼고 이름을 바꿨다. 이름을 바꿨더니 잘 매핑이 된다.
Mock이란 어떤 행동을 했을 때 어떤 결과값을 줄 건지 정의한 가짜 객체를 뜻하며, Mockito는 Mock을 이용하여 테스트 코드를 작성할 수 있게 해주는 프레임워크이다. 아래 AddressController 파일이 있고 그 안에는 addrSave() 함수로 주소를 저장하는 Service 함수가 실행된다. @RestController @RequiredArgsConstructor public class AddressController { private final AddressService addressService; @PostMapping("/v1/members/{id}/address") public AddressResponse addrSave(@PathVariable("id") Long memberI..
Swagger는 API 문서를 생성하고 관리하는 도구인 API Docs 이다. Swagger가 springfox, springdocs 2종류가 있는데 springfox는 업데이트가 중단돼서 현재는 springdocs만 사용되고 있는 중이다. springfox를 사용해도 되긴 한데 springboot 버전 2점대에서만 사용 할 수 있다. springdocs는 그게 2버전으로 나뉘는데 1.x, 2.x 버전으로 나뉘는데, 1.x 버전은 springboot 버전 2.x 버전에서 사용되고 2.x 버전은 springboot 버전 3.x 버전에서 사용된다. 각 최신 버전은 아래 URL에서 확인할 수 있다. 1.x 버전 공식 문서는 URL : https://springdoc.org/v1/ 2.x 버전 공식 문서 URL..
이 문제를 이해하는데 쫌 시간이 오래 걸렸다. 간단하게 설명하면 각 칸마다 높이가 있고, 물이 0부터 차 올랐을 때 가장 큰 안전영역 개수를 구하면 된다. 물이 4만큼 차 올랐을 때 안전영역은 아래와 같이 구해진다. 만약에 물이 안차오르면 안전영역은 1이다. 그래서 각 칸의 높이가 전부 1이면 답은 1이다. 물의 최대 높이는 지역의 최대 높이이다. 그래서 물의 높이는 0부터 지역의 가장 큰 수만큼 돌려주면 된다. 물의 높이 0도 신경 써야 하는 이유는 메모에 "아무 지역도 물에 잠기지 않을 수도 있다." 는 조건이 있기 때문이다. [전체 풀이 코드] package baekjoon.classfication.dfs; import java.io.BufferedReader; import java.io.Input..
이 문제는 골드5 문제로 일반 사람과 적록 색약 따로 BFS를 돌려서 풀어야 한다. 맨 처음 문제를 해결할 때는 BFS 돌릴 때 분기를 줘서 해결해보려고 했지만 너무 조건문이 복잡해져서 적록 색약 map을 따로 만들고 G를 R로 변경하는 방식으로 바꿨다. 가독성을 위해 조건문은 최대한 2차 까지만 하려고 노력했다. 최대한 깔끔하게 코드를 작성하는 것이 관건인 문제인 것 같다 [풀이 코드] import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.LinkedList; import java.util.Queue; import java.util.StringTokenizer; //https://www.acmicpc.net/p..
이 토마토 문제는 골드5 문제로 실버 단계에서 풀던 bfs 공식 으로 풀리지가 않았다. 기존 bfs의 공식이라 함은 for문을 돌아서 1을 찾은 다음 바로 큐에 담고 방문체크를 한 다음에 bfs를 돌리는 것인데 똑같이 이렇게 푸니 절대로 풀리지 않는 문제가 있었다. 기존 풀이 코드 for (int i = 0; i < mapZ; i++) { for (int j = 0; j < mapY; j++) { for (int k = 0; k < mapX; k++) { if (map[i][j][k] == 1 && !isVisited[i][j][k]) { isVisited[i][j][k] = true; bfs(i, j, k); } } } } 직면한 문제와 해결 방법 만약 입력이 아래 처럼 주어졌을 때 밑에 1을 찾아 바..
DB에서 데이터를 조회하는 것은 애플리케이션 서버 안에서 실행되는 메서드 보다 비교도 안될 정도로 시간 비용이 많이 든다. 그래서 DB에서 데이터를 조회하는 것을 최소화하는 것이 성능 최적화의 중요 요점이라고 볼 수 있다. JPA 동작원리 애플리케이션 내에서 EntityManager는 EntityManagerFactory 객체에서 만들어지는데 EntityManagerFactory객체는 한개만 있고 EntityManager는 여러개 만들어 낸다. EntityManager는 한개의 트랜잭션을 가질 수 있다. EntityManager가 관리하는 트랜잭션 내에서 애플리케이션 성능을 높이기 위해 영속성 컨텍스트라는 개념이 나온다. 영속성 컨텍스트란 JPA 내부 동작 방식을 이해하려면 영속성 컨텍스트를 이해해야 하..
@Entity 사용 유의사항 1. @Entity를 매핑해서 사용할 클래스는 기본생성자는 필수다(public 또는 protected 생성자) JPA 구현체들은 클래스의 인스턴스를 생성할 때 기본 생성자를 필요로 한다. 기본 생성자가 없으면 JPA 구현체가 클래스의 인스턴스를 생성할 수 없다. 또한 JPA는 성능 최적화를 위해 프록시 패턴을 사용하는데 프록시 객체를 생성하는데 기본 생성자가 필요하다. 2. Final 클래스, enum, interface, inner 클래스에는 사용할 수 없다. Final 클래스는 상속이 안되므로 프록시 객체를 생성하지 못한다. 3. DB에 저장할 필드에 final을 사용하면 안된다. JPA는 엔티티를 영속성 컨텍스트에서 관리하고 데이터베이스와 상호 작용할 때 필드의 값을 ..