Spring - 컨트롤러에 POST mapping url이 정확한데도 404 에러가 뜨는 이유 - Java Reflection

@RequestMapping(value = "getServerResourceCountDateType.do", method = RequestMethod.POST)
public ModelAndView ServerResourceCountDateType(ServerResourceInfoDTO dto, Authentication authentication) 
{
 //TODO
}

 

컨트롤러에 이러한 형식의 POST mapping url 메소드가 있다고 해보자.

view단에서 정확하게 해당 url로 post요청을 보내도 404 status code를 내뿜으며

함수 호출 자체가 안되는 경우가 있다.

 

왜그럴까?

 

혹시 Mapping되는 객체의 기본 생성자가 없다면 그럴 수 있다.

 

 

그것은 바로 Java라는 언어는 Java Reflection이라는 개념이 존재하기 때문이다.

우리가 보통 DTO 클래스를 만들때 기본생성자도 같이 만들어주는데

그 이유가 바로 객체가 생성만 된다면 이 Reflection API가 필드들을 알아서 매칭시켜주기 때문이다.

 

Java Reflection?

 Reflection 이란?
구체적인 클래스 타입을 알지 못해도, 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API

자바에서 제공하는 리플렉션(Reflection)은 C, C++과 같은 언어를 비롯한 다른 언어에서는 볼 수 없는 기능이다. 이미 로딩이 완료된 클래스에서 또 다른 클래스를 동적으로 로딩(Dynamic Loading)하여 생성자(Constructor), 멤버 필드(Member Variables) 그리고 멤버 메서드(Member Method) 등을 사용할 수 있도록 한다.

java Reflection이 가져올 수 없는 정보 중 하나가 바로 생성자의 인자 정보들이다. 따라서 기본 생성자 없이 파라미터가 있는 생성자만 존재한다면 java Reflection이 객체를 생성할 수 없게 되는 것이다.

이글에서 404가 일어난 이유를 알고자할 때 Reflection API에서 기억해야할 특징은 바로

Reflection API가 가져올 수 없는 정보 중 하나가 생성자의 인자 정보라는 점이다.

 

기본 생성자 없이 파라미터가 있는 생성자만 존재한다면 java Reflection이 객체를 생성할 수 없게 되는 것이다.

그래서 DTO클래스를 작성할 때 대부분 기본 생성자를 선언하는 것이다.

 

따라서 위 상황은 오버라이딩한 생성자 함수의 파라미터에 알맞게 post요청을 보내서

DTO 객체가 생성될 수 있는 상황도 아니였고!

 

기본 생성자마저 없어서 Java Reflection API가 객체를 생성해주지도 못해서 

아예 ServerResourceDTO 객체가 생성이 안되니 해당 post 요청을 처리하는 메소드인

ServerResourceCountDateType 메소드를 호출을 못하게 되는 상황인 것이다.

 

추가적으로 Java Reflection API가 정말 유용한 녀석인게 이렇게 기본생성자만 있다면

 Reflection API가 필드들을 알아서 매칭시켜주고 이렇게 알아서 필드들을 매칭시켜주기 때문에

Jackson의 ObjectMapper를 이용해서 post요청의  JSON 데이터 타입이  오브젝트 즉, DTO 객체로 변환이

가능하게 되는 것이다.