API 서버는 예외 발생 시 각 예외 상황에 맞는 오류 응답 스펙을 정하고, 스펙에 맞는 데이터를 응답해야 한다. API 서버는 HTTP 요청 시 JSON 데이터를 응답한다고 가정한다. 서블릿 예외 처리 방식 서블릿 예외 처리 방식으로 예외 발생 시 API 응답 방식을 알아보자. 먼저 ErrorPage로 처리할 예외와 경로를 지정한다. package hello.exception; import org.springframework.boot.web.server.ConfigurableWebServerFactory; import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.WebServerFacto..
웹 애플리케이션 동작 중 예외가 발생하면 예외를 처리하고 필요하다면 사용자가 알 수 있도록 오류 페이지를 응답하는 것이 좋은 웹 애플리케이션이다. 이를 위해 스프링 MVC의 예외 처리와 오류 페이지 응답 구조를 알아보자. 여기서 오류 페이지란 클라이언트에게 오류를 알리는 뷰(ex - html 문서)이다. 만약 뷰가 아닌 API로 정의된 데이터(ex - json)만을 응답해야하는 API 서버에서는 각 오류(예외) 상황에 맞는 오류 응답 스펙을 정하고 스펙에 맞는 데이터를 응답하면 된다. 예외 처리와 오류 페이지 응답 스프링 MVC는 톰캣과 같은 서블릿 컨테이너를 기반으로 동작하고 서블릿 컨테이너는 자바를 기반으로 동작한다. 따라서 스프링 MVC의 예외 처리 구조를 파악하려면 자바 예외 처리 - 서블릿 컨테..
ArgumentResolver ArgumentResolver(정확히 HandlerMethodArgumentResolver)는 핸들러 메서드에서 사용되는 다양한 인자를 생성해 제공해주는 역할을 맡는다. 스프링이 기본으로 제공해주는 ArgumentResolver도 있지만 프로그래머가 직접 커스텀 ArgumentResolver를 만들어 핸들러 메서드에서 자신이 원하는 인자를 받을 수 있다. 아래는 세션 키를 받아 키에 해당하는 세션 데이터가 있으면(로그인 된 사용자이면) loginHome 뷰를, 세션 데이터가 없으면(로그인 되지 않은 사용자이면) Home 뷰를 응답하는 간단한 핸들러 메서드이다. 핸들러 메서드의 인자가 살짝 길어 가독성이 떨어진다. 커스텀 ArgumentResolver를 만들어 이를 해결해보자..
로그인 기능을 구현하다고 해보자. 모든 컨트롤러에서는 비로그인 사용자의 접근을 차단하기 위해 로그인 로직이 필요하다. 하지만 로그인 로직을 모든 컨트롤러에 넣을 경우 로그인 로직이 바뀌면 모든 컨트롤러도 수정해야되는 문제가 발생한다. 여러 로직에서 공통으로 관심이 있는 로직을 공통 관심사(cross-cutting concern)이라 하며 공통 관심사(여기서는 로그인 로직)를 분리해 구현하면 위의 문제를 해결할 수 있다. 스프링은 공통 관심사를 분리하기 위해 AOP 기능을 제공하지만 웹과 관련된 공통 관심사는 서블릿 필터나 스프링 인터셉터를 사용하는 것이 좋다. 웹과 관련된 공통 관심사는 HTTP 요청 정보가 필요한데 서블릿 필터와 스프링 인터셉터는 바로 HttpServletRequest에 접근할 수 있기..
스프링 빈 검증 검증 로직을 만드는 일은 반복적이고 귀찮은 일이다. 특히 특정 필드에 대한 검증 로직은 널 값인지, 특정 범위를 넘어서는지 등 거의 정해져 있다. Bean Validation을 사용한다면 애노테이션으로 검증 로직을 대체할 수 있다. Bean Validation이란 자바 빈 객체를 검증하는 표준 기술이며 검증 애노테이션과 여러 인터페이스를 정의하고 있다. Bean Validation을 구현한 구현체중 일반적으로 하이버네이트 Validator을 많이 사용한다. 공식 사이트 : The Bean Validation reference implementation. - Hibernate Validator The Bean Validation reference implementation. - Hibern..
검증(Vaildation) 프로그램의 입력 값은 예측할 수 없다. 만약 잘못된 값이 들어온다면 프로그램에 문제가 생긴다. 따라서 사용자 입력 등의 프로그램 입력을 받는다면 항상 입력 값을 검증하고 잘못된 값이 들어올 시 처리 로직을 만들어야 한다. 여기서 입력 값이 올바른지 확인하는 과정을 검증이라한다. 검증에는 클라이언트 검증과 서버 검증이 있다. 클라이언트 검증은 클라이언트 측에서 검증하는 것이며 서버 검증은 서버 측에서 검증한다. 클라이언트 검증은 입력을 받으면서 검증할 수 있어 사용자 편의가 증가하지만 사용자 값을 조작해 서버로 보낼 수 있다. 따라서 최종적으로 서버 검증이 필요하다. 하지만 서버 검증만 제공한다면 사용자 편의가 떨어진다. 둘을 적절히 섞어서 사용하되, 최종적으로 서버 검증은 꼭 ..
Lombok Lombok이란 애노테이션 기반으로 코드를 자동완성 해주는 라이브러리이다. Lombok을 사용하면 Getter, Setter, 생성자 등 다양한 코드를 자동완성 할 수 있다. Lombok 기능 @Getter, @Setter Getter와 Setter 메서드를 자동완성한다. @Getter와 @Setter를 클래스 이름 위에 적용하면 모든 필드에 적용되며 필드 위에 적용하면 해당 필드에만 적용된다. @Getter @Setter public class User { private String email; private String name; /*자동 생성 코드 String getEmail() { return email; } void setEmail(String email) { this.email =..
JWT (JSON Web Token) JWT는 JSON 객체를 안전하게 전송하기 위한 인터넷 표준 방법(RFC 7519)이다. JWT는 전자 서명 되었기 때문에 데이터가 검증되고 신뢰할 수 있다. JWT는 HAMC 알고리즘 또는 RSA · ECDSA를 사용한 공유/개인 키로 서명한다. JWT 활용 예 인증(Authentication) 및 권한 부여(Authorization) : JWT를 사용하는 가장 일반적인 시나리오이다. 사용자가 로그인을 하면 서버 측에서 JWT를 발급한다. 이후 사용자는 다음부터 JWT를 포함해 요청하고 서버 측에서 JWT 검증에 성공하면 서버는 요청한 사용자가 인증 및 권한이 부여된 사용자임을 알 수 있다. 쉽게 말해 JWT는 서버에 인증 및 권한 부여를 받을 수 있는 출입증과 같..