Programming 127

[Kotlin] 코틀린에서 Mockito 사용시 final class 문제 해결

Intro 코틀린으로 코드를 작성하다보면 간혹가다가, 자바에서는 별 문제 없던게 의도대로 동작하지 않을 때가 있습니다. 이번에는 테스트 코드를 작성하다가 스터빙을 하려고 하는데 문제가 있었는데요, 아래와같이 테스트를 하려고 했습니다. // When val memberContext = Mockito.mock(MemberContext::class.java) Mockito.`when`(memberContext.member).thenReturn(member) quizService.edit(memberContext, quiz.id!!, quizEditDto) // Then val findById = quizService.findById(quiz.id!!) assertThat(findById.description)..

Programming/Kotlin 2022.09.25

[Kotlin] 코틀린에서 queryDSL 설정하기

Intro 자바에서도 QClass 생성은 처음 하면 꽤나 당황스러운 과정인데, 코틀린은 또 과정이 달랐기에 결과물을 기록으로 남기고자 합니다. 2022년 9월 19일 기준의 최신 라이브러리들에서 잘 작동하고 있는 방법 입니다. 설정 build.gradle.kts plugins { ... kotlin("kapt") version "1.7.10" } dependencies { ... implementation("com.querydsl:querydsl-jpa:5.0.0") kapt("com.querydsl:querydsl-apt:5.0.0:jpa") } 소스코드는 딱 위의 변경 사항만 있었습니다. 의존성 변경 후에 Shift + Command + I 키를 입력 해서 Load Gradle Changes를 해 주..

Programming/Kotlin 2022.09.19

[Spring] @PageableDefault 혹은 @SortDefault 여러 컬럼으로 정렬하기

Intro 컨트롤러를 통해 페이지 정보를 받고, 서비스 레이어 및 Persistence Layer를 통해 여러개의 데이터를 조회 할 때 종종 @Pageable Default 어노테이션을 사용합니다. 예를 들어 컨트롤러에서 @PageDefault를 아래와 같이 설정 하면 Kotlin @GetMapping fun findAll(@PageableDefault(sort = ["id"]) pageable: Pageable): ApiResponse { return ApiResponse.ok(quizService.findAll(pageable).map { quiz -> QuizDto.of(quiz) }) } Java @GetMapping public ApiResponse findAll(@PageableDefault(..

[Spring] mockMvc 스프링 시큐리티와 연동하기. @AuthenticationPrincipal 파라미터 전달 해결

Intro mockMvc를 통해 api 테스트를 진행 하는데, 스프링 시큐리티를 연동 하기 전에는 괜찮았는데 연동을 한 후에 테스트가 제법 까다로웠습니다. 일단 단순 로그인 여부만 체크하는 부분은 간단하게 넘어갈 수 있었는데, @AuthenticationPrincipal 어노테이션을 걸고 파라미터로 컨트롤러에서 로그인 정보를 받아오는 부분까지 테스트 하려니 쉽지 않았습니다. 제가 코틀린으로 토이 프로젝트를 하고 있다보니 코드는 코틀린이 대다수지만 사실 자바와 차이가 없기 때문에 자바로 진행하고 계신 분들도 같은 맥락으로 문제 해결을 하실 수 있으며, 마지막에는 자바 코드도 조금 첨부 해 두었습니다. MockMvc NoSecurity 일단 처음으로, 따로 시큐리티 인증 과정이 없는 api의 mockMvc ..

[Kotlin] 코틀린에서 Validation 이 안될때 해결방법

문제 create를 위한 DTO를 생성 해서 자바에서 사용했던 것 처럼 validation을 해 보려 했는데 밸리데이션이 전혀 먹히지가 않았습니다. QuizCreateDto.kt data class QuizCreateDto( @NotBlank val description: String, @NotBlank val answer: String, @NotBlank val explanation: String, val examples: Array ) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is QuizCreateDto) return false if (description != other.descr..

Programming/Kotlin 2022.09.07

[Spring Boot JPA] P6Spy 활용해 쿼리 로그 확인하기

Intro 스프링부트와 JPA로 프로젝트를 진행하다 보면 실제 쿼리가 어떻게 나갈지 눈으로 확인을 하고 싶을 때가 참 많습니다. JPA가 참 편하긴 한데 개발자가 직접 쿼리를 작성하지 않았다 보니 실제로 어떤 쿼리가 나갈지는 눈으로 확인 하기 전까지는 정확히 알기 힘들고, 가끔씩은 의외의 쿼리가 나가는걸 보고 놀라기도 합니다. 제 기준에 쿼리를 꼭 확인해야 할 상황이 크게 두가지 정도가 있었는데요 의도한대로 작동하지 않아서 쿼리가 의심될 때 N+1 문제가 발생하고 있는지 확인이 필요할 때 그러다보니 항상 테스트 설정에서는 쿼리가 전부 출력되게 설정 해두고 테스트 코드들을 실행 시키고 있습니다. 확실히 쿼리가 눈으로 확인이 되면 마음의 안정이 좀 오는 것 같아요. 쿼리 로그를 확인하는 방법을 단계별로 개선..

jQuery AJAX대신 XHR로 파일 다운로드하기

Intro a 링크를 통한 파일 다운로드를 제공 하고 있었는데, 개선이 필요했습니다. 전체 데이터를 poi를 활용해 엑셀 파일을 생성 한 뒤에 반출을 해 주는 과정인데, 데이터가 클 수록 파일을 작성하는데 워낙 시간이 오래 걸리다보니 기다리는동안 사용자 경험이 너무 좋지 않았습니다. 그래서 파일 다운로드 과정을 AJAX를 이용해 비동기로 요청하고, 요청을 기다리는 동안 waitMe 를 이용해 로딩바를 보여주는 식으로 개선을 하기로 했습니다. https://github.com/vadimsva/waitMe AJAX 이를 위해 jQuery AJAX를 활용해 코드를 구현 해 보았습니다. $('#export').on('click', function () { var wait = $(th..

Programming/javascrlpt 2022.08.23 (3)

Armeria 튜토리얼 따라해보기

Intro Build a reactive microservice at your pace: Armeria는 아주 작고 단순한 형태로부터 시작해 점차 서비스를 키울 수 있게 해줍니다. your go-to microservice framework for any situation: 어떤 상황에서도 마이크로소프트를 만들 수 있는 프레임워크 입니다. gRPC, Thrift, GraphQL 등의 프로토콜도 지원합니다. 최근 학습을 하다보면 비동기와 논블로킹이라는 키워드가 참 많이 보입니다. 부끄럽지만 저는 항상 Java로 동기식 서버만을 작성해와서 잘 모릅니다. 4개월 쯤 전 프로젝트의 스프링부트 버전을 1.x -> 2.x 으로 마이그레이션 하기 위해 그 차이를 학습중에 스프링 5의 WebFlux 라는게 눈에 들어왔..

Programming/Java 2022.08.20

[Java] Optional 올바르게 사용하기

Intro 자바가 8버전으로 넘어오며 추가된 기능들이 굉장히 많이 있습니다. 보통 가장 먼저 언급되는 Lamdba와 Stream API 뿐만 아니라 조금의 차이는 있지만 Joda-Time을 그대로 가져온듯한 날짜와 시간 API, 인터페이스에 추가된 Default 메서드와 static 메서드 등 지금까지 이 기능들 없이 어떻게 코드를 짰을까 싶은 요소들이 굉장히 많습니다. 그중에서도 둘째로 치면 서러워 할 클래스가 있으니 바로 Optional 입니다. Optional java.util.Optional.java 자바 아키텍트인 Brian Goetz는 결과 값이 없음을 명확하게 표현 하려는 의도로 Optional을 추가했다고 합니다. 자바8 이전까지는 null이 그 역할을 해 왔지만, null을 사용할 경우에..

Programming/Java 2022.07.21

[Java] switch 문이 if-else 보다 효율적인 이유

Intro 코드를 작성하다 보면 switch 문으로 작성할지, 혹은 if-else 를 사용할 지 고민될때가 자주 있습니다. 개인적으로는 보통 elseif 가 두개이상 붙게되는 시점부터는 보통 코드의 가독성이나 문맥에 따라 switch 문을 사용 하려 하고 있습니다. if.java void function(String args) { if ("a".equals(args)) { // A logic } else if ("b".equals(args)) { // B logic } else { // C logic } } switch.java void function(String args) { switch (args) { case "a": // A logic break; case "b": // B logic break..

Programming/Java 2022.07.09

[JAVA] zxing 활용해 QR코드 생성하기

Intro COVID 19 이후로 정말 많은것이 달라졌습니다. 하나하나 나열하기도 힘든 만큼 일상 생활 속에서 달라진 것 들이 많지만 그 중 하나의 기술을 뽑자면 QR 코드가 아닐까 싶습니다. 아주 오래전부터 있었지만 별다른 주목을 받지 못했고 그렇게 잊혀지는가 했는데 코로나로 인한 방문 기록, 전자문진표 등 조금씩 많이 쓰이는가 싶더니 카카오페이를 비롯한 여러가지 간편결제 서비스가 많아지면서 없어서는 안 될 기술이 되었습니다. 어플리케이션을 만들 때에도 곳곳에 QR코드를 활용 할 일이 많아졌는데요, QR코드 생성 한다면 크게 두가지 방법이 있습니다. 구글의 QR Codes API 에 요청 QR 코드를 작성하는 OpenSource를 활용해 로컬에서 생성 얼핏 보면 외부 API를 활용 하는게 간단해 보이는..

Programming/Java 2022.06.30

[Spring Boot] git 정보 확인하는 endpoint 작성하기

Intro 서버에 현재 배포되어 있는 어플리케이션의 버전 정보를 표시 할 수 있는 방법이 있을까 고민을 해 보았습니다. 하나의 프로젝트가 여러개의 서버에서 각기 다르게 서비스 되고 있다 보니 해당 정보를 관리자 페이지에서 확인 할 수 있게끔 하면 좋겠다는 생각이 들었는데요. 방법이 있었습니다. git-commit-id-plugin 이라는 메이븐 플러그인을 활용하면 어렵지 않게 구현 할 수 있습니다. 아래는 Spring Boot 공식 매뉴얼에 작성된 관련 내용 입니다. https://docs.spring.io/spring-boot/docs/2.1.7.RELEASE/reference/html/howto-build.html#howto-git-info 설정 Maven Dependencies pom.xml org..

JAVA) 자바에서는 Call By Reference가 불가능 합니다.

Intro 사실 자바를 처음 배우고나서 최근까지도 함수를 호출 하여 파라미터가 전달 될 때에 primitive 타입인 경우에는 value가, 그 외에는 reference가 전달 된다 라고 알고 있었습니다. 자바에서의 Primitive 데이터 타입들 byte short int long float double boolean char String의 경우에만 String pool을 통해 immutable로 관리되기 때문에 primitive가 아님에도 call by reference가 되지 않지만 Java) String의 Immutable이 의미하는 것 그 외에는 reference가 넘어간다고 알고 있었는데요 그 개념 하에서는 LinkedNode 나 Trie 등을 다루는 메서드를 짤 때 마다 뭔가 생각한 대로 동..

Programming/Java 2022.06.06

Kotlin) Data class 에 기본 생성자 만들기

Intro Kotlin과 SpringBoot를 활용해 스프링 시큐리티를 공부하고 있습니다. 아직은 코틀린에 익숙하지가 않아 자바로 된 코드를 코틀린으로 작성 할 때는 한번씩 꽤나 막히는 부분이 있는데, 이번에는 기본 생성자를 찾지 못한다는 오류가 발생했습니다. 생성자가 없다는 오류 기본 생성자를 찾지 못해 에러가 발생하고 있었는데요.. 자바였다면 그냥 @NoArgsContructor 라는 롬복 어노테이션 하나만으로도 해결 할 수 있는 이 상황을 코틀린에서는 어떻게 해결 해야 할까요? 문제의 원인이 된 상황과 해결 방법을 확인 해 보겠습니다. 원인 일단 발단이 된 코드는 아래와 같습니다. jackson 라이브러리를 활용해 request의 reader를 그대로 읽어 AccountDto 로 변환 하는 과정 인..

Programming/Kotlin 2022.05.25

JAVA) Date 를 LocalDateTime 으로, 혹은 그 반대로 변환하기

Intro 제법 오래된 프로젝트를 유지보수 하고 개선하다보니, Date 타입을 다루어야 할 일이 제법 많이 있습니다. Date API는 JDK 1.0 부터 제공된 유구한 역사를 가진 클래스인데요, 워낙 문제가 많다보니 JDK 1.1에서 바로 Calendar 클래스가 추가 되며 Date의 많은 메서드들을 @Deprecated 시켜버렸지만 여전히 오랜기간 꾸준히 애용되어 왔습니다. 그러다 마침내 JDK 1.8 버전에서 JodaTime 의 날짜와 시간 API가 추가되면서 LocalDateTime 이나 LocalDate를 사용 할 수 있게 되었습니다. 기존에 있는 Date를 걷어낼 수 있으면 참 좋겠지만, 그럴 여유가 없을 경우에는 일단 새로 작성하는 코드들에서 최대한 Date 사용을 피하지만, 어쩔 수 없이 ..

Programming/Java 2022.05.23