Loading...
Spring Framework Reference Documentation 7.0.2의 @ModelAttribute의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
@ModelAttributeSee equivalent in the Reactive stack
@ModelAttribute method parameter annotation은 요청 매개변수, URI 경로 변수, 그리고 요청 헤더를 모델 객체에 바인딩합니다. 예를 들어:
1@PostMapping("/owners/{ownerId}/pets/{petId}/edit") 2public String processSubmit(@ModelAttribute Pet pet) { (1) 3 // method logic... 4}
| 1 | Pet의 인스턴스에 바인딩합니다. |
1@PostMapping("/owners/{ownerId}/pets/{petId}/edit") 2fun processSubmit(@ModelAttribute pet: Pet): String { (1) 3 // method logic... 4}
| 1 | Pet의 인스턴스에 바인딩합니다. |
요청 매개변수는 요청 본문의 폼 데이터와 쿼리 매개변수를 포함하는 Servlet API 개념입니다. URI 변수와 헤더도 포함되지만, 동일한 이름의 요청 매개변수를 오버라이드하지 않는 경우에만 포함됩니다. 헤더 이름의 대시는 제거됩니다.
위의 Pet 인스턴스는 다음과 같이 얻을 수 있습니다:
@SessionAttributes annotation에 모델 속성이 나열된 경우, HTTP 세션에서 액세스.Converter를 통해 획득 (예제는 아래에 이어짐).위에서 언급했듯이, 모델 속성 이름이 경로 변수나 요청 매개변수와 같은 요청 값의 이름과 일치하고, 그리고 호환되는 Converter<String, T>가 있는 경우, Converter<String, T>를 사용하여 모델 객체를 얻을 수 있습니다. 아래 예제에서, 모델 속성 이름 account는 URI 경로 변수 account와 일치하고, 이를 퍼시스턴스 저장소에서 조회하는 등록된 Converter<String, Account>가 있습니다:
1@PutMapping("/accounts/{account}") 2public String save(@ModelAttribute("account") Account account) { (1) 3 // ... 4}
1@PutMapping("/accounts/{account}") 2fun save(@ModelAttribute("account") account: Account): String { (1) 3 // ... 4}
기본적으로 생성자와 프로퍼티 데이터 바인딩이 모두 적용됩니다. 그러나, 모델 객체 설계에는 신중한 고려가 필요하며, 보안상의 이유로 웹 바인딩에 특화된 객체를 사용하거나 생성자 바인딩만 적용하는 것이 권장됩니다.
프로퍼티 바인딩을 반드시 사용해야 하는 경우에는, 어떤 프로퍼티를 설정할 수 있는지 제한하기 위해 allowedFields 패턴을 설정해야 합니다. 이에 대한 추가 세부사항과 예제 설정은 모델 설계을 참고하십시오.
생성자 바인딩을 사용할 때는 @BindParam annotation을 통해 요청 매개변수 이름을 커스터마이즈할 수 있습니다. 예를 들어:
1class Account { 2 3 private final String firstName; 4 5 public Account(@BindParam("first-name") String firstName) { 6 this.firstName = firstName; 7 } 8}
1class Account(@BindParam("first-name") val firstName: String)
@BindParam은 생성자 매개변수에 해당하는 필드에도 지정할 수 있습니다.<br>@BindParam은 기본으로(out of the box) 지원되지만,DataBinder에DataBinder.NameResolver를<br>설정하여 다른 annotation을 사용할 수도 있습니다.
생성자 바인딩은 List, Map, 그리고 배열 인자를 지원하며, 이는 하나의 문자열 (예: 쉼표로 구분된 목록)에서 변환되거나, accounts[2].name 또는 account[KEY].name과 같은 인덱스 키를 기반으로 할 수도 있습니다.
일부 경우에는 데이터 바인딩 없이 모델 속성에 액세스해야 할 수 있습니다. 이러한 경우에는 Model을 컨트롤러에 주입하여 직접 액세스하거나, 다음 예제에서 보듯이 @ModelAttribute(binding=false)를 설정할 수 있습니다:
1@ModelAttribute 2public AccountForm setUpForm() { 3 return new AccountForm(); 4} 5 6@ModelAttribute 7public Account findAccount(@PathVariable String accountId) { 8 return accountRepository.findOne(accountId); 9} 10 11@PostMapping("update") 12public String update(AccountForm form, BindingResult result, 13 @ModelAttribute(binding=false) Account account) { (1) 14 // ... 15}
| 1 | @ModelAttribute(binding=false) 설정. |
1@ModelAttribute 2fun setUpForm(): AccountForm { 3 return AccountForm() 4} 5 6@ModelAttribute 7fun findAccount(@PathVariable accountId: String): Account { 8 return accountRepository.findOne(accountId) 9} 10 11@PostMapping("update") 12fun update(form: AccountForm, result: BindingResult, 13 @ModelAttribute(binding = false) account: Account): String { (1) 14 // ... 15}
| 1 | @ModelAttribute(binding=false) 설정. |
데이터 바인딩에서 오류가 발생하면, 기본적으로 MethodArgumentNotValidException이 발생하지만, 이러한 오류를 컨트롤러 메서드에서 처리하기 위해 @ModelAttribute 바로 옆에 BindingResult 인자를 추가할 수도 있습니다. 예를 들어:
1@PostMapping("/owners/{ownerId}/pets/{petId}/edit") 2public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) { (1) 3 if (result.hasErrors()) { 4 return "petForm"; 5 } 6 // ... 7}
| 1 | @ModelAttribute 옆에 BindingResult를 추가. |
1@PostMapping("/owners/{ownerId}/pets/{petId}/edit") 2fun processSubmit(@ModelAttribute("pet") pet: Pet, result: BindingResult): String { (1) 3 if (result.hasErrors()) { 4 return "petForm" 5 } 6 // ... 7}
| 1 | @ModelAttribute 옆에 BindingResult를 추가. |
데이터 바인딩 이후에 자동으로 검증을 적용하려면 jakarta.validation.Valid annotation이나 Spring의 @Validated annotation을 추가하면 됩니다. Bean Validation과 Spring validation을 참고하십시오. 예를 들어:
1@PostMapping("/owners/{ownerId}/pets/{petId}/edit") 2public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) { (1) 3 if (result.hasErrors()) { 4 return "petForm"; 5 } 6 // ... 7}
| 1 | Pet 인스턴스를 검증. |
1@PostMapping("/owners/{ownerId}/pets/{petId}/edit") 2fun processSubmit(@Valid @ModelAttribute("pet") pet: Pet, result: BindingResult): String { (1) 3 if (result.hasErrors()) { 4 return "petForm" 5 } 6 // ... 7}
| 1 | Pet 인스턴스를 검증. |
@ModelAttribute 뒤에 BindingResult 매개변수가 없는 경우, 검증 오류와 함께 MethodArgumentNotValidException이 발생합니다. 그러나, 다른 매개변수에 @jakarta.validation.Constraint annotation이 있어서 메서드 검증이 적용되는 경우에는 대신 HandlerMethodValidationException이 발생합니다. 자세한 내용은 Validation 섹션을 참고하십시오.
@ModelAttribute사용은 선택 사항입니다. 기본적으로,<br>BeanUtils#isSimpleProperty에 의해<br>단순 값 타입이 아니고 AND 다른 인자 리졸버에 의해 리졸브되지 않는<br>모든 매개변수는 암시적인@ModelAttribute로 간주됩니다.
GraalVM으로 네이티브 이미지를 컴파일할 때, 위에서 설명한 암시적인<br>
@ModelAttribute지원은 관련 데이터 바인딩 리플렉션 힌트에 대한 적절한<br>사전(AOT) 추론을 허용하지 않습니다. 그 결과, GraalVM 네이티브 이미지에서 사용하기 위해서는<br>메서드 매개변수에@ModelAttribute를 명시적으로 annotation하는 것이 권장됩니다.
@CookieValue
@SessionAttributes