본문 바로가기

Java

(78)
Controller 1개가 어떻게 수 많은 Request를 처리하는가? (spring mvc, tomcat thread, singleton bean) Controller 1개가 어떻게 수 많은 Request를 처리하는가 배경 의식의 흐름 Controller는 한 개인가? 지금와서 생각하면 조금 바보같았지만, 저런 질문이 떠오른 이유는 아래와 같습니다. 스프링에서 웹 애플리케이션을 개발할 때, (대부분의 경우에) 스프링 빈(Bean)으로 객체를 생성합니다. Bean의 스코프를 prototype으로 변경하면 HTTP Request 마다 해당 빈을 새롭게 생성해서 처리하도록 할 수 있지만, 그렇게 하는 경우를 거의 본 적이 없습니다. 그러면 내가 만든 Controller(Bean) 하나가 1만 개의 요청이든 10만 개의 요청이든 처리를 한다는 얘긴데, 이게 감당가능한가? 이런 생각이 갑자기 스쳐지나가면서 의문이 생겼습니다. 조금 찾아보니 결론은 Contro..
스프링 부트에서 Request 유효성 검사하는 방법, 서버 개발한다면 꼭 해야하는 작업 Spring Validation 스프링부트에서 Request로 오는 객체(DTO)를 어떻게 검증하는가에 대한 이야기 데이터 검증(validation)은 여러 계층에 걸쳐서 발생하는 흔한 작업이다. 어떻게하면 깔끔하게 유효성 검사를 할 수 있을지 생각해보고 얻은 방법을 공유하고자 한다. 스프링에서 가장 기본적인 validation은 Bean validation이다. Bean validation Bean validation은 클래스 "필드"에 특정 annotation을 적용하여 필드가 갖는 제약 조건을 정의하는 구조로 이루어진 검사다. validator가 그 클래스로 생성된 객체의 유효성 여부를 확인한다. 어떠한 비즈니스적 로직에 대한 검증이 아닌, 객체 자체의 필드에 대한 검증을 한다. 예제 코드를 보고 테스트해본다. plugins { ..
Jackson custom serializer, deserializer 적용했던 사례 공유, LocalDateTime JSON 파싱하는 방법 Jackson custom serializer, deserializer example JSON은 프로그래밍에서 굉장히 많이 쓰이는 데이터 포맷이다. 특히 스프링부트를 이용한 프로젝트에서는 'spring-boot-starter-web'을 dependency에 추가하기만 하면 jackson이라는 json 라이브러리가 자동으로 추가될 정도다. 심지어 jackson이 제공해주는 objectMapper 객체는 스프링 빈으로 제공하기까지 한다. 그러나 이렇게 기본 제공해주는 objectMapper 객체의 경우, 그냥 사용하기에는 모든 요구사항을 충족하기 어렵다. 요구 사항을 충족시키시 위해서는 Object to JSON(Serialize/직렬화), JSON to Object(Deserialize/역직렬화)를 입맛에..
REST API 응답은 어떻게 줘야할까? (표준 Response 객체를 만들 수 있을까?, 정확하게 응답 처리를 하는 방법, 성공과 실패 응답) - 왜 이런 생각을 하였는가? 필자가 쓰는 Vue 프레임워크에서 axios라는 HTTP client 라이브러리가 있다. 해당 라이브러리에서 HTTP 요청에 성공했을 때는 왜 "response.data"에 http reponse의 body 값이 들어가고, HTTP 요청에 실패했을 때는 왜 "error.response"에 body내용이 들어가는지가 궁금했다. HTTP 요청에 성공했든 실패했든 모든 응답은 response라고 하고 body 내용이면 "repsonse.body"로 통일하면 되는거 아닌가? 하는 생각이 들었다. //success { "payload" : "~~~~", "error" : null } //fail { "payload" : null, "error" : { "message" : "Not ..
Spring에서 Logback을 이용해서 필터없이 별도의 디렉토리에 로그를 남기는 방법 (Logback MDC 사용법, 동적 로그 남기기) 로그를 분류해야하는 경우 스프링에서 로그를 남길 때 대부분 Logback을 사용한다. 보통 한 파일에 모든 로그를 남기기보다는 기능, 모듈별로 로그를 남기거나 어떠한 기준(로그 레벨등...)에 의해 로그를 여러 파일 혹은 여러 디렉토리에 남긴다. 그렇게 구현하려면 logback 설정 파일(logback-spring.xml 같은 파일)에서 property로 여러 로그 경로를 등록해놓고 logger의 패키지를 나눠서 지정하는 것이 일반적인 방법일 것이다. 그러나 위의 방법은 어느정도 패키지 분류가 되어있는 상태여야하고 분류할 기준의 개수가 제한적이어야 한다. 어느정도는 Logback의 filter를 이용한 방법으로 쉽게 처리할 수도 있겠지만, 여전히 같은 패키지, 같은 클래스의 로그에 대해서는 분류하기 어려..
값 타입(JPA에서 @Entity 내부에 값들을 객체로 다루는 방법, @Embedded, @Embeddable) 위의 그림은 JPA에서 사용하는 타입을 정리한 것이다. JPA를 배울 때 다짜고짜 Entity라는 개념을 배우고 그 객체안에 String 타입의 name, int 타입의 age등의 속성들을 정의하여 사용했다. 그런데 Entity는 객체로 잘 다뤘으면서 내부의 변수(속성)는 객체로 다루지 않고 나열식으로 사용했었다. 그래서 그 것들이 Entity는 아니지만 엔티티 객체 내부에서 값이지만 객체로 사용되게 하는 방법으로 값 타입이 있다. 그것에 대해 알아본다. JPA에서 사용하는 타입은 엔티티 타입(@Entity), 값 타입(int, String, Integer)으로 나뉜다. 값 타입은 다시 3개의 타입으로 나뉜다. 기본 값 타입(int, Integer, String) 임베디드 타입(새로 정의한 복합 타입) ..
JPA 프록시와 연관 관계 정리, 영속성 전이, 언제 사용하는 것이 좋고 어떻게 사용할까? (지연로딩 vs 즉시로딩) "도서 (자바 ORM 표준 JPA 프로그래밍 - 김영한 지음)"를 공부하고 정리한 내용임을 사전에 알려드립니다. 프록시와 연관관계 정리 - 프록시 JPA는 객체지향언어와 관계형 데이터베이스의 패러다임 불일치를 해결하는 기술이다. 프록시가 이 문제에 도움을 주는데 어떤 부분에서 도움을 주는지 정리한다. 객체는 team1.getMembers().get(0); 이런식으로 연관된 객체들을 탐색할 수 있는 반면 RDB의 경우 참조하는 외래키를 이용해서 테이블간의 조인 쿼리를 작성해서 탐색해야한다. 그러다보니 연관된 객체를 쓰일지 안 쓰일지도 모르는 체 전부다 가져와야하는 문제가 있다. 이 문제를 프록시라는 기술로 해결한다. 프록시는 실제 연관된 객체를 즉시 join을 통해 DB로부터 가져오는 것이 아니라 앞서 프..
@ControllerAdvice, @ExceptionHandler를 이용한 예외처리 분리, 통합하기(Spring에서 예외 관리하는 방법, 실무에서는 어떻게?) 예외 처리 과정 프로그래밍에서 예외 처리는 아주 중요하면서도 아주 어렵다. 과하다할 만큼 상세하고 다양하게 예외를 잡아 처리해준다면, 클라이언트도 그렇고 서버도 그렇고 더 안정적인 프로그램이 될 수 있게 도와준다. 예외 처리를 하는 경우와 방법은 다양하다. 메서드 내에서 예외 상황을 예측해서 처리하는 try-catch문을 이용하는 방법 요구사항에 의한 예외 처리 (ex. validation > 특정 값이 0~255범위가 아니면 유효하지 않은 값으로 판단하고 예외 처리) 스프링 시큐리티에서 인터셉터로 잡아서 UnauthorizedException 같은 예외 처리 기타 여러 예외 처리들을 적용하다보면 코드가 엄청나게 복잡해진다. if문으로 잡든 try-catch로 잡든 상위 메서드로 예외처리를 위임하든 코드..