Spring/Spring Web MVC
[Spring Web MVC] 로그인 처리 - Filter / Interceptor
[Spring Web MVC] 로그인 처리 - Filter / Interceptor
2023.07.11로그인 한 사용자에 한해서만 웹 페이지가 제공하는 서비스를 사용할 수 있어야 한다. 로그인 하지 않은 사용자가 특정 URL으로 접속을 시도할 경우 로그인을 하지 않아도 서비스를 사용할 수 있으면 안 된다. 컨트롤러에서 로그인 여부를 체크하는 로직을 하나하나 추가해서 작성하는 방법도 있지만, 이렇게 설계하면 나중에 로그인 관련 로직이 변경될 때 작성된 로직을 모두 수정해야 하는 불편함이 생긴다. 여기서의 로그인처럼 여러 로직에서 공통으로 관심이 있는 작업을 공통 관심사라고 한다. 웹과 관련된 공통 관심사는 서블릿 필터 또는 스프링 인터셉터를 사용해 한 번에 처리할 수 있다. Servlet Filter 필터는 수문장 역할을 한다. HTTP 요청 -> 서버 -> 필터 -> 디스패처 서블릿 -> 컨트롤러 서버는..
[Spring Web MVC] 로그인 처리 - Cookie / Session
[Spring Web MVC] 로그인 처리 - Cookie / Session
2023.07.10패키지 구조를 먼저 설계하자. 도메인과 웹을 분리했는데, 도메인은 시스템이 구현하는 핵심 비즈니스 업무 영역을 말한다. 나중에 웹을 다른 기술로 변경한다고 해도 도메인은 그대로 유지할 수 있어야 한다. (도메인은 웹에 의존하지 않고, 웹은 도메인에 의존한다.) 도메인 : 비즈니스 로직 (서비스, 리포지토리, 모델, 엔티티) 웹 : HTTP 요청 처리하고 응답 (컨트롤러, 필터, 리스너) public Member login(String loginId, String password){ // Optional findMemberOptional = memberRepository.findByLoginId(loginId); // Member member = findMemberOptional.get(); // if(m..
[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=..
[Spring Web MVC] Thymeleaf (2)
[Spring Web MVC] Thymeleaf (2)
2022.08.20타임리프는 스프링 없이도 잘 동작하지만, 스프링과의 통합을 위한 편리한 기능들을 많이 제공한다. 기능을 하나하나 살펴보자. 입력 폼 처리 상품명 타임리프를 사용하기 전 모델을 통해 item 객체를 넘겨준다. *{...} 은 선택 변수 식으로 th:object 에서 선택한 객체에 접근한다. ( ${item.itemName} 으로 작성해도 된다. ) th:field 는 폼에서 id / name / value 속성을 자동으로 만들어준다. (th:field 에서 지정한 이름으로 설정된다.) HTML 폼에 체크박스가 있는 경우 전송해서 POST 방식으로 서버에게 요청하면 서버에서 요청 값을 확인 시 체크박스가 선택된 경우 해당 값이 true 로, 체크박스가 선택되지 않은 경우 해당 값이 null로 초기화 돼 있다..
[Spring Web MVC] Thymeleaf (1)
[Spring Web MVC] Thymeleaf (1)
2022.08.19타임리프 뷰 템플릿 엔진은 백엔드 서버에서 HTML을 동적으로 렌더링 할 때 사용된다. 스프링과 통합이 가장 잘 되는 뷰 템플릿이고, 제공하는 기능도 가장 많아서 뷰 템플릿 중에서는 타임리프를 많이 사용한다. 텍스트 th:text 사용 sdqwfe 컨텐츠 안에서 직접 출력하기 = [[${data}]] ${data} 를 통해 sdqwfe를 모델로 전달받은 data로 바꿔서 렌더링한다. HTML 컨텐츠 영역 안에서 직접 데이터를 출력하려면 [[]] 를 사용한다. th:utext = [(...)] = [(${data})] 이스케이프 기능을 사용하지 않고 렌더링하려면 utext 혹은 [()] 를 사용한다. 변수 기본적으로 변수 표현식 ${...} 을 사용해서 변수를 사용한다. SpringEL 표현식 Object..
[Spring Web MVC] Spring MVC와 Thymeleaf 예시
[Spring Web MVC] Spring MVC와 Thymeleaf 예시
2022.08.18스프링 MVC를 사용해 아주 간단한 쇼핑몰 프로젝트를 진행해보자. 여기서 검은색은 컨트롤러고, 컨트롤러를 통해 뷰를 호출한다. 이렇게 요구사항이 정리되면 디자이너 / 웹 퍼블리셔 / 백엔드 / 프론트엔드 개발자가 업무를 분담해서 프로젝트를 진행한다. 디자이너 : 디자인하고 결과물을 웹 퍼블리셔 혹은 프론트엔드 개발자에게 넘겨준다. 웹 퍼블리셔 : 디자인을 바탕으로 HTML CSS를 만들어 개발자에게 넘겨준다. 백엔드 : HTML CSS 가 나오기 전까지는 시스템을 설계하고 비즈니스 모델을 개발한다. 이후 화면이 나오면 뷰 템플릿으로 변환해 동적으로 화면을 구성하고 흐름을 제어한다. 프론트엔드 : 디자인을 바탕으로 HTML CSS를 만드는 역할도 하고, HTTP API를 통해 웹 클라이언트가 요구하는 데이..