본문 바로가기

Spring MVC

(33)
[Spring MVC] 파일 업로드, 다운로드 – MultipartFile 웹 애플리케이션에서 파일 업로드를 구현하는 것은 매우 일반적인 요구사항이다.파일 업로드를 이해하려면 먼저 HTML 폼(Form)이 데이터를 서버로 전송하는 두 가지 주요 방식의 차이를 알아야 한다. 🧩 HTML 태그의 enctype 속성 태그의 enctype 속성은 폼 데이터를 서버로 전송할 때 어떤 방식(인코딩 타입)으로 전송할지를 지정하는 속성이다.즉, 해당 속성의 값에 따라 다른 방식으로 폼 데이터를 전송할 수 있다. enctype 속성은 다음과 같은 속성값을 가질 수 있다.application/x-www-form-urlencoded (기본값)모든 문자(키와 값)를 URL 인코딩하여 전송 (공백은 +로, 특수문자는 %로 시작하는 16진수 형태로 인코딩)multipart/form-data폼 데이..
[Spring MVC] 스프링의 타입 변환기 – Converter, Formatter 애플리케이션 개발 시 타입 변환은 매우 흔하게 발생하는 작업이다. 특히 웹 애플리케이션에서는 HTTP 요청 파라미터가 항상 문자열(String)로 전달되기 때문에,이를 숫자(Integer, Long)나 특정 객체 타입으로 변환하는 과정이 필수적이다. 스프링은 이러한 타입 변환을 위해 Converter와 Formatter를 제공한다. 🧩 Converter – 범용적인 타입 변환기 Converter 인터페이스는 소스 타입(S) 객체를 타겟 타입(T) 객체로 변환하는 convert() 메서드를 가지고 있다.개발자는 이 인터페이스를 구현하여 원하는 모든 종류의 타입 변환 로직을 만들 수 있다.public interface Converter { @Nullable T convert(S source); ..
[Spring MVC] API 예외 처리 – @ExceptionHandler ❌ HTML 오류 페이지의 한계 서블릿 오류 페이지 매핑이나 스프링 부트의 BasicErrorController를 사용하는 방식은 HTML 오류 화면을 제공하는 데는 훌륭하다.하지만 API는 기계(클라이언트)와 통신하는 것을 전제로 하므로, 예외가 발생했을 때 단순히 오류 화면을 반환하는 것은 적절하지 않다. 대신, API 클라이언트가 이해하고 처리할 수 있도록 미리 약속된 형식의 JSON 오류 메시지와 명확한 HTTP 상태 코드를 반환해야 한다. 📜 기존 서블릿 컨테이너의 예외 처리 메커니즘을 이용 WAS에 예외가 전파되거나, response.sendError(statusCode, message)를 통해 오류가 전달되면,해당 오류에 대해 등록된 오류 페이지가 있는지 확인한다.@Componentpubl..
[Spring MVC] 서블릿 컨테이너와 스프링 부트의 예외 처리 방식 웹 애플리케이션에서 예외 처리는 서비스의 안정성과 사용자 경험을 결정하는 매우 중요한 요소다.사용자는 서버의 내부 오류(예: 하얀색 오류 화면)를 보고 싶어 하지 않으며, 개발자는 오류의 원인을 명확하게 파악하고 싶어 한다. 우선 스프링이 제공하는 편리한 기능을 다루기 전에, 그 근간이 되는 서블릿 컨테이너의 예외 처리 방식을 알아보자. WAS가 제공하는 기본 오류 페이지를 보려면 스프링이 제공하는 기본 오류 페이지인 Whitelabel Error Page를 비활성화해야 한다.application.properties 파일에 server.error.whitelabel.enabled=false 옵션을 추가하면 된다. 🧩 서블릿 컨테이너의 예외 처리 방식 서블릿은 두 가지 방식으로 예외 상황을 인지하고 처..
[Spring MVC] 공통 관심 사항 – 서블릿 필터, 스프링 인터셉터 애플리케이션을 개발하다 보면 "로그인 인증"과 같이 여러 컨트롤러에 걸쳐 공통적으로 적용해야 하는 기능들이 생긴다. 물론 모든 컨트롤러에 인증 로직을 일일이 추가할 수도 있지만 매우 비효율적이다.또한 인증 정책이 변경될 때 모든 코드를 수정해야 하는 등 유지보수하기 어려워진다. 이처럼 여러 로직에 흩어져 있지만 하나의 단위로 관리되어야 하는 기능들을 공통 관심 사항(Cross-Cutting Concern)이라고 한다. 공통 관심 사항은 스프링 AOP로도 해결할 수 있다.하지만 "웹"과 관련된 공통 관심 사항은 서블릿 필터 또는 스프링 인터셉터를 이용하는 것이 좋다.필터와 인터셉터는 HTTP 헤더, URL 정보 등 웹 개발에 필요한 정보가 들어있는 HttpServletRequest를 제공하기 때문이다. ..
[Spring MVC] 로그인 처리 – 쿠키, 세션(HttpSession) HTTP 프로토콜은 근본적으로 상태가 없는(Stateless) 특성을 가진다.즉, 서버는 클라이언트의 각 요청을 완전히 독립적인 것으로 취급하며, 이전 요청의 내용을 기억하지 못한다. 이 특성 때문에 "로그인 상태 유지"와 같은 기능은 HTTP만으로는 구현할 수 없다.사용자가 로그인에 성공한 후 다른 페이지로 이동하면, 서버는 그 사용자가 방금 로그인했던 바로 그 사용자라는 사실을 알지 못한다. 이 문제를 해결하기 위해 클라이언트와 서버 간에 상태를 유지(Stateful)하기 위한 기술이 필요하다.그 중 가장 대표적인 것이 바로 쿠키(Cookie)와 세션(Session)이다. 🍪 쿠키(Cookie) 쿠키는 서버가 사용자의 웹 브라우저에 저장하는 작은 데이터 조각이다. 서버는 HTTP 응답 헤더에 쿠키를..
[Spring MVC] Bean Validation 이전의 Validator 인터페이스를 직접 구현하는 방식이 검증 로직을 컨트롤러로부터 분리하는 단계였다면,Bean Validation은 검증 로직 자체를 애노테이션 기반으로 표준화하고 자동화하는 기술이다. 🧩 Bean Validation이란? Bean Validation은 반복적이고 정형화된 검증 로직(예: 값이 비어있는지, 특정 범위를 만족하는지)을 모든 프로젝트에서 일관성 있게 처리할 수 있도록 만든 자바 표준 기술 사양(JSR-380)이다. 이는 특정 구현체가 아닌 인터페이스와 애노테이션의 모음이다.마치 JPA가 데이터 접근 기술의 표준 사양이고, 하이버네이트(Hibernate)가 그 구현체인 것과 같은 관계다. 스프링 부트는 기본 구현체로 Hibernate Validator를 사용한다. 🤔 왜..
[Spring MVC] Validator 다음 검증 코드를 보면 검증 로직이 늘어날수록 컨트롤러 코드가 복잡해진다는 문제점이 존재한다.@PostMapping("/save")public String saveItem(@ModelAttribute Item item, BindingResult bindingResult, // 반드시 검증할 파라미터 바로 뒤에 위치 RedirectAttributes redirectAttributes) { // 검증 로직 if (!StringUtils.hasText(item.getName())) { bindingResult.rejectValue( "name", // field ..
[Spring MVC] BindingResult, MessageCodesResolver 🧩 BindingResult란?폼 바인딩/검증 과정에서 발생한 모든 오류를 담는 객체요청 파라미터 → 객체 변환 중 발생한 바인딩 오류(타입 불일치, 값 범위 초과 등)Bean Validation(@Valid, @Validated) 또는 비즈니스 검증 수행 중 발생한 검증 오류⚠️ 항상 "검증할 파라미터 바로 뒤"에 선언해야 연결됨예: public String saveItem(@ModelAttribute Item item, BindingResult bindingResult) { ... }순서가 어긋나면 BindException이 발생하거나, 다른 객체와 연결될 수도 있음BindingResult 인터페이스는 Errors 인터페이스를 상속함실제로 넘어오는 구현체는 BeanPropertyBindingResu..
[Spring MVC] 검증 (클라이언트 검증 vs 서버 검증) 웹 애플리케이션에서 검증은 애플리케이션의 견고함과 사용자 경험을 좌우하는 핵심 기능이다. 여기서 검증은 사용자가 폼(Form)을 통해 데이터를 제출했을 때, 해당 데이터가 비즈니스 규칙에 맞는지 체계적으로 확인하고, 오류가 있다면 사용자에게 명확하고 친절하게 알려주는 전반적인 과정을 의미한다. 검증은 크게 클라이언트 검증과 서버 검증으로 나눌 수 있다. 💻 클라이언트 검증브라우저(JavaScript, HTML5 input 속성 등)나 모바일 앱에서 사용자 입력을 즉시 검증예: 이메일 형식, 비밀번호 길이, 필수 입력 여부 등✅ 장점빠른 피드백 제공 → 사용자 경험(UX) 향상서버까지 요청이 가지 않아 네트워크/서버 리소스 절약❌ 한계클라이언트 코드는 언제든 조작 가능 (F12 → 콘솔, 네트워크 탭, ..
[Spring MVC] 메시지 & 국제화(i18n) 현대 웹 애플리케이션 개발에서 하드코딩된 텍스트는 유지보수의 가장 큰 적 중 하나다.간단한 문구 하나를 변경하기 위해 수많은 HTML 파일을 수정해야 하는 상황은 비효율적일 뿐만 아니라 실수를 유발하기 쉽다. 스프링은 이러한 문제를 해결하기 위해 유연한 메시지 관리 및 국제화(Internationalization, i18n) 기능을 제공한다. 🤔 메시지 기능이 왜 필요할까? "상품명"이라는 단어를 모두 "상품 이름"으로 바꿔달라는 기획자의 갑작스러운 요청을 받았다고 가정해 보자.만약 모든 텍스트가 HTML 파일에 하드코딩되어 있다면, 개발자는 관련된 모든 파일을 열어 일일이 수작업으로 변경해야 한다.이는 매우 번거롭고 누락의 위험이 크다.상품명 하지만 메시지 기능을 적용하면 화면에 표시되는 모든 텍..
[Spring MVC] 타임리프 폼 데이터 바인딩 – th:object, th:field 타임리프는 스프링 환경에서 HTML 폼 요소와 서버 측 객체 간의 데이터 바인딩을 매우 직관적으로 처리할 수 있는 기능을 제공한다.이를 통해 개발자는 반복적인 코드 작성을 줄이고, 서버에서 전달된 데이터를 손쉽게 화면에 렌더링하며, 사용자가 입력한 값을 다시 서버의 객체로 매핑할 수 있다. 그중 타임리프의 핵심 속성인 th:object와 th:field에 대해서 알아보자. 🧩 th:object (폼 데이터의 주인 지정)폼 바인딩 대상 객체(커맨드 객체)를 지정하는 속성HTML 태그에서 주로 사용하며, 이후 폼 내부의 모든 데이터 바인딩의 기준점이 됨th:object="${userForm}"과 같이 모델에 담긴 객체 이름을 지정해당 폼 내부에서 ${userForm.name} 대신 간결하게 *{name}..
[Spring MVC] 타임리프의 기본 문법 우선 타임리프를 사용하려면 태그에 다음과 같이 선언해야 한다. 📌 변수 출력 – th:text, th:utext, [[...]], [(...)]model.addAttribute("user", new User("홍길동", 25))이름이름[[${user.name}]][(${user.name})]th:text타임리프의 표준 속성해당 HTML 요소의 텍스트 콘텐츠를 출력하고, 기존 콘텐츠를 덮어씀XSS(Cross Site Scripting) 방지를 위해 HTML escape 처리가 자동 적용됨th:utext"unescaped text"의 약자th:text와 마찬가지로 텍스트를 출력하지만, HTML escape 없이 그대로 출력HTML 태그를 포함한 콘텐츠를 브라우저에 직접 렌더링 하고 싶을 때 사용[[....
[Spring MVC] 타임리프(Thymeleaf) 타임리프는 서버 측에서 데이터를 받아 HTML을 동적으로 만들어 클라이언트로 전송하는 템플릿 엔진이다.주로 Spring MVC에서 뷰(View)를 생성할 때 사용되며, 기존의 JSP를 대체하거나 보완하는 용도로 많이 활용된다.타임리프의 기본 문법은 다음 글을 참고하자. 🧩 타임리프의 핵심 특징서버 사이드 HTML 렌더링 (SSR: Server-Side Rendering)타임리프는 서버에서 HTML을 동적으로 생성하고, 클라이언트(브라우저)에게 완성된 HTML을 응답하는 방식으로 동작함컨트롤러에서 전달한 모델 데이터를 기반으로 템플릿 파일 내의 변수를 치환하여 최종 HTML 생성내추럴 템플릿(Natural Templates)순수 HTML 구조를 유지하면서 템플릿 역할까지 수행하는 방식타임리프 파일은 순수..
[Spring MVC] HttpEntity – RequestEntity, ResponseEntity Spring MVC는 HTTP 요청/응답 메시지를 직접 다루는 대신, 이를 추상화된 객체로 표현하여 제공한다.이는 서블릿 API에 종속적이지 않고, 보다 객체 지향적인 HTTP 메시지 처리를 가능하게 한다. 즉, HttpEntity와 이를 상속한 RequestEntity와 ResponseEntity는 HTTP 요청 및 응답 메시지를 추상화하여 개발자가 손쉽게 요청과 응답을 처리하도록 도와주는 객체다. 🧱 HttpEntity – 헤더, 바디public class HttpEntity { private final HttpHeaders headers; @Nullable private final T body; ...}HTTP 요청 또는 응답의 헤더와 바디를 캡슐화하는 클래스R..
[Spring MVC] @ResponseBody 🧩 @ResponseBody란? 스프링 MVC에서 핸들러 메서드의 반환 값을 HTTP 응답 본문으로 직접 변환하도록 지시하는 애노테이션이다. 즉, 반환 값을 ViewResolver를 통해 뷰로 변환하지 않고,HttpMessageConverter를 사용해 반환 객체를 HTTP 응답 본문(body)에 직접 쓰도록(직렬화) 처리한다. 예시:@GetMapping("/user")@ResponseBodypublic UserDto getUser() { return new UserDto("kim", 25);}HTTP/1.1 200 OKContent-Type: application/json{ "name": "kim", "age": 25} 👉 반환된 UserDto 객체는 MappingJackson2Ht..
[Spring MVC] @RequestBody 🧩 @RequestBody란? 스프링 MVC에서 HTTP 요청 본문(body)을 자바 객체로 변환하여 핸들러 메서드 파라미터에 바인딩할 때 사용하는 애노테이션이다. @ModelAttribute는 주로 폼 데이터(application/x-www-form-urlencoded)를 자바 객체로 받을 때 사용한다면,@RequestBody는 주로 XML, JSON(application/json) 등 구조화된 데이터를 자바 객체로 받을 때 사용한다. 예시:POST /usersContent-Type: application/json{ "name": "kim", "age": 25}@PostMapping("/users")public String saveUser(@RequestBody UserDto user) { .....
[Spring MVC] @PathVariable 🧩 @PathVariable이란? 스프링 MVC에서 URI 템플릿 변수(경로 변수)를 핸들러 메서드 파라미터에 바인딩하기 위해 사용하는 애노테이션이다. @RequestParam이나 @ModelAttribute와는 달리, URL 경로 자체에 포함된 값을 추출하는 데 사용되며,주로 RESTful 스타일의 URL에서 자주 활용된다. 예시: GET /users/2@GetMapping("/users/{id}")public String getUser(@PathVariable("id") Long userId) { ... } 👉 {id}에 해당하는 값인 2가 userId에 바인딩된다. 🔎 왜 사용하는가? 과거에는 대부분의 데이터 전달이 ?key=value 형태의 쿼리 파라미터를 통해 이루어졌다.하지만 RESTf..
[Spring MVC] @ModelAttribute 🧩 @ModelAttribute란? 스프링 MVC에서 컨트롤러 메서드의 파라미터나 반환 값을 모델(Model)에 바인딩하거나,HTTP 요청 파라미터를 커맨드 객체로 변환하여 컨트롤러 메서드의 파라미터에 바인딩할 때 사용하는 애노테이션이다. 즉, 여러 개의 파라미터가 하나의 객체 필드로 대응될 수 있을 때, 그 객체를 자동으로 생성하고 필드에 값을 바인딩해 준다. @RequestParam은 요청 파라미터를 단순 타입(int, Long, String, Enum 등)의 파라미터로 받을 때 사용한다면,@ModelAttribute는 요청 파라미터를 복합 타입(UserForm 등)의 파라미터로 받을 때 사용한다. 예시:POST /joinContent-Type: application/x-www-form-urlenc..
[Spring MVC] @RequestParam 🧩 @RequestParam이란? 스프링 MVC에서 HTTP 요청 파라미터를 핸들러 메서드의 파라미터에 바인딩할 때 사용하는 애노테이션이다. 요청 파라미터는 아래 두 가지 방식으로 전달된다.쿼리 파라미터: GET /search?q=spring폼 데이터: POST 요청에서 application/x-www-form-urlencoded 타입으로 전달 쿼리 파라미터와 폼 데이터가 모두 요청 파라미터로 인식될 수 있는 이유는서블릿 API가 이들을 모두 ServletRequest.getParameter() 기반으로 통합해서 조회할 수 있도록 설계되어 있기 때문이다. @RequestParam은 주로 GET 요청에서 검색어, 필터, 정렬 등과, POST 요청에서 로그인 정보, 폼 입력 데이터 등을 받아올 때 유용하다..
[Spring MVC] 애노테이션 기반 컨트롤러의 주요 파라미터 바인딩, required 옵션 주의점, value (=name) 생략 시 주의점 Spring MVC의 @RequestMapping 애노테이션 기반 컨트롤러는 다양한 방식으로 요청 데이터를 핸들러 메서드의 파라미터로 받을 수 있도록 하는 파라미터 바인딩 기능을 제공한다. 몇가지 주요 애노테이션들과 인터페이스를 알아보자. 📌 @RequestParam – 쿼리 파라미터 / HTML Form 파라미터@GetMapping("/hello")public String hello(@RequestParam("name") String name) { ... }GET /hello?name=kim 요청 → name에 "kim"이 바인딩됨단순 타입(int, Integer, String 등)일 경우, @RequestParam 생략 가능 (실무에선 명확성 때문에 생략하지 않는 것을 권장)속성: value (=n..
[Spring MVC] 애노테이션 기반 컨트롤러의 핵심 – @RequestMapping 🧩 @RequestMapping이란? Spring MVC에서 HTTP 요청을 특정 컨트롤러 메서드에 매핑하기 위해 사용하는 애노테이션이다. 요청 URL, HTTP 메서드, 파라미터 조건, 헤더 조건, 미디어 타입 조건 등을 조합하여 요청을 정교하게 매핑할 수 있다. 예시:@RequestMapping("/hello")public String hello() { return "hello";} 👉 /hello 경로로 들어온 모든 요청을 해당 메서드로 처리 🧩 @RequestMapping을 클래스 레벨에 선언 시? @RequestMapping은 메서드 레벨, 클래스 레벨 모두에서 사용할 수 있다.클래스 레벨에서는 공통 URL 경로를 지정하고, 메서드 레벨에서는 세부적인 경로와 매핑 조건을 지정한다. 예..
[Spring MVC] 애노테이션 기반 컨트롤러 🧩 애노테이션 기반 컨트롤러의 탄생 배경과 의의 초기의 스프링 프레임워크는 주로 DI(의존성 주입)와 AOP(관점 지향 프로그래밍)에 초점을 맞추었기 때문에, 웹 계층 기능은 미흡했다.그 결과, 웹 계층은 Struts, WebWork 등 외부 MVC 프레임워크에 의존하는 구조가 일반적이었고, 스프링은 단순히 비즈니스 로직을 위한 DI 컨테이너로 사용되는 경우가 많았다. 하지만 @RequestMapping 기반의 애노테이션 컨트롤러가 도입되면서 상황이 크게 달라졌다.XML 설정 없이 단순한 자바 코드로 명확하게 URL과 컨트롤러를 매핑할 수 있게 되었고, 프로그래밍적 선언 방식이 가능해졌다.그 결과, 스프링은 완전한 MVC 프레임워크로 진화하게 되었으며, 현재는 사실상의 표준 웹 프레임워크로 자리잡게 되..
[Spring MVC] ViewResolver 🧩 ViewResolver란? Spring MVC에서 컨트롤러(핸들러)는 뷰 자체가 아니라 단순히 논리 뷰 이름을 반환한다.하지만 뷰가 렌더링되려면 실제 물리 경로가 필요하다. ViewResolver는 논리 뷰 이름을 실제 렌더링 가능한 물리 뷰 경로로 변환하여 실제 뷰 객체를 생성하는 역할을 담당한다. 즉, 논리 뷰 이름을 받아서 실제 뷰 객체를 반환하는 것이 ViewResolver의 핵심 역할이다. 🧩 주요 ViewResolver 종류 스프링 부트는 다음과 같은 ViewResolver를 우선순위에 따라 등록한다.우선순위ViewResolver설명1BeanNameViewResolver뷰 이름과 일치하는 스프링 빈을 탐색2InternalResourceViewResolver뷰 이름에 prefix와 suf..
[Spring MVC] HandlerMapping, HandlerAdapter 스프링 MVC는 다양한 형태의 컨트롤러(핸들러)를 하나의 일관된 구조 내에서 처리할 수 있도록 설계되어 있다.이 유연함의 핵심은 바로 HandlerMapping과 HandlerAdapter 두 인터페이스 컴포넌트에 있다.HandlerMapping: 요청 URL에 매핑되는 핸들러를 찾는 역할HandlerAdapter: 찾아낸 핸들러를 실제로 실행하는 방법을 결정하는 역할 이 두 컴포넌트를 통해 스프링 MVC는 아래와 같은 흐름으로 동작한다.클라이언트가 요청을 보낸다.HandlerMapping이 요청에 해당하는 핸들러 객체(컨트롤러)를 탐색한다.HandlerAdapter가 해당 핸들러를 어떻게 실행할지를 결정하고 실행한다.반환된 ModelAndView를 기반으로 뷰가 렌더링된다. 🧩 과거 방식의 컨트롤러 ..
[Spring MVC] 스프링 MVC의 핵심 – DispatcherServlet 스프링 MVC는 전통적인 웹 애플리케이션 아키텍처의 핵심 패턴인 프론트 컨트롤러(Front Controller) 패턴을 기반으로 동작한다.점진적으로 직접 구현한 프론트 컨트롤러 프레임워크와 스프링 MVC의 구조를 비교해 보면 그 유사성이 명확히 드러난다.직접 구현스프링 MVC설명FrontControllerServletDispatcherServletHTTP 요청을 중앙에서 받아 처리하는 프론트 컨트롤러handlerMappingMapHandlerMapping요청 URL에 매핑되는 컨트롤러(핸들러)를 탐색MyHandlerAdapterHandlerAdapter다양한 방식의 핸들러를 유연하게 호출하는 어댑터ModelViewModelAndView모델 데이터와 뷰 이름을 함께 담는 객체viewResolver()Vie..
[Spring MVC] 프론트 컨트롤러 패턴의 점진적 도입 기존의 MVC 패턴은 중복 코드, 유지보수의 어려움, 구조 일관성 부족 등의 한계가 존재했다.이 문제를 해결하기 위해 프론트 컨트롤러(Front Controller) 패턴을 점진적으로 도입해 보자. (v1 ~ v5) 1️⃣ 프론트 컨트롤러 패턴 v1❌ 기존 MVC 패턴의 한계컨트롤러마다 개별적으로 서블릿 클래스를 작성해야 하며, 요청 URL별로 각각 매핑이 필요함이로 인해 서블릿 클래스가 많아지고, 각 컨트롤러에 공통적으로 필요한 로직(예: 인코딩, 인증, 로깅 등)이 중복 처리됨확장이나 변경이 어려워지고, 전반적인 코드 구조의 일관성도 무너지게 됨테스트 관점에서도 서블릿에 종속되기 때문에, 단위 테스트가 어렵고 생산성이 저하됨 ✅ 프론트 컨트롤러 패턴 v1: 컨트롤러 진입점의 일원화 단 하나의 서블..
[Spring MVC] MVC 패턴을 적용한 서블릿 + JSP 기반 웹 애플리케이션 웹 애플리케이션의 구조를 명확하게 분리하기 위해 MVC 패턴(Model-View-Controller)을 적용해 보자.Controller → 서블릿클라이언트의 요청을 받아서 처리하고, View로 제어를 전달하는 역할 View → JSP단순히 데이터를 받아서 화면을 그리는 역할만 수행화면에 필요한 데이터는 컨트롤러가 준비하고 JSP는 순수하게 출력만 담당Model → HttpServletRequestHttpServletRequest는 내부에 데이터 저장소(속성 맵)를 가지고 있다.request.setAttribute(key, value)를 통해 데이터를 저장하고,request.getAttribute(key)를 통해 데이터를 조회할 수 있다.이 방식을 사용하면 컨트롤러에서 만든 데이터를 JSP로 전달할 수 있..
[Spring MVC] 순수 JSP 기반 웹 애플리케이션 기존의 순수 서블릿 기반 웹 애플리케이션을 JSP(JavaServer Pages) 기반으로 전환해보자. 🔹 회원 등록 폼 – new-form.jsp 이름: 나이: 등록 contentType: JSP가 생성하는 응답의 MIME 타입을 설정한다.form: /jsp/members/save.jsp로 POST 요청을 보낸다. 이는 회원 정보를 저장하는 페이지이다. 🔹 회원 저장 처리 – save.jsp 회원 등록 성공 id= username= age= 메인 JSP는 내부적으로 서블릿으로 변환되므로, 서블릿과 동일하게 request, response 객체 사용이 가능하다.: 자바 로직을 포함하는 JSP 스..
[Spring MVC] 순수 서블릿 기반 웹 애플리케이션 서블릿만을 이용하여 회원 등록, 회원 목록 조회 기능을 가진 간단한 웹 애플리케이션을 만들어 보자. 🔹 도메인 회원 객체 – Member@Getter @Setterpublic class Member { private Long id; private String username; private int age; public Member() {} public Member(String username, int age) { this.username = username; this.age = age; }}id: 내부 저장소에서 부여username, age: 사용자가 입력한 정보 🔹 메모리 기반 회원 저장소 (싱글톤) – MemberRepositorypubli..