2024. 10. 9. 12:12ㆍSpring Framework/Web on Servlet Stack
https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/modelattrib-method-args.html@ModelAttribute
어노테이션은 HTTP 요청의 파라미터를 객체에 바인딩하는 데 사용되는 스프링 MVC의 기능입니다. 이를 통해 클라이언트가 전송한 폼 데이터나 쿼리 스트링 파라미터를 자동으로 객체에 매핑할 수 있습니다. 또한, 이 객체는 뷰에서 사용될 모델에 추가될 수 있습니다. 스프링은 여러 방식으로 @ModelAttribute
에 해당하는 객체를 생성하고 바인딩할 수 있으며, 유효성 검사 및 데이터 바인딩 과정에서의 오류 처리도 가능합니다.
기본 개념
@ModelAttribute
는 주로 컨트롤러 메서드의 아규먼트로 사용되어, 요청 파라미터를 자동으로 특정 객체에 바인딩합니다.
예시 상황:
클라이언트가 아래와 같은 HTTP 요청을 통해 데이터를 전송했다고 가정합니다.
POST /owners/1/pets/2/edit
Content-Type: application/x-www-form-urlencoded
name=Max&age=5&species=dog
이 요청에서 name
, age
, species
와 같은 파라미터를 Pet
객체로 매핑하고 싶다면, @ModelAttribute
를 사용하여 이를 자동으로 처리할 수 있습니다.
예시 코드 (Java)
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.stereotype.Controller;
@Controller
public class PetController {
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute Pet pet) {
System.out.println("Pet Name: " + pet.getName());
System.out.println("Pet Age: " + pet.getAge());
System.out.println("Pet Species: " + pet.getSpecies());
return "petDetails";
}
}
코드 설명:
@ModelAttribute Pet pet
:Pet
객체에 클라이언트로부터 전달된 요청 파라미터를 바인딩합니다.name
,age
,species
파라미터는Pet
객체의 필드로 자동으로 매핑됩니다.- 메서드 아규먼트로
Pet
객체가 선언되었기 때문에, 스프링은 이를 자동으로 바인딩하고, 그 결과로 생성된Pet
객체를 메서드 내에서 사용할 수 있습니다.
객체 생성 방식
- 기본 생성자:
@ModelAttribute
로 지정된 객체는 기본적으로 해당 클래스의 기본 생성자를 통해 생성됩니다. - 요청 파라미터 매핑: 생성된 객체의 필드에 요청 파라미터가 자동으로 매핑됩니다. 이 과정에서 스프링은 파라미터 이름과 객체의 필드 이름을 일치시키려고 합니다.
- 컨버터 사용: 만약 요청 파라미터가 객체로 변환되기 위해서 특별한 변환이 필요하다면,
Converter<String, T>
를 구현하여 변환 과정을 추가할 수 있습니다.
예시 (경로 변수와의 매핑)
@PutMapping("/accounts/{account}")
public String save(@ModelAttribute("account") Account account) {
//...
}
이 예시에서 account
경로 변수가 Account
객체로 바인딩됩니다. 스프링은 요청에서 account
라는 경로 변수를 찾아, 그것을 Account
객체로 변환합니다. 이 과정에서 Converter<String, Account>
가 필요할 수 있으며, 이를 통해 데이터베이스에서 Account
객체를 가져오거나 적절한 변환을 수행할 수 있습니다.
유효성 검사 및 바인딩 오류 처리
@ModelAttribute
는 데이터를 바인딩하는 과정에서 발생하는 오류를 처리할 수 있습니다. 이를 위해 BindingResult를 아규먼트로 추가할 수 있습니다. 유효성 검사를 자동으로 적용하고 싶다면 @Valid
또는 @Validated
어노테이션을 추가할 수 있습니다.
예시 코드 (유효성 검사 및 오류 처리)
import org.springframework.validation.BindingResult;
import jakarta.validation.Valid;
@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) {
if (result.hasErrors()) {
return "petForm";
}
// 데이터 처리 로직...
return "petDetails";
}
코드 설명:
@Valid
:Pet
객체의 필드에 대해 유효성 검사를 수행합니다. 이 검사는Pet
클래스의 필드에 정의된 제약 조건(예:@NotNull
,@Size
)을 바탕으로 이루어집니다.BindingResult
: 유효성 검사 결과나 데이터 바인딩 과정에서의 오류를 저장합니다. 오류가 있을 경우 이를 처리할 수 있습니다.
데이터 바인딩 없이 모델에 값 추가
@ModelAttribute
는 데이터 바인딩 없이도 단순히 모델에 객체를 추가할 수 있습니다. 예를 들어, binding=false
옵션을 사용하면 바인딩을 하지 않고 객체를 모델에 추가할 수 있습니다.
예시 코드 (바인딩 없이 모델에 추가)
@ModelAttribute
public AccountForm setUpForm() {
return new AccountForm();
}
@PostMapping("/update")
public String update(@ModelAttribute(binding=false) Account account, AccountForm form) {
// 여기서 Account는 바인딩되지 않음
return "accountDetails";
}
Reactive 스택에서의 사용 (Spring WebFlux)
Spring WebFlux에서도 유사하게 @ModelAttribute
와 같은 방식으로 요청 파라미터를 객체에 바인딩할 수 있습니다. 다만, WebFlux는 비동기 처리를 지원하기 때문에 Mono
또는 Flux
로 데이터를 처리하게 됩니다.
Reactive 예시 코드
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.stereotype.Controller;
import reactor.core.publisher.Mono;
@Controller
public class ReactivePetController {
@PostMapping("/reactive-pets/edit")
public Mono<String> processSubmit(@ModelAttribute Pet pet) {
return Mono.just("Processed pet: " + pet.getName());
}
}
코드 설명:
Mono<String>
을 통해 비동기 방식으로 결과를 반환합니다.@ModelAttribute
는 Spring WebFlux에서도 기존 MVC 방식과 동일하게 요청 파라미터를 객체에 바인딩합니다.
요약
@ModelAttribute
는 요청 파라미터를 객체에 자동으로 바인딩하는 어노테이션입니다.- 유효성 검사, 오류 처리, 모델에 객체 추가 등의 다양한 기능을 제공합니다.
- WebFlux에서도 유사한 방식으로 사용 가능하며, 비동기 처리를 지원합니다.
'Spring Framework > Web on Servlet Stack' 카테고리의 다른 글
Handler Method : @SessionAttribute (0) | 2024.10.09 |
---|---|
Handler Method : @SessionAttributes (6) | 2024.10.09 |
Annotated Controllers[3] - @CookieValue (0) | 2024.10.09 |
@RequestHeader (0) | 2024.10.09 |
Annotated Controllers[1] (1) | 2024.10.06 |