본문 바로가기

전체 글455

JUnit Test로 컨트롤러 API 테스트 (RestTemplate, MockMVC) 테스트를 할 때는 서비스단을 호출하는 경우도 있지만, 종종 컨트롤러에 있는 API를 호출하는 경우도 있다. 이는 너무 당연한 거라서 굳이 따로 포스팅을 하지 않았었다. 그런데 오늘도 PM 부장님의 요청으로 한 가지 테스트를 하기로 했다. 테스트는 별 건 아니고, 특정 API를 여러 번 찔러서 평균적으로 속도가 얼마나 걸리는지 확인해보는 일이었다. 굳이 JMeter까지 사용할 건 아닌 것 같아서, 간단하게 Test 코드를 작성하고 돌리려고 했다. 우선 테스트 대상으로 아래와 같은 간단한 API가 있다고 해보자.private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");@GetMapping("/date")public String date().. 2024. 11. 6.
SSE를 사용해 알람 구현 비슷하지만 다른 웹 어플리케이션 두 개를 우리 팀과 다른 팀에서 각자 구현중이다. 정말 상세하게 요구사항을 하나 하나 짚어보면 엄연히 다른 웹 어플리케이션이지만, 어느정도 비슷한 어플리케이션 이니만큼 공통적인 부분은 존재한다.그리고 다른 팀은 우리 팀에 비해 인원이 월등히 많기 때문에 개발 속도가 현저히 빠르고, 이로 인해 공통적인 부분은 해당 팀의 소스코드를 참고해서 개발을 수행중이다. 어쨌든 공통적인 부분 중에는 알람 기능도 존재한다. 별 건 아니고 배치 모듈에서 이상사항을 발견하고 알람을 DB에 Insert하면, 이를 로그인한 사용자들의 화면에 띄워주는 것이다.알람 기능 역시 다른 팀이 먼저 개발을 해놓았기에 이를 참고해서 개발을 했다. 그리고 그 과정에서 SSE라는 새로운 개념을 알게 되었다. 오.. 2024. 10. 29.
Redis도 네트워크 딜레이를 고려해야 한다 이번에 받은 요구사항이다.리스트 페이지에서 특정 데이터 목록을 조회한 후 상세 조회 페이지로 이동한다.상세 조회 페이지에는 "이전", "다음" 게시물 조회 기능이 존재한다.리스트 페이지에서 조회된 순서에 따라 "이전", "다음" 게시물로 이동해야 한다.위 요구사항은 조회를 할 때 사용한 파라미터를 쿼리 파라미터 등으로 넘겨 조회 조건을 유지함으로써 쉽게 구현이 가능하다. 하지만 문제가 하나 있는데, 그것은 바로 상세조회 페이지에서 "상태 변경이 가능"하고, 이 상태가 리스트 페이지에서 "조회 조건"에 포함된다는 것이었다. 예를 들어보자."댓글이 0개"인 게시글만을 필터링해서 목록을 조회했다.가장 첫번째에 있는 A 게시글에 들어간다.댓글을 달았다."다음 게시물로 이동" 버튼을 눌러 다음 게시물인 B 게시글.. 2024. 10. 28.
[Mybatis] Insert 후 자동으로 생성된 PK 가져오기 게시판을 예로 들어보자.아래와 같은 테이블이 존재한다고 가정한다. DROP TABLE IF EXISTS file_info;DROP TABLE IF EXISTS board_info;CREATE TABLE board_info ( `board_id` INT NOT NULL AUTO_INCREMENT, `board_title` VARCHAR(100) NULL, `board_content` VARCHAR(2000) NULL, `writer` VARCHAR(20) NULL, `crtr_dtm` TIMESTAMP NULL, PRIMARY KEY (`board_id`));CREATE TABLE file_info ( `file_id` INT NOT NULL AUTO_INCREMENT, `board_id` INT NOT .. 2024. 9. 14.
[Thymeleaf] 데이터를 동적으로 바꾸기 - replaceWith 재직중인 회사에서는 웹 UI 개발 시 거의 전부 Thymeleaf\ 사용을 선호한다. 그리고 DOM 관리에는 JQuery를, 데이터 로딩에는 Ajax를 사용하는 것을 선호한다. 사실 처음부터 웹 UI 개발을 주로 할 생각은 없었다. 원래는 백엔드 개발자가 되고 싶었고, 현재 회사도 원래는 백엔드 개발자로 들어오게 되었다. 하지만 만성 인력난에 허덕이는 중소기업의 특성상 백엔드 개발만 할 수는 없고, 제안서 작성부터 요구사항 식별, 설계, 개발, 테스트, 배포 등 전과정을 해야만 했다. 웹 UI 개발도 별로 원하지는 않았지만 어쩔 수 없이 해야하는 부분 중 하나였다. 그동안 웹 UI를 개발할 때마다 나는 한 가지 말을 입에 달고 살았다.저는 원래 웹 개발자가 아니에요. 여러 가지 뜻이 함축된 말이었다. 백.. 2024. 9. 14.
Mybatis 중복 쿼리 공통화 (<sql>과 <include>) + Interceptor 이번 프로젝트에서는 4중 조인 등 복잡한 쿼리가 많은 탓에 JPA 대신 MyBatis를 채택해서 사용했다. 그리고 지금까지 MyBatis를 사용하면서 뭣도 모르고 사용하고 있었다는 사실을 눈치챘다. 그것은 바로 지금까지 를 사용한 적이 없다는 것이었다. 어찌됐던 지금이라도 알았으니 다행이라고 생각하고, 연습 및 재활용을 위해 블로그에 기록을 해놓을까 한다. 코드에서 여러 메소드에 중복된 코드가 존재하면 어떻게 할까? 당연한 말이지만 중복된 코드가 여러 군데 존재하면 유지 보수가 어렵다. 만약 해당 코드에서 문제가 발생했을 경우 동일한 모든 코드를 수정해야 하기 때문이다. 게다가 쓸데없이 코드가 길어져 가독성도 저하된다. 이를 위해 중복된 코드가 발견될 경우 메소드로 만드는 "메소드화' 리팩토링을 하곤 .. 2024. 9. 7.
[Spring] 자바 이미지 핸들링 이번 프로젝트에서 개발한 웹 사이트는 이미지를 핸들링할 일이 많은 프로젝트였다. 게다가 이미지를 그냥 가져오는 것이 아니라 "특정 부위만 잘라서" 가져와야 했는데, 이를 하려다보니 아무래도 시간이 오래 걸려 "28개의 이미지가 출력되는 웹 페이지가 출력되는 데 0.2 초 내로 걸렸으면 좋겠다. 단, 성능을 위해 이미지 품질 저하는 없어야 하고 반드시 원본 이미지를 출력해야 한다." 는 요구사항을 충족할 수가 없었다. 그래서 이런 저런 방법을 사용하며 삽질을 한 끝에 해당 기능을 완료했고,  추후 필요 시 재사용을 위한 포스팅을 해볼까 한다. 프로젝트 준비우선 핸들링할 이미지를 선택하자. 구글에서 귀여운 시츄 사진을 가져왔다. 해당 사진은 D:\images\ 내에 넣어놓았다. 그리고 스프링 프로젝트를 생성.. 2024. 7. 21.
[Thymeleaf] Lang 설정을 통한 다국어 페이지 제공 웹 사이트들을 들어가다보면, 아래와 같이 여러 언어를 지원하는 웹 사이트를 발견할 수 있다.  지금까지는 국내에서만 사용될 웹 사이트를 개발했기에 굳이 해당 기술을 익힐 필요가 없었다. 하지만 다음 프로젝트는 해외에서 사용될 예정이기에 한국어+영어+a 를 지원하는 웹 사이트가 필요했고, 이에 다국어 웹 사이트 개발 방법을 공부해볼까 한다. 우선 다국어 설정 전에 html에서 사용하는 메세지를 모아놓는 messages.properties 설정 방법을 알아볼까 한다.  messages.properties를 사용한 텍스트 출력 자바 코드 내에서 여러 클래스에서 동시에 사용하는 변수는 static으로 만들거나 혹은 enum으로 만들어 사용하고 관리한다. THYMELEAF 개발 시에도 이렇게 여러 페이지에서 동일.. 2024. 6. 10.
[JAVA Spring] Thread에 시간제한(Timtout) 걸기 저번 프로젝트를 진행하던 중 한 가지 문제사항에 직면했다. 우선 로직은 아래와 같다.사용자가 데이터를 업로드한다.프로그램은 데이터를 받아 큐에 임시저장한 후 사용자에게 업로드 완료 알림을 보낸다.스케줄러가 동작하며 주기적으로 큐에서 데이터를 빼 스레드에 할당해 비즈니스 로직을 실행시킨다. 이 때 문제사항이 생겼다.사용자가 데이터를 업로드할 때, 업로드된 데이터가 너무 큰 경우이다. 너무 큰 데이터를 업로드했을 때 시간이 오래 소요되는 것은 당연한 일이다. 하지만 지나치게 오랜 시간이 소요되면 어찌됐던 문제가 발생할 수 있다. 게다가 가장 중요한 문제는 위에서 사용자가 업로드한다는 데이터는 파일(엑셀 혹은 csv)인데, 엑셀의 경우 poi 라이브러리를 이용해 구현했다. 하지만 너무 큰 엑셀 파일이 업로드되.. 2024. 5. 17.
Checked Exception과 Unchecked Exception 진짜진짜진짜진짜 간단한건데.. 까먹고 살았다가 오늘 이를 다시금 알게 된 계기가 있어 까먹지 않고자 다시 한 번 공부를 하고, 이를 블로그에 기재해볼까 한다. 프로그래밍을 하다보면 예외처리는 선택이 아닌 필수이다. 그래야만 사용자의 요청에 대한 예외가 발생했을 경우 어떠한 상황으로 인해 예외가 발생했는 지 사용자에게 return할 수 있다.그런 거 없이 500 Internal Exception만 Return하는 코드를 본 적이 있는데, 내가 사용자였다면 두 번 다시 사용하지 않을 것 같다. 그리고 예외인 Exception은 크게 두 가지로 구분된다.Checked ExceptionUnchecked Exception두 Exception의 차이점은 간단하다. 바로 try, catch로 감싸는 예외처리문이 강제.. 2024. 5. 8.
Spring Validation 프로젝트가 끝나고 종료 보고까지 잠시 할 게 없어서 인터넷을 뒤적거리며 이런 저런 개발 자료를 보던 중 처음 보는 것을 발견했다. 지금까지 Controller에서 사용자 입력을 받으면 코드 내에서 해당 입력에 대한 검증을 수행했었다. 이것이 당연하다고 생각하고 있었기 때문이다. 하지만 간단한 검증 작업은 굳이 수기로 하지 않아도 됐었다. 그냥 Spring Validation을 사용하면 알아서 사전에 설정한 검증을 수행해주는 것이었다..!!!처음 알았다..!!! 사실 입력값 검증이라는 것이 간단한 것만 하는 것이 아니기에, 이러한 라이브러리를 알게 되었어도 이를 자주 사용할지는 의문이다. 하지만 이는 단지 내 사고가 편협한 것일 수도 있고, 또한 어떤 지식이던 알아두면 좋다는 신념 하에 한 번 공부를 해볼.. 2024. 5. 7.
[JAVA/BFS] 숫자 변환하기 https://school.programmers.co.kr/learn/courses/30/lessons/154538?language=java# 프로그래머스코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.programmers.co.kr   해결 포인트최단 거리를 찾는 문제이므로 DFS 보다는 BFS가 적합하다.제시된 대로 x에 연산을 할 경우 시간 초과가 나므로, y에 역으로 연산을 하는 것이 해결책이다. import java.util.LinkedList;import java.util.Queue;class Solution { // BFS에 탑재하기 위한 임시 클래스 class TmpNu.. 2024. 5. 7.