Spring
[Spring Database] 데이터베이스 예외 처리
[Spring Database] 데이터베이스 예외 처리
2022.09.05서비스가 처리할 수 없는 SQLException 예외를 런타임 예외로 전환하는 방식으로 의존 관계를 제거하자. MemberRepository 클래스도 인터페이스로 변경해 구현 기술을 쉽게 변경할 수 있도록 하자. 이제 MemberService의 코드 변경 없이 DI를 사용해 구현 기술을 변경할 수 있다. 인터페이스의 구현체가 체크 예외를 던지려면 인터페이스의 메서드에 먼저 체크 예외를 던지는 부분이 선언돼있어야 한다. 즉, SQLException과 같이 체크 예외를 사용하는 경우 인터페이스에도 해당 체크 예외가 선언돼있어야 한다. (throws Exception) 그런데, 인터페이스에 throw ~~Exception 문장을 추가하는 순간 해당 인터페이스는 특정 기술에 의존하게 되고, 이건 우리가 의도한 ..
[Spring Database] Transaction AOP
[Spring Database] Transaction AOP
2022.09.01트랜잭션을 적용해 여러 작업들을 하나의 작업으로 묶어서 처리하는건 성공했지만, 비즈니스 로직을 처리하는 코드보다 트랜잭션을 처리하는 코드가 훨씬 더 많아져 코드가 지저분해졌다. 좀 더 간단하게 처리하는 방법을 알아보자. 애플리케이션의 구조는 역할에 따라 세 가지 계층으로 나눌 수 있다. 프레젠테이션 계층 : UI와 관련된 처리를 담당하고, 클라이언트의 요청을 검증하고 응답하는 역할을 한다. (스프링 MVC, HTTP..) 서비스 계층 : 계좌이체와 같은 비즈니스 로직을 담당한다. (특정 기술에 의존하지 않고 자바 코드로 작성) 데이터 접근 계층 : 실제 데이터베이스에 접근하는 코드를 담당한다. (JDBC, JPA...) 모두 중요한 계층이지만, 그 중에서도 핵심 비즈니스 로직이 구현된 서비스 계층은 특히..
[Spring Database] Transaction / Lock
[Spring Database] Transaction / Lock
2022.09.01데이터를 저장할 때 메모장같은 파일이나 다른 저장소 대신 데이터베이스를 사용하는 가장 큰 이유는 데이터베이스가 트랜잭션을 제공하기 때문이다. 데이터베이스에서의 트랜잭션은 한 가지 거래를 안전하게 처리되도록 보장해주는 작업을 의미한다. 인터넷 뱅킹을 생각해보자. A가 B에게 1000원을 이체하면 A의 잔고는 1000만큼 감소시키고, B의 잔고는 1000만큼 증가시켜야 한다. 만약 감소하는 작업은 성공했지만 증가하는 작업은 실패하는 치명적인 오류가 발생한다면? 아무도 그 은행을 사용하지 않을 것이다. 즉, 증가시키는 작업과 감소시키는 작업이 하나의 작업처럼 묶여서 동작해야 한다. 데이터베이스가 제공하는 트랜잭션 기능을 사용하면 두 가지 작업 모두 성공해야 데이터베이스에 값을 저장 (Commit) 하고, 중간..
[Spring Database] Connection Pool과 Data Source
[Spring Database] Connection Pool과 Data Source
2022.08.31데이터베이스 커넥션을 획득할 때는 다음과 같은 과정을 거친다. 1. 애플리케이션 로직에서 데이터베이스 드라이버를 통해 획득 가능한 커넥션 조회 2. 데이터베이스 드라이버에서는 TCP/IP 커넥션을 연결한다. (3 way handshake 같은 네트워크 동작 사용) 3. 커넥션이 연결되면 데이터베이스에 ID, PW 및 부가정보를 전달한다. 4. 데이터베이스에서는 전달받은 정보를 바탕으로 내부 인증을 완료하고 데이터베이스 세션을 생성한다. 5. 데이터베이스에서 커넥션 생성이 완료됐다는 응답을 보내고, 데이터베이스 드라이버가 클라이언트에게 커넥션 객체를 반환한다. 이렇게 커넥션을 새로 만드는 작업은 과정도 복잡하고 시간도 많이 소모된다 -_-. 매번 TCP/IP 커넥션을 새로 생성하기 위해 리소스를 사용하고,..
[Spring Database] JDBC
[Spring Database] JDBC
2022.08.30Java DataBase Connectivity 의 약자로, 자바에서 데이터베이스에 접속할 수 있도록 도와주는 자바의 API이다. 클라이언트가 서버에게 데이터를 저장하거나 조회하려는 요청을 보내면 서버는 데이터베이스에 접근해 해당 요청을 실행한다. 잠시 과거의 데이터베이스 사용 방식에 대해 알아보자. 먼저 커넥션을 연결한다. (TCP / IP) 보통 JDBC드라이버와 데이터베이스간의 연결 시에는 TCP/IP 프로토콜을 사용한다. 그 후 서버는 데이터베이스가 이해할 수 있는 SQL을 연결된 커넥션을 통해 데이터베이스에 전달한다. 데이터베이스는 전달된 SQL을 실행하고, 결과를 서버에게 준다. 이후 서버는 응답 결과를 활용해 클라이언트의 요청을 수행한다. 각각의 데이터베이스마다 연결하는 방법과 SQL을 전달..
[Spring Web MVC] Multipart
[Spring Web MVC] Multipart
2022.08.29HTML Form을 통해 파일 업로드를 이해해보자. HTML Form 전송 방식에는 크게 두 가지가 있다. 1. application/x-www-form-urlencoded 2. multipart/form-data 1번은 가장 기본적인 방식이다. 별도의 enctype 옵션이 없으면 요청 HTTP 헤더에 Content-Type: application/x-www-form-urlencoded 을 추가하고, 폼에 입력한 내용을 HTTP 바디 메세지에 & 로 구분해서 전송한다. 파일을 업로드 할 경우 문자가 아니라 바이너리 데이터를 전송해야 하는데... 1번 방식으로는 문자와 바이너리 데이터를 한 번에 전송하기 힘들다. 이런 문제를 해결하기 위해 multipart 가 도입됐다. Form 태그에 enctype="m..
[Spring Web MVC] 스프링 타입 컨버터
[Spring Web MVC] 스프링 타입 컨버터
2022.08.28HTTP 요청 파라미터는 모두 String 으로 처리된다. 따라서 요청 파라미터를 정수나 실수와 같은 다른 타입으로 사용하고 싶은 경우 타입 변환 과정을 거쳐야 한다. @GetMapping("/hello-v2") public String helloV2(@RequestParam Integer data) { System.out.println("data = " + data); return "ok"; } @ModelAttribute UserData data class UserData { Integer data; } /users/{userId} @PathVariable("userId") Integer data @RequestParam @ModelAttribute @PathVariable 애너테이션을 사용할 때는 ..
[Spring Web MVC] API 예외 처리
[Spring Web MVC] API 예외 처리
2022.08.26웹 페이지의 경우, 4xx / 5xx 번호마다 오류 페이지만 작성해주면 에러 페이지 관련 대부분의 문제를 쉽게 해결할 수 있다. 웹 뿐만 아니라 모바일, 서버 간의 통신 등에서 예외를 처리할 때는 HTML로 처리할 수 없고 API를 사용해서 통신해야 한다. 즉, 클라이언트에게 보여주는 HTML 화면이 아니라 API를 통해 정확한 데이터를 뿌려 줘야 한다. API 통신에는 국제적으로 정해진 약속이 없기 때문에 서버와 API를 요청하는 클라이언트가 서로 오류 응답 스펙을 정의해야한다. @RequestMapping("/error-page/500") public String errorPage500(HttpServletRequest request, HttpServletResponse response){ log.i..
[Spring Web MVC] 예외 처리와 오류 페이지
[Spring Web MVC] 예외 처리와 오류 페이지
2022.08.26자바에서 메서드를 실행시킬 때 예외가 발생하면 해당 메서드를 호출한 메서드로 예외를 던지는걸 반복하다가, 메인 메서드에 도달했는데도 예외를 처리하지 못하면 예외 정보를 남기고 해당 쓰레드를 종료시킨다. 스프링 MVC를 사용하는 웹 애플리케이션에서는 쓰레드가 하나만 돌아가지 않는다. 사용자의 요청별로 별도의 쓰레드가 할당되고, 이 쓰레드들은 서블릿 컨테이너 내부에서 실행된다. 예외가 발생했는데 제대로 처리하지 못해 서블릿 컨테이너 외부까지 예외가 전달되면 어떻게 될까? WAS ←필터 ←디스패처 서블릿 ←인터셉터 ← 컨트롤러 (예외 생김) 차례대로 예외가 전달된다. 그럼 WAS까지 예외가 전달되면? 예외는 서버 내부에서 처리할 수 없는 오류가 발생한 것으로 간주하고 HTTP 상태코드 500번을 반환한다. 그..
[Spring Web MVC] Bean Validation
[Spring Web MVC] Bean Validation
2022.08.23보통 작성하게 되는 검증 로직은 빈 값인지 확인하거나 값이 특정 크기를 넘는지 확인하는 등 복잡하지 않다. 지금까지는 간단한 로직을 작성하기 위해 코드를 좀 많이 써야 됐는데, Bean Validation을 잘 활용하면 애너테이션을 기반으로 검증을 정말 간단하게 처리할 수 있게 된다. 스프링이 제공하는 Bean Validation은 애너테이션과 인터페이스의 모음으로, 구현체는 적당히 골라 사용하면 된다. 그럼 Bean Validation을 어떻게 사용하는지, 그리고 어떻게 작동하는지 살펴보자. import org.hibernate.validator.constraints.Range; import javax.validation.constraints.Max; import javax.validation.cons..
[Spring Web MVC] 데이터 검증
[Spring Web MVC] 데이터 검증
2022.08.22숫자나 문자로 작성해야 하는 폼에 잘못된 값을 넣고 서버로 데이터를 전송하면 오류 화면으로 이동된다. 이러면 사용자는 폼을 처음부터 작성해야 하는데, 이런 서비스는 사용자 친화적이지 않다. 이처럼 컨트롤러의 중요한 역할 중 하나는 HTTP 요청이 정상인지 검증하는 것이다. 클라이언트 부분에서 자바스크립트를 통해 검증하는 방법도 있지만, 보안에 매우 취약하고 서버 단에서만 검증하면 즉각적인 고객 사용성이 떨어진다. 클라이언트와 서버에서 모두 검증하는 편이 합리적이다. 상품 등록 시 검증 로직에 부합하지 않는 정보가 입력되면 고객에게 오류 페이지를 보여주는 대신, 다시 상품 등록 폼을 보여주고 어떤 값을 수정해야 하는지 알려줘야 한다. (검증 작업은 컨트롤러에서 수행된다.) @PostMapping("/add..
[Spring Web MVC] 메세지와 국제화
[Spring Web MVC] 메세지와 국제화
2022.08.20국제화는 특정 설정별로 메세지를 다른 국가의 언어로 제공하는 작업을 말한다. HTML 파일에 하드코딩된 텍스트들을 하나의 파일에 모아서 관리하는 작업을 메세지를 관리 라고 부른다. item=상품 item.id=상품 ID item.itemName=상품명 item.price=가격 item.quantity=수량 messages.properties 처럼 메세지 관리용 파일을 만들어서 HTML에 텍스트를 넣을 때 프로퍼티의 키 값으로 사용한다. 메세지 관리 아이디어에서 조금 더 생각하면 국제화 관리에 대한 아이디어를 얻을 수 있다. 여기서 국제화는 클라이언트가 요청을 보낸 언어 정보에 따라 특정 언어로 HTML을 렌더링 하는 작업을 말한다. item=Item item.id=Item ID item.itemName=..