이번에 발생한 이슈에 대해 정리해본다. POI라이브러리는 오피스 파일들을 자바에서 사용하기 위해 사용하는 라이브러리로, 이 경우 엑셀을 다루기 위해 사용되었다. MS Excel은 기본적으로 저장할 때 .xlsx나 .xls의 확장자를 이용하는데, .xls은 2003 이전버전을, 이후는 .xlsx를 사용한다. 문제가 된 부분은 업로드한 엑셀파일을 서버 임시경로에 저장하는 부분에서 발생했다. 업로드하기 위해 작성이 필요한 양식을 다운로드받는 기능이 있는데, 이때도 .xslx로 다운로드되기 때문에 .xls까지는 테스트가 되지 않았던 모양이었다.(레거시코드인데, 개발 당시에 원래 테스트가 이루어졌어야 맞다고 본다...) 원래대로라면 업로드한 파일 그대로 임시경로에 저장되어서 읽어서 사용하는데, 이때 파일을 .xs..
내 실수로 발생한 건 아니지만 개발하다보면 이런 경우가 생길 수도 있을 것 같아서 정리해둔다. 얼마전 한 이슈 관련해서 유의사항을 전달받았는데, 보안상 보여지지 않거나, 보여지더라도 암호화를 통해 보여져야 할 데이터가 보란듯이 암호화도 거치지 않은 채로 로그에 info 레벨로 남겨지고 있었다는 것이다. 그래서 메일 주요 내용은 보안을 항상 고려하고 로그 레벨을 고려해서 로그를 남기라는 것이었다. 기계적으로 남기지 말고 로그에 어떤 데이터를 어떻게 보여줄지도 생각해야함을 깨달았다. 이미 알고 있는 내용이지만 간단히 정리해보자면 로그 레벨은 일반적으로 아래와 같다. FATAL : 심각 ERROR : 예외 발생 WARN : 실행에는 문제 없지만 경고 INFO : 정보성 DEBUG : 개발시 디버그 용도 TRA..
최근에 성능 개선을 하면서 dead code를 발견했는데 처음엔 왜 dead code인지 모르겠다가 원인을 찾았다. 아래는 내가 발견했던 코드를 최대한 단순화해서 표현한 예시이다. MultipartFile excelFile = request.getFile("excelFile"); List excelContent = null; ... try { // 파일 업로드 작업 } catch (IOException e) { LOGGER.error("excel file error {}", e.getMessage()); if (excelFile != null) { excelFile = null; } if (excelContent != null) { excelContent.clear(); // 이 부분이 dead code..
최근에 담당한 건에 대해 정리해보려고 한다. 기존 프로젝트에는 엑셀업로드를 통해 대량등록하는 기능이 있었는데, 엑셀 한 줄 한 줄씩 처리하다보니 성능이 느렸다. 기존에 요구된 처리량은 많아야 몇백건정도라 그동안 문제가 되지 않았지만 이번에 몇만건을 처리해야 하는 경우가 생기면서 성능을 개선하게 되었다. 요구사항 - 구분코드와 문장으로 유일한 데이터인지 판단한다. 같은 구분코드와 문장의 데이터는 존재할 수 없다. - 데이터를 구성하는 요소는 구분코드, 문장, 대체문장인데, 문장과 대체문장은 같을 수 없다. - 엑셀내에 중복된 데이터가 존재한다면 가장 최신(가장 아래)의 데이터로 등록되어야 한다. - DB에도 존재하는 중복된 데이터는 새로 등록하는 데이터로 업데이트한다. - 구분코드 2, 3의 경우, 문장에..
첫 회고를 남기기 전에... 학원에서 팀 프로젝트를 진행하면서 느낀 건 지난 프로젝트의 경험이 굉장히 소중하다는 것이었다. 어떤 점을 잘했고, 어떤 점이 부족했는지, 어떤 점을 앞으로도 주의해야할지 되새겨보는 것이 꽤 도움이 되었다. 그래서 직업으로서의 개발을 해가면서도 좀 더 나은 개발을 하기 위해 회고를 작성하고자 한다. 사실 좀 더 자세한 내용이 담긴 회고는 따로 있어서 이 공간에는 프로젝트 내용을 최대한 드러내지 않는 한에서 작성할 것이다. 잘한 점 다른 팀원이 개발한 부분을 꼼꼼하게 테스트를 진행했다. ➡️ 다른 팀원의 개발부분도 이해하게 되어 전체적인 프로젝트 이해도가 상승 부족했던 점 API 연동하여 Json으로 받은 응답을 객체로 직렬화할 때 어려움이 있었다. ➡️ 🔗API 응답 Json ..
본 내용은 도서를 참고하여 작성되었습니다. Runtime Data Area에서 Heap Area(이하 'Heap')를 살펴보자. 자바 프로그램에서 생성된 객체는 이 'Heap'에 생기게 된다. 그런데 이 'Heap'는 한정되어 있고 이를 효율적으로 관리하기 위해 GC가 필요하다. 쉽게 말하면 더 이상 사용하지 않는 객체가 메모리를 차지하지 못하게 버려준다. 이 Heap은 대부분의 객체가 탄생하는 Eden, Survivor1과 Survivor2, Old, Permanent로 구성되어 있다. 이름으로 알 수 있다시피 Eden에서 살아남은 객체는 S1, S2로 이동하게 되고 이후로 Old로 이동하게 된다. 대부분의 객체가 탄생하는 Eden은 각 스레드별로 객체를 할당하는 구역이 나누어져 있다.(계산하려고 줄서..
이번 프로젝트에서 목록의 체크박스를 선택해서 삭제하는 기능을 구현하게 되었다. 기존 코드에 있던 대로 선택된 체크박스들을 ","로 연결해서 문자열로 가져오고 서버단에서 "," split해주었는데, 오늘 코드리뷰 중에 좀 더 간단하게 구현할 수 있는 방법이 있지 않겠냐는 대리님의 말씀이 있어서 한 번 찾아보았고, 훨씬 간결하게 구현할 수 있는 방법이 생겨서 포스팅해둔다. Front에서의 처리 사실 가 있어야겠지만 우선은 생략. 그리고 [선택삭제] 버튼을 누르면 ajax가 작동하도록 했는데, 이때 보내는 데이터를 아래처럼 만들었다. data : jQuery("input[name='checkRow']:checked").serialize(), Back에서의 처리 저렇게 ajax에서 데이터를 보내게 되면 chec..
회사 업무를 진행하다가 최근에 다루기 어려웠던 문제가 있어서 적어둔다. API에 요청을 하고 그 응답을 받아서 응답에 따라 로직을 타는 부분이었는데, 응답이 제대로 안 받아지는 문제가 있었다. Response 우선 내가 받아야 하는 응답의 json구조는 아래와 같았다. { "resultCode":"0000", "resultMessage":"Success", "totalCount":1 "items":[ { "index":0, "name":"홍길동", "gender":"M" } ] } items는 없을 수도 있고, 여러 개로 구성될 수도 있었다. 그럼 받는 방향에서 어떻게 객체를 구성해야 하는지 고민을 했다. 우선 내가 짠 구조는 아래와 같았다. class ApiResponse { private String..