들어가기 전

해결방법은 lombok 라이브러리를 사용하여 해결하는 과정을 써 내려갈 것입니다.

@ModelAttribute

@ModelAttribute가 무엇인지는 간략하게 설명하겠습니다.
@ModelAttribute는 @RequestParam처럼 파라미터로 값을 바인딩하는 것인데  @RequestParam은 하나의 대한 파라미터이고 @ModelAttribute는 여러 개의 값을 객체에 정의하고 파라미터의 값을 여러 개를 받을 때 사용합니다.
그리고 사용을 할 때 @RequestParam과 @ModelAttribute는 생략이 가능합니다.

 

만약 아래와 같이 코드를 작성하여 @ModelAttribute를 사용하면 어떻게 될까요?

 

 

Controller 코드

 

@RestController
public class TestController {


    @GetMapping("/test")
    public TestDto modelAttributea(@ModelAttribute TestDto testDto) {
        return testDto;
    }
}

 

 

DTO 클래스

 

@NoArgsConstructor
@AllArgsConstructor
public class TestDto {

    private String name;

    private int age;

}

 

  • @NoArgsConstructor : 빈 생성자 생성
  • @AllArgsConstructor : 클래스에 정의된 필드를 다 가진 생성자 생성

 

위와 같이 @NoArgsConstructor, @AllArgsConstructor만 하고 클라이언트로부터 요청이 오면 어떤 결과를 리턴할까요?

 

 

 

결과는 406 에러가 발생하게 됩니다.

 

그럼 406 에러가 발생하지 않게 하려면 어떻게 해야 될까요?

 

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class TestDto {

    private String name;

    private int age;

}

 

@Getter를 추가시켜주면 406 에러를 피할 수 있습니다. 그리고 추가를 해주고 난 뒤의 결과는 어떻게 될까요?

 

 

 

@Getter을 사용하여 406 에러는 해결하였으나 값을 넣어도 값이 들어오지 않습니다.

 

 

여기서 잠깐!
@AllArgsConstructor이 객체가 정의한 모든 변수를 담은 생성자를 생성해준다고 위에서 설명드렸습니다.
그런데 파라미터로 작성한 name, age가 name과 age를 매개변수로 가진 생성자에 자동적으로 바인딩되어야 되는 게 아닌가?라고 필자는 생각했습니다.
그런데 해본 결과는 위에 결과와 같이 모든 값이 null 또는 0으로 들어옵니다.
그래서 여러가지를 시도 해본 결과 아래와 같은 해결방법을 찾을 수 있었습니다.

해결 방법
@NoArgsConstructor 삭제
or
@Setter 추가

해결방법 2개 중 하나로 하시면 값이 잘 들어오시는 것을 확인하실 수 있습니다.

 

즉! @ModelAttribute를 사용하여 값이 Null이 아닌 입력한 값을 받고 싶으면 @NoArgsConstructor이 있을 시 제거를 하고 @AllArgsConstructor를 붙여주거나 @NoArgsConstructor를 제거하지 않고 @Setter을 작성해주면 해결됩니다.