@ModelAttribute / @RequestBody 애너테이션은 웬만하면 붙여주는 편이 명확하다.

  • @ModelAttribute를 명시하지 않아도 자동으로 URL 파라미터를 객체로 매핑해주고, GET은 관례적으로 URL 파라미터로 데이터를 전달하기 때문에, 굳이 @ModelAttribute를 사용해야 하느냐 라고 생각할 수 있는데
  • Controller에서 GetMapping 메서드는 사실 (URL 파라미터/HTTP 바디) 양 쪽 모두 데이터를 받을 수 있다.
  • 따라서 항상 `` @ModelAttribute / @RequestBody``를 명시해 주는 편이 좋다.

 

@RequestParam

queryString이나 form 요청에서 파라미터를 하나 하나 받을 때 사용한다.

```java

@RequestParam("name")

@RequestParam(value="name", defaultValue="unknown") 

// ?name이 없어도 4** 뜨지 않음

@RequestParam(value="name", required=false) 

```

  • 파라미터 하나 하나 마다 애너테이션을 적어줘야 하니 여러개를 받을 때는 지저분해져서 부적합하다.
    • 여러개를 한번에 받기 위해 아래 처럼 Map으로 받는 방식은 쓰지 않는 것이 좋다.
    • 대신 커맨드 객체(+@ModelAttribute)를 사용하자.

```java

// 아래 방식은 별로다. 커맨드 객체를 쓰자

@RequestParam HashMap<string,string> paramMap

```

 

@RequestParam VS @PathVariable

자원 자체를 나타낼 때는 @PathVariable

orderBy나, filter 같은 조건을 명시하는 것에는 @RequestParam

근데 깔끔하게 설계가 잘 안되는 경우도 있으니까. 상황에 따라 맞춰서 사용하는 경우도 있음.

포함 관계가 아닐 때가 애매한데, 이는 검색 조건으로 보고 @RequestParam으로 처리하는 것이 매끄러운 것 같기도 함.

REST api / RESTful 이란.

 

@RequestParam이나 @PathVariable이나 파라미터가 너무 많은 경우 Map이나 command 객체 사용 가능

 

@ModelAttribute

```java

public List<User> getUserList(@ModelAttribute UserSearch userSearch) {
    return userService.getUserList(userSearch);
}

```

  • URL 파라미터 또는 POST Form Data 형태의 파라미터를 UserSearch 클래스의 필드들로 매핑해준다.
    • 이렇게 자동으로 매핑되어 반환되는 객체를 커맨드 객체라고 부른다.
  • 매핑 rule? ( 여기서 constructor는 @ConstructorProperties와 무관 )
    • NoArgsConstructor & AllArgsConstructor 둘 다 있는 경우
      • NoArgsConstructor 호출
      • setter 호출해서 param 초기화
    • AllArgsConstructor만 있는 경우
      • AllArgsConstructor 호출해서 param 초기화
      • setter 호출해서 param 초기화 (덮어써짐)
    • 즉, constructor에도 없고 setter도 없는 필드는 초기화되지 않는다.
  • Spring 5.2.4 기준 위와 같이 동작한다.
  • Spring 4.3.4 기준 반드시 NoArgsConstructor와 Setter가 존재해야만 한다. (No default constructor found;라고 에러 발생.)
    • 이런 관점에서도 presentationdto를 반드시 도메인 모델과 분리하는 것이 좋다.

*** ``java @ModelAttribute("query")``와 같이 쓰면 jsp에서 `` query``로 데이터에 접근하도록 지정할 수 있음.

 

@RequestBody

  • 바디를 통해 받은 json 형태의 데이터를, jackson ObjectMapper 사용해서 바로 객체로 매핑해준다. 
    • json 형태의 데이터를 받는 용도이기 때문에, form 요청 (application/x-www-form-urlencoded 형태)은 받을 수 없다.
    • content-type이 form인데 @RequestBody로 받는 경우 415 Unsupported Media Type 발생
  • 매핑 룰은 여기에 [Java] Jackson Serialization  

 

@Valid와 Errors

`` @Valid``를 사용할 때, `` Errors errors``를 파라미터로 받으면 어떤 항목에서 에러가 발생했는지 메서드 내에서 처리할 수 있다.

Valid는 ModelAttribute, RequestBody 모두 동작한다.

 

DTO 생성 시점에 validation

별도 annotation 도움 없이 생성자나 init block 활용한다.

 

@RequestAttribute and @SessionAttribute Annotations

https://www.baeldung.com/whats-new-in-spring-4-3#SessionAttribute

 

 

기타 Controller와 관련된 애너테이션