1. 서블릿 예외 처리서블릿은 2가지 방식으로 예외를 처리한다.1.1. Exception웹 애플리케이션은 사용자 요청별로 스레드가 할당되고, 서블릿 컨테이너 안에서 실행된다. 애플리케이션에서 예외가 발생했는데 해당 예외를 잡지 못한 경우는 어떻게 될까? 기본적으로 어떠한 요청이 들어올 경우 다음과 같이 요청이 전파된다.WAS → 필터 → 서블릿 → 인터셉터 → 컨트롤러만약 컨트롤러에서 예외가 발생하면 요청의 전파 방향과 반대로 전파된다.WAS ← 필터 ← 서블릿 ← 인터셉터 ← 컨트롤러예외 발생시 서블릿 컨테이너에서 그에 맞는 오류 페이지를 보여준다.1.2. response.sendError() 메서드오류가 발생하면 HttpServletResponse가 제공하는 sendError 메서드를 사용해도 된다...
분류 전체보기
1. 서블릿 필터이전 포스팅에서 구현한 코드는 로그인을 하지 않아도 특정 url을 입력하면 해당 url로 이동할 수 있다. 이를 위해 모든 비지니스 로직을 수행할 때 사용자의 로그인 여부를 체크할 수 있다. 하지만 이런 방식은 이후 로그인 관련 로직을 바꿀 때 해당 체크 로직을 다 수정해야할 수도 있다.이와 같이 여러 로직에서 공통으로 관심있는 것을 공통 관심사(cross-cutting concern)이라고 한다.이러한 공통 관심사는 AOP로도 해결할 수 있다. 하지만 웹과 관련된 공통 관심사는 서블릿 필터 혹은 스프링 인터셉터를 사용하는 것이 좋다. 필터는 서블릿이 지원하는 수문장 역할을 하는 것으로 필터의 흐름은 다음과 같다.HTTP 요청 → WAS → 필터 → 서블릿 → 컨트롤러만약 필터를 통해 적..
1. 쿠키 사용로그인 상태를 유지하기 위해서는 쿠키를 사용할 수 있다. 서버에서 로그인에 성공하면 HTTP 응답에 쿠키를 담아서 전달하고, 브라우저는 앞으로 해당 쿠키를 지속적으로 보내면 된다. 쿠키의 종류는 다음과 같다.영속 쿠키: 만료 날짜를 입력하면 해당 날짜까지 유지된다.세션 쿠키: 만료 날짜를 생략하면 브라우저 종류시까지만 유지된다.우리는 세션 쿠키를 사용해볼 것이다. 쿠키는 다음과 같이 response에 담을 수 있다.@PostMapping("/login")public String login(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response) { ... ..
1. Bean Validation이전 포스팅의 Validation 코드들을 보면, reject, rejectValue 등의 메소드를 활용해 검증을 수행했다. 하지만 이런 코드들은 너무 번거롭다. 하지만 특정 필드의 검증 로직은 대부분 빈 값인지, 특정 범위 안에 있는지 등 일반적인 것들을 목표로 한다. Bean Validation은 이러한 공통된 일반적인 검증 로직들을 @NotBlank, @Range, @Max 등의 어노테이션으로 제공한다.Bean Validation이란 검증 로직을 모든 프로젝트에 적용할 수 있도록 공통화/표준화한 것이다.사실 Bean Validation은 기술 표준(인터페이스)으로 구현체가 따로 있는데, 주로 사용하는 구현체는 하이버네이트 Validator이다. (JPA라는 표준 기술..
1. 검증 직접 처리사용자가 잘못된 값을 입력했는지, 입력하지 않은 값은 없는지를 체크하기 위해서는 검증을 수행해야한다. 검증을 위해 전달된 값들이 우리가 원하는 의도된 값인지 아래와 같이 각각 직접 확인해줄 수 있다.@PostMapping("/add")public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes, Model model) { // 검증 오류 결과를 보관 Map errors = new HashMap(); if (!StringUtils.hasText(item.getItemName())) { errors.put("itemName", "상품 이름은 필수입니다."); }..
1. 체크 예외와 인터페이스이전 서비스 코드를 보면 아직 서비스 계층이 SQLException이라는 서비스에서 처리할 수 없는 예외에 의존하고 있는 것을 알 수 있다.@Slf4j@RequiredArgsConstructorpublic class MemberServiceV3 { private final MemberRepositoryV3 memberRepository; @Transactional public void accountTransfer(String fromId, String toId, int money) throws SQLException { bizLogic(fromId, toId, money); } private void bizLogic(String fromI..
1. 기존 코드의 문제점1.1. 애플리케이션 구조애플리케이션에서 단순하지만 많이 사용하는 방법은 아래와 같이 3계층으로 나눈 방식이다.프레젠테이션 계층: UI와 관련된 처리를 한다.서비스 계층: 비지니스 로직을 담당한다.데이터 접근 계층: 데이터베이스 접근을 담당한다. JDBC, JPA 등이 해당한다.세 가지 계층 중 가장 중요한 것은 서비스 계층이다. 비지니스 로직이 담겨있기 때문에 최대한 변경 없이 유지되어야 하며 이를 위해 특정 기술에 종속적이지 않게 해야한다. 따라서 UI 관련 기술들은 프레젠테이션 계층에서, 데이터 접근 기술들은 데이터 접근 계층에서 담당하여 서비스 계층은 기술에 종속되지 않도록 한다.1.2. 문제점이전 비지니스 코드의 내용은 다음과 같다.@Slf4j@RequiredArgsCon..
1. 트랜잭션이란?1.1. 트랜잭션의 기본 이해트랜잭션의 사전적 정의는 "거래"다. 이때 데이터베이스에서 트랜잭션이란 하나의 거래를 안전하게 처리하도록 보장함을 의미한다. 근데 하나의 거래를 안전하게 처리하려면 고려할게 많다. 예를 들어, A의 돈을 B에게 이체한다고 하자. 그럼 A의 잔고 값을 감소시키고, B의 잔고 값은 증가시켜야한다. 만약 두 작업 중 하나는 성공하고, 하나는 실패하는 경우는 문제가 된다. 이런 경우 트랜잭션은 작업 1, 2가 모두 성공되어야 데이터를 저장한다. 하나라도 실패하면 거래 전의 상태로 되돌린다. 이때, 모든 작업이 성공하여 데이터베이스에 반영하는 것을 Commit이라고 부르고, 하나라도 실패하여 이전 상태로 되돌리는 것을 Rollback이라고 부른다.1.2. ACID트랜..