본문 바로가기

Issue

[Java] @RequestBody 로 받은 Jackson 필드명에 대한 고찰

반응형

⌗ 이슈 현상


데이터 필드명을 아래와 같이 되어있어 Controller 에서 RequestBody 어노테이션을 사용해 받고 있던 API 가 있었다..

 

- API에서 Request로 받는 데이터

@Data
public class Data {
	private long aId;
	private List<Long> productNo;
}

 

- API 내용

public void Api (@RequestBody Data) {
	return service(Data);
}

 

대충 이런 방식으로 API가 있었는데, 테스트하는 과정에서 API에 디버깅 걸어 aId 필드의 데이터를 확인하려 하는데,

계속 전달이 되지 않는 현상이 있었다..

 

아니, 이게 무슨일인가 ?

 

늘상 만들던 거라 절때 이상하리 없을 만했는데,

데이터형이 안맞아서 그런건지 아니면 RequestBody 어노테이션이 통신 과정에서 못받아오는 건지, 삽질을 하던 중

이래저래 문서를 찾아보고 나니 알게된 사실 !

 

문제는 Jackson이 Java Bean 이름 지정 규칙을 사용하여 Java 클래스의 Json 속성을 파악하기 때문인 것.

이는 특정 문제로, 권장 사항은 Jackson을 사용하는 데이터 필드명의 처음 두 글자를 대문자로 사용하지 않는 것입니다.

 

즉, 기존 Java 이름의 중간에서 속성 또는 이벤트 이름을 추출하면 일반적으로 첫 번째 문자를 소문자로 변환한다.

그러나 모든 대문자 이름을 가끔씩 사용하기 위해 이름의 처음 두 문자가 모두 대문자인지 확인하고 그대로 두는게 좋다.

 

- JavaBean Naming Rule

8.8 Capitalization of inferred names.
Thus when we extract a property or event name from the middle of an existing Java name, we normally convert the first character to lower case. However to support the occasional use of all upper-case names, we check if the first two characters of the name are both upper case and if so leave it alone. So for example, 

“FooBah” becomes “fooBah” 
“Z” becomes “z” 
“URL” becomes “URL” 

We provide a method Introspector.decapitalize which implements this conversion rule.
Here’s the source code for Introspector.decapitalize(). 

public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))){
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}

The following table shows how the 1st two characters map. If this was a mathematical function, I’d say it wasn’t one-to-one. (‘aa’ and ‘Aa’ imply the same getter)

property  getter 
aa getaa()
aA getaA()
Aa getaa()
AA getAA()

 

⌗ 해결 방법


그렇다고 사용하고 있던 Data 필드명을 바꾸기에 위험 요소가 있다고 생각한다면,

@JsonProperty 어노테이션을 사용해보자 !

 

@Data
public class Data {
	@JsonProperty("aId")
	private long aId;
	private List<Long> productNo;
}

 

이런식으로 사용하게 된다면, 유입되는 파라미터를 확인할 수 있을 것이다 :)

 

 

⌗ 참고


- StackOverflow : stackoverflow.com/questions/30205006/why-does-jackson-2-not-recognize-the-first-capital-letter-if-the-leading-camel-c

 

Why does Jackson 2 not recognize the first capital letter if the leading camel case word is only a single letter long?

I'm using Spring 4 MVC with Jackson 2 for my service. For one of the operations I have a request object that has an attribute where the leading camel case word this is only one letter in length: p...

stackoverflow.com

 

- JavaBean Convention (8.8장 참고) : download.oracle.com/otn-pub/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/beans.101.pdf

 

 

반응형

❥ CHATI Github