전체 글 140

Spring Security Filter의 동작 흐름

Spring Security Filter를 알기 전에 웹요청의 처리 흐름에 대해 먼저 알아야 한다. Servlet의 FilterChain 서블릿기반 어플리케이션의 경우, 클라이언트에서 웹요청이 들어오면 서블릿 컨테이너는 해당 요청을 DispetcherServlet으로 보내기 이전에 FilterChain을 생성한뒤 HttpServletRequest를 진행한다. 이때 FilterChain을 구성하는 요소들이 Filter이다. 이때 하나의 서블릿은 하나의 HttpServletRequest와 HttpServletResponse를 제어하며 이를 위해 여러 Filter들이 사용될 수 있다. DelegatingFilterProxy Servlet filter가 Servlet container 안에 존재하는 것과 달리 ..

멱집합 심화

문제 말썽꾸러기 김코딩은 오늘도 장난을 치다가 조별 발표 순서가 담긴 통을 쏟고 말았습니다. 선생님께서는 미리 모든 발표 순서의 경우의 수를 저장해 놓았지만 김코딩의 버릇을 고치기 위해 문제를 내겠다고 말씀하셨습니다. 김코딩은 모든 조별 발표 순서에 대한 경우의 수를 차례대로 구한 뒤 발표 순서를 말하면 이 발표 순서가 몇 번째 경우의 수인지를 대답해야 합니다. 총 조의 수 N과 선생님이 말씀하시는 발표 순서 K가 주어질 때, 김코딩이 정답을 말 할 수 있게 올바른 리턴 값을 구하세요. 모든 경우의 수가 담긴 배열은 번호가 작을수록 앞에 위치한다고 가정합니다. ex) N = 3일경우, [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 문제 요약 N 만큼의 요소를 가..

BindException과 MethodArgumentNotValidException

개인 프로젝트를 하던중 쿼리 파라미터의 정보가 만들어 놓은 Dto의 유효성 검증에 실패했을때 BindException이 발생 하게 되어 @ExceptionHandler를 이용하여 해당 예외에 대한 처리를 코드로 작성 해주려 하고 있었다. BindException에 대한 예외 처리 코드 작성 GlobalExceptionAdvice @RestControllerAdvice public class GlobalExceptionAdvice { @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) public ErrorResponse handleMethodArgumentNotValidException( MethodArgumentNotValidException e) {..

Personal Research 2023.05.10

Spring Rest Docs Custom

다이전 포스트에서 Spring Rest Docs를 이용하여 API문서의 자동화를 진행하던 중 몇가지 보완해야될 점을 발견했다. 테이블에 optional에 대한 정보 표현 유효성 검증에 대한 정보 표현 두가지를 표현하기 위해서 Spring Rest Docs 사용자 정의를 이용하여 API문서를 좀 더 개발자에 맞게 표현해줄 수 있다. Optional에 대한 정보 표현 1. Request fields의 Optional에 대한 정보 표시 @WebMvcTest(MemberController.class) @MockBean(JpaMetamodelMappingContext.class) @AutoConfigureRestDocs public class MemberControllerRestDocsTest { ... ... ..

Spring Rest Docs (API 문서화)

API 문서화란 클라이언트가 REST API 백엔드 애플리케이션에 요청을 전송하기 위해서 알아야 되는 요청 정보(요청 URL(또는 URI), request body, query parameter 등)를 문서로 잘 정리하는 것을 의미한다. API 자동 문서화의 방법으로 Swagger와 Spring Rest Docs를 사용한다. 둘의 특징은 다음과 같으며 이번 포스트에서는 Spring Rest Docs를 사용한다. Swagger의 API 문서화 방식 애터네이션 기반의 API 문서화 방식 애플리케이션 코드에 문서화를 위한 애너테이션들이 포함된다. 가독성 및 유지 보수성이 떨어진다. API 문서와 API 코드 간의 정보 불일치 문제가 발생할 수 있다. API 툴로써의 기능을 활용할 수 있다. Spring Res..

Slice test

메서드 단위로 테스트하는 단위 테스트와 는 달리 Slice 테스트는 계층별로 테스트를 진행한다. (ex. Api 계층, 서비스 계층, 데이터베이스 계층) API 계층 테스트 Api계층의 Controller 테스트를 위한 테스트 클래스 구성 import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springfra..

Unit test (단위 테스트)와 테스트 종류

단위 테스트 위의 그림에서 알수 있듯이 단위 테스트는 가장 작은 단위인 메서드 단위로 테스트하는 것을 말한다. F.I.R.S.T 원칙 단위 테스트를 위한 테스트 케이스를 작성하기 위해 참고할 수 있는 가이드 원칙으로 F.I.R.S.T 원칙을 참고할 수 있다. Fast(빠르게) 일반적으로 작성한 테스트 케이스는 빨라야 한다. Independent(독립적으로) 각각의 테스트 케이스는 독립적이어야 한다. Repeatable(반복 가능하도록) 테스트 케이스는 어떤 환경에서도 반복해서 실행이 가능해야 된다. Self-validating(셀프 검증이 되도록) 단위 테스트는 성공 또는 실패라는 자체 검증 결과를 보여주어야 한다. Timely(시기적절하게) 단위 테스트는 테스트하려는 기능 구현을 하기 직전에 작성해야 ..

DB N+1 문제해결(JPQL의 join fetch 사용)

N+1문제란 DB에서 어떠한 데이터를 불러올때 해당 엔티티의 연관관계(N)만큼 쿼리가 추가 발생하는 문제이다. 이러한 문제를 JPQL의 join fetch를 사용하여 발생하는 쿼리의 수를 줄일수가 있다. 테스트를 위한 세팅 @Profile("n-plus-one-problem") @Configuration public class NPlusOneProblemConfig { private EntityManager em; private EntityTransaction tx; @Bean public CommandLineRunner testJpaFetchStrategyRunner(EntityManagerFactory emFactory) { this.em = emFactory.createEntityManager();..

이벤트리스너와 비동기

이벤트리스너 ApplicationEventPublisher를 이용하여 이벤트를 발생시킨뒤 @EventListener와 @TransactionalEventListener 에너테이션을 사용하여 정해진 대상과 관련된 메서드를 특정한 시점에 호출시킬수 있다. 이벤트리스너를 사용하면 정해진 조건에 맞는 이벤트만을 추적하여 관련된 메서드만을 자동으로 실행시킬수 있게 되어 따로 특정한 로직을 실행 시키기위해 다른 객체들과 의존관계를 맺지 않아도 되어 코드간의 의존성을 낮추고 더 독립적인 프로그래밍이 가능하다. 예제 코드 @Getter @Component @Slf4j public class EventHandler { // 1. @EventListener public void process(Member member){ ..

BeanWrapper를 이용하여 객체의 필드값 접근

기존코드 public Member updateMember(Member member) {// 수정시킬 필드값들을 담고있는 Member 엔티티 객체 Member findMember = findVerifiedMember(member.getMemberId());// 데이터베이스에 저장된 Member 엔티티 객체 //매개변수로 받은 객체의 필드들을 하나씩 확인하여 값이 들어있는 필드의 값들만 업데이트 Optional.ofNullable(member.getName()) .ifPresent(name -> findMember.setName(name)); Optional.ofNullable(member.getPhone()) .ifPresent(phone -> findMember.setPhone(phone)); Optio..