🔍 리팩토링 전의 코드 프로젝트 중 테스트를 작성하면서, 기계적이고 반복적으로 하나의 패턴을 여러 상황별 테스트 메서드에 공통으로 사용하고 있음을 발견했다. 아래 두 코드 블럭들과 같이 모든 코드가 동일하고 ErrorCode 의 종류와 HTTP 상태를 나타내는 status() 만 차이가 있는 메서드들이 있었다. 기능 구현 메서드들을 작성할 때에는 템플릿 콜백 패턴과 같이 인터페이스를 활용해 중복을 제거하고 관심사를 분리할 수 있었는데, 테스트 코드에서는 한 번도 매개 변수를 가진 메서드를 정의해본 적이 없다는 단순한 이유로 하나의 메서드에서 작성한 코드를 ctrl+c, ctrl+v (복사 후 붙여넣기) 하여 다른 메서드에서 쓰는 비효율적인 프로그래밍을 했다. 리팩토링을 거쳐서 어떻게 중복을 줄이고 공통된..
📃 Introduction 프로젝트에서 스프링 시큐리티를 적용해 기본적으로 모든 API 경로는 인증 절차를 거치게 하고, 회원가입과 로그인을 포함한 몇몇 API 는 인증이 없이 호출이 가능하도록 변경해야 했다. 모든 API 가 인증 절차를 거치게 하는 것은 어렵지 않았으나, 몇 개의 API 가 인증이 없이도 호출되도록 변경하는 것이 까다로웠다. 🚩 현재 상황 아래는 현재 보안 필터 체인의 구성이다. 각각 회원가입과 로그인을 나타내는 POST /api/v1/user/join 과 POST /api/v1/users/login 을 antMatchers 의 permitAll() 메서드를 활용해서 인증 절차가 필요하지 않게 설정해주었다. 문제는 GET api/v1/posts/** 또한 인증 없이 호출되게 설정했다는..
🔍 현 상황 프로젝트 진행 과정 프로젝트를 하면서 스프린트를 두 개로 나누었다. 각 스프린트를 브랜치로 만들었다. 첫 스프린트 단위는 브랜치 이름으로 sprint1 을 사용했다. sprint1 을 source 브랜치로 각 기능 구현을 할 때마다 1개 브랜치씩 만들었고, 기능 구현을 마칠 때마다 sprint1 으로만 병합을 하고 main 은 놔두었다. sprint1 의 모든 작업을 마친 후 main 브랜치에 병합을 할 생각이었다. 문제 발생 스프린트가 끝나기 전까지 모든 기능 단위에 대한 브랜치는 sprint1 에만 병합, 즉 merge 가 되어야 했다. 근데 무슨 생각이었는지, 실수로 Target branch 를 바꾸어주지 않고 main 에 기능 한 개를 merge 하고 말았다. 이후 main 에 스프린..
Configuration 클래스에서 HandlerExceptionResolver 주입하기 기존 SecurityConfig 클래스에 다음 두 줄을 추가한다: private final HandlerExceptionResolver exceptionResolver; public SecurityConfig(@Qualifier("handlerExceptionResolver") HandlerExceptionResolver exceptionResolver) { this.exceptionResolver = exceptionResolver; } 그리고 기존에 JwtAuthenticationFilter 는 매개 변수로 비밀 키만 받고 있었는데, 필드 변수로 생성된 exceptionResolver 도 받도록 변경한다. 보안 ..
🚀 사건의 전말 GitLab 으로 버전 관리를 하는 프로젝트에 CI, 지속적 통합을 적용하기 위해서는 YAML 파일 .gitlab-ci.yml 에 프로젝트 리포지토리에 변경이 일어날 때마다 실행될 파이프라인에서 사용할 명령어들로 구성된 스크립트를 작성해야 한다. 내 프로젝트에서는 Docker 를 이용해 애플리케이션을 Gradle 로 빌드하여 Docker 이미지를 만들어야 했다. 아래와 같이 YAML 파일을 작성하였다. 레포지토리에 있는 Dockerfile을 사용해서 Docker 이미지를 생성한다. 그리고 깃랩의 컨테이너 레지스트리에 등록한다. stages: - dockerbuild-push package: image: docker:latest stage: dockerbuild-push services: ..
📌 개요 위치에 따라 번호가 매겨져 있는 아파트들의 옥상에 5G 기지국을 설치하려고 한다. 5G 기지국은 기존에 설치되어 있는 4G 기지국과는 전파의 전달 범위가 다르다. 기존에 4G 가 설치되어 있는 아파트들의 목록을 담은 배열 stations 와 총 아파트의 개수 N, 그리고 5G 기지국을 설치했을 때의 전파 전달 범위를 나타내는 W 가 주어졌을 때, 모든 아파트에 전파를 전달하기 위해 설치해야 하는 기지국의 최소 개수를 구하여라. 예) N = 11, stations = [4, 11], W = 1 4번 아파트와 11번 아파트에 전파 전달 범위 1 의 기지국이 설치되어 있으므로, 전파를 전달받을 수 있는 아파트는 위 그림과 같이 3, 4, 5, 그리고 10, 11번 아파트이다. 나머지 1, 2, 6, ..
📃 Introduction 웹 어플리케이션을 배포하여 서비스로서 제공할 때, 클라우드를 사용한 가상 서버 호스팅 또는 물리적인 서버를 직접 구매 또는 임대하는 방법이 있다. 오늘은 가상 서버 호스팅이 무엇인지에 댇해서 알아보고자 한다. 📌 가상 서버의 정의 사용하는 방식에 따라 정의가 달라질 수 있다고 한다. 서버는 물리적인 데이터 센터 또는 클라우드 환경에 위치할 수 있는데, 하나의 물리적인 서버를 다른 이들과 공유하기 위해 사용되는 것이 바로 가상 머신이다. (Virtual Machine) 서버는 본래 하나의 기업이나 개인을 위해 사용되는 것이 일반적이었으나, 서버의 가상화를 통해 한 서버가 제공하는 자원을 다양한 사용자가 나누어 사용할 수 있게 되었다. 가상 서버는 물리 서버에 비해 하드웨어가 필요..
📝 Summary Mustache 를 사용해서 웹 페이지를 만들고 있다면, HTML 태그 중 과 을 사용해서 POST 요청을 처리한 경험이 있을 것이다. 이 때, 만약 API 가 문자열 형태의 데이터를 받는다면, 태그 안에는 반드시 type="text" 라고 명시해주어야 한다. 그렇지 않으면 문자열을 인식하지 못해 null 로 인식하게 된다... 라고 생각했던 프로젝트의 과정 중 일부를 소개한다. 프로젝트 중 컨트롤러에서 API 를 설계한 후 mustache 템플릿을 이용해서 view 를 처리하고 있었다. 로그인 정보를 입력하면 사용자를 로그인시킨 후, 다음 화면으로 넘어가는 동작을 구현하고 있었다. 다음과 같은 API 를 작성했다: 이 API 들을 활용하기 위해 home.mustache 에 아이디를 f..
- Total
- Today
- Yesterday
- 도커
- N+1
- ci/cd
- DeSerialization
- Java Data Types
- 깃랩
- 알고리즘
- JPA
- 기지국 설치
- LazyInitializationException
- @RequestBody
- 인증/인가
- docker
- DTO
- ResponseEntity
- Jackson
- spring security
- 지연 로딩
- json web token
- 코딩 테스트
- 서버 호스팅
- 코테
- gitlab
- JPQL
- 역직렬화
- Spring Boot
- 가상 서버
- 프로그래머스
- google cloud
- JOIN FETCH
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |