티스토리 뷰

 

핵심 요약

1. @ModelAttribute는 "가장 적절한" 생성자를 찾아 객체를 생성 및 초기화한다
2. 객체 생성 및 초기화 -> Data Binding -> Validation 순서로 진행된다
3. Data Binding은 getter / setter가 존재하는 변수에 한해서 이루어진다

 

@ModelAttribute

- Annotation that binds a method parameter or method return value to a named model attribute, exposed to a web view. 

(메서드 파라미터를 Bind 해주거나, 웹 뷰에 노출되는 모델을 지정된 name 속성으로 담아 리턴해주는 애노테이션)

 

- Supported for controller classes with @RequestMapping methods.

(@RequestMapping 애노테이션이 달려있는 컨트롤러 클래스와 함께 사용됨)

 

-  Data binding can lead to security issues by exposing parts of the object graph that are not meant to be accessed or modified by external clients. 

(데이터 바인딩은 보안 이슈를 불러올 수도 있음 - 외부 클라이언드가 접근(get)하거나 수정(set)하면 안되는 객체의 일부분을 노출하게 됨으로써..= DTO를 쓰자)

 

- Note however that reference data and all other model content are not available to web views when request processing results in an Exception since the exception could be raised at any time making the content of the model unreliable. 

(처리 과정 중에 Exception이 터지면 (대표적으로 Type mismatch), 해당 모델은 신뢰할 수 없는 것이기 때문에 View에 모델을 리턴하지 않는다)

 

*  Data Binding 중 발생하는 BindException을 처리하고 싶으면 @ModelAttribute 뒤에 BindingResult를 붙여줘야 한다 (아래 참고)

 

* 모델을 지정된 name 속성으로 뷰에 리턴해준다는 것은

@PostMapping
public String registerAdmin(@ModelAttribute("admin") AdminRegisterDto registerDTO) {
    ...
}

@ModelAttribute("이름")을 받았을 때

registerDTO의 값을 getter/setter로 바인딩 해준 이후에

model.addAttribute("admin", registerDTO);

위 코드를 자동으로 만들어서 넣어준다는 의미이다.

 

 

# 스프링에서 ModelAttribute가 객체를 생성하는 방법

(우선순위 순 정렬인지는 모르겠으나, 이 중 한가지 방법을 이용해 객체를 생성/초기화 한다)

 

- Retrieved from the model where it may have been added by a @ModelAttribute method.

 

- Retrieved from the HTTP session if the model attribute was listed in the class-level @SessionAttributes annotation

 

- Obtained through a Converter where the model attribute name matches the name of a request value such as a path variable or a request parameter (see next example).

 

- Instantiated using its default constructor. = 기본 생성자(NoArgsConstructor) 이용

 

- Instantiated through a “primary constructor” with arguments that match to Servlet request parameters. Argument names are determined through JavaBeans @ConstructorProperties or through runtime-retained parameter names in the bytecode. = request parameter와 가장 잘 맞는(?) 생성자를 이용

 

 

@ModelAttribute의 Data Binding

- After the model attribute instance is obtained, data binding is applied. 

(모델 객체가 초기화 된 이후에 데이터 바인딩을 적용한다)

 

- Only public properties following the JavaBeans naming conventions are exposed for data binding

(자바빈 명명 규칙을 따르는 public 프로퍼티가 존재하는 데이터에 대해서만 바인딩이 이루어진다)

= 각 변수마다 public getter / public setter 가 있어야 한다는 것.

 

- It is extremely important to properly configure allowed and disallowed field patterns when exposing your domain model directly for data binding purposes. Otherwise, it is a big security risk.

((DTO 없이) 도메인 모델을 곧바로 데이터 바인딩 하고자 할 때는, 노출할 변수와 숨길 변수를 잘 설정하는 것이 매우 중요하다)

-> 외부로부터 숨기고 싶은 변수는 getter/setter를 뗀 채로 사용하면 OK


- Furthermore, it is strongly recommended that you do not use types from your domain model such as JPA or Hibernate entities as the model object in data binding scenarios.

(JPA(Hibernate) 엔티티(도메인) 모델을 곧바로 바인딩 받는 것은 매우 권장하지 않는다 = DTO를 사용해라)

 

- Data binding can result in errors. By default, a BindException is raised. However, to check for such errors in the controller method, you can add a BindingResult argument immediately next to the @ModelAttribute

(Data Binding에 실패하면, BindException이 발생한다. 예외를 바로 던지지 않고 컨트롤러에서 별도로 처리하고 싶으면 @ModelAttribute 바로 옆에 BindingResult를 붙이면 된다)

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) {
    if (result.hasErrors()) {
        return "petForm";
    }
    // ...
}

 

- You can automatically apply validation after data binding by adding the jakarta.validation.Valid annotation or Spring’s @Validated annotation

(Data Binding이 끝난 이후에는 @Valid, @Validated 애노테이션을 이용해 값을 검증하도록 할 수 있다)

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) { (1)
    if (result.hasErrors()) {
        return "petForm";
    }
    // ...
}

=> 객체 생성 및 초기화 -> Data Binding -> Validation 순서로 진행된다

 

- Note that using @ModelAttribute is optional (for example, to set its attributes). By default, any argument that is not a simple value type and is not resolved by any other argument resolver is treated as if it were annotated with @ModelAttribute.

(simple value type 또는 다른 argument resolver가 처리하는 것이 아닌 경우는 모두 @ModelAttribute가 적용되기 때문에 생략해도 된다)

 

* simple value type: a primitive or primitive wrapper, an enum, a String or other CharSequence, a Number, a Date, a Temporal, a URI, a URL, a Locale, or a Class.

(원시 자료형 및 Wrapper / Enum / String / Number / Date 등)

 

 

 

<참고>

 

ModelAttribute (Spring Framework 6.0.0 API)

The name of the model attribute to bind to. The default model attribute name is inferred from the declared attribute type (i.e. the method parameter type or method return type), based on the non-qualified class name: e.g. "orderAddress" for class "mypackag

docs.spring.io

 

Web on Servlet Stack

This part of the reference documentation covers support for Servlet stack, WebSocket messaging that includes raw WebSocket interactions, WebSocket emulation through SockJS, and publish-subscribe messaging through STOMP as a sub-protocol over WebSocket. = I

docs.spring.io

 

Web on Servlet Stack

This part of the reference documentation covers support for Servlet stack, WebSocket messaging that includes raw WebSocket interactions, WebSocket emulation through SockJS, and publish-subscribe messaging through STOMP as a sub-protocol over WebSocket. = I

docs.spring.io

 

@ModelAttribute와 @RequestBody 그리고 Setter

@RequestBody와 Setter 본 주제에 대해 이야기하기 전에 먼저 @ModelAttribute에 대해 이야기해보려합니다. @ModelAttribute 우리는 Spring에서 Reqeust Parameter를 얻기 위해 @ModelAttribute를 사용하곤합니다. 값을 바

minchul-son.tistory.com

 

 

읽는 시간은 확실히 오래걸리는데 그만큼 이해가 엄청 잘 되는 것 같다

앞으로도 공식문서 읽는 습관을 들여야지..

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함