개요Dktechin 주관 기업실무 프로젝트를 진행하면서 Argument Resolver를 이용해서 컨트롤러에서 조건을 어노테이션으로 받아 조금 더 가독성있고 간단하게 사용하는 방법을 알게되어서 정리해보려고 한다.이 방법을 통해서 검색 조건 파라미터들을 @SearchParam이라는 어노테이션으로 받아서 MemberSearchParam, BoardSearchParam 등 여러 Record 객체로 만들어서 사용했다.HTTP 메시지 컨버터컨트롤러에서 변수 바인딩 처리 방법특정 변수에 바인딩@RequestParam 사용가변 경로 변수 바인딩@PathVariableHttp Body 변수 바인딩@RequestBody(주로 DTO 사용)파일과 같은 Multipart@RequestPart이 때 Argument Resol..
개요이 때까지 Service 테스트는 필수적으로 해왔는데 Controller 테스트는 postman으로 해보고 되면 되는구나하고 넘겼다.과거의 나 반성해라!근데 유닛 테스팅에 대해 공부하던 중 Controller 테스트도 하는 것이 무조건 좋다고 해서(Postman은 http에 비해 상당히 제약이 적기 때문이다.)그래서 Controller 테스트 코드 작성한거랑 발생한 오류들에 대해 정리해볼 것이다. Test 코드Test 코드 어노테이션@WebMvcTest(controllers = EpisodeController.class)@MockBean(JpaMetamodelMappingContext.class)@AutoConfigureMockMvc 먼저 Service 테스트 코드와 다르게 @SpringBootTes..
개요Spring Boot와 TypeScript 기반으로 웹 애플리케이션을 제작하고 있는데 유저 프로필 이미지를 받아 저장하는로직이 필요했다.이를 위해서 프론트에서 보낸 이미지를 MultiPartFile로 받아서 S3에 저장하는 방식으로 구현하기로 했다.S3 생성이나 키 생성과 같은 AWS 관련 할 일은 생략하겠다.Spring Boot S3 연결연결을 위해서는 AWS의 access키랑 secret키를 등록해야 한다. 오타에 조심하자.. }안써서 1시간 고생했다.cloud: aws: s3: bucket: ${bucket-name} credentials: access-key: ${access-key} secret-key: ${secret-key} region: ..
문제 발생 @Builder를 사용해서 엔티티의 1:N 관계를 정의하던 중 new ArrayList()로 필드를 초기화 해도 NullPointException 에러가 발생했다. List가 Builder 패턴을 이용해서 엔티티를 초기화할 때 Null값으로 된 것이다. Cannot invoke "java.util.List.add(Object)" because the return value of "semicolon.MeetOn_WhenToMeet.domain.when_to_meet.domain.WhenToMeet.getTimeTableList()" is null java.lang.NullPointerException: Cannot invoke "java.util.List.add(Object)" because t..
개요 Spring Cloud Eureka로 웹 서비스 토이? 프로젝트를 진행하던 중 프론트 개발자의 요청으로 Swagger를 배포하여 API 연결할 일이 생겼다. 근데 각 서버마다 자신의 포트로 Swagger를 열면 상당히 불편할 것 같다는 결론이 나왔다. 하나의 uri로 모든 서버의 Swagger-ui로 접근할 수 있게 해달라는 부탁명령이 내려왔다. Swagger란? 개발한 Rest API를 편리하게 문서화하여 이를 사용하는 사용자가 편리하게 API를 호출하고 테스트할 수 있게 도와주는 프로젝트 이다. Spring Boot 기준 밑 dependency를 추가해주면 간단하게 쓸 수 있다. implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui..
개요 엔티티 객체를 Dto로 변환하는 과정에서 For문을 사용하는 것 보다 Stream을 이용하는 방법으로 구현하고 있는데 둘의 성능 차이가 궁금해져서 한 번 해보려고 한다. Stream 특징 데이터를 읽기만 한다. 병렬 처리가 쉽다. 가독성이 좋다. 상황에 따라 다르겠지만.. 데이터 셋이 클수록 병렬 스트림을 이용하여 For문에 비해 성능이 좋아진다. Stream VS For 성능 비교 ArrayList 자체가 원시 데이터에 비해서 워낙 순회하는데 비용이 커서 속도 차이는 별로 안난다고 한다. 백문이 불여일견(타) 한번 테스팅 해봤다. 내가 제일 자주 사용했던 엔티티 리스트를 Dto로 리스트로 변환하는 stream.map(lambda).toList()를 사용했다. 테스팅 코트 @Test void For..
개요 Next.js와 Spring Boot를 기반으로 하는 웹 애플리케이션 프로젝트에서 카카오 소셜 로그인을 구현하게 되었다. JWT를 기반으로 인증, 인가 관련 기능을 구현하기로 해서 클라이언트에게 엑세스 토큰과 리프레시 토큰을 발급하여 로컬 스토리지에 저장하고 사용하는 방식을 택했다. 이를 개선해보려고 한다. 엑세스 토큰, 리프레시 토큰 엑세스 토큰 유효 기간이 매우 짧은 토큰으로 따로 DB에 저장하지 않고 받은 값을 Spring Security의 필터체인을 통해 검사하고 유효 여부를 판단한다. 주로 30분 정도로 짧은 시간 내에 인증을 위해서 사용한다. 리프레시 토큰 유효 기간이 엑세스 토큰에 비해 비교적 긴 토큰이다. 엑세스 토큰이 만료되었을 때 새로운 엑세스 토큰을 발급하기 위해 사용한다. 문제..
* 그냥 제 생각대로 만들어서 해결했습니다. 정답x 고민 회원 가입 로직을 구현하던 중 Private 메소드에 대한 테스트를 어떻게 진행해야 할 지에 대한 고민이 생겼다. 외부에서 접근하지 않는 메소드로 굳이 Public으로 작성할 이유가 없었기 때문이다. 실제 문제: 이메일 인증을 완료하고 회원 가입을 승인해주는 로직에서 이메일 인증을 보내기 전에 데이터베이스에 같은 이메일이 존재하는 지 확인하고 존재하지 않는다면 인증 코드를 보내고 아니면 예외를 발생시켜야 했다. 이 때 이메일 중복 확인 메소드를 Private으로 설정했고 테스트 코드를 작성할 때 이메일 중복 확인이 잘 되는지 확인하고 싶었다. 코드: AuthService private void checkDuplicatedEmail(String em..
처음 처음에 Enum 타입에 대해서 부정적으로 바라봤다. Enum 클래스를 새로 생성하는 것도 별로라고 생각했고 성능적으로 크게 높아지는지 확신도 없었기 때문이다. 근데 역시 그냥 생기는 기술은 없는 것 같다. Enum 타입을 무시하고 사용하지 않은 대가를 톡톡히 치뤘다. ㅠㅠㅠㅠ Enum 타입을 사용하지 않는다면? 프로젝트를 진행할 때 각종 데이터 타입을 모두 String으로 설정했었다. 처음에는 아무 문제도 없었다. 사실 조심만 하면 사용하는데 크게 문제는 없었다. 단순히 MessageType이나 NoticeType과 같은 형식이 정해진 값들도 오타만 내지 않는다면 테스트 코드나 DB에 넣을 때도 크게 어려움은 없었다. 실제로 사용한 noticeType private String noticeType;..
세션 대신 JWT를 사용하기 위해 각종 코드를 적용하면서 코드를 그대로 가져오려니 이해안되는 부분이 많았다. 코드도 복잡하고 동작 과정도 모르는 상태로 사용하려니 JWT 형식 변경이나 유지보수에 어려움이 있을게 뻔해서 자주 볼 수 있게 정리해보려고 한다. 참조 https://blog.javabom.com/minhee/session/spring-security-1/spring-security https://bcp0109.tistory.com/301 JWT 적용을 위해 봤던 코드 및 로직들 1. Why JWT? JWT의 특징 사용자 인증에 필요한 모든 정보를 토큰에 담아 클라이언트(React)에 저장하기 때문에 별도의 DB 테이블이 필요 없다. 일반 토큰과의 가장 큰 차이점 분산 마이크로 서비스 환경에서 클..