티스토리 뷰
안녕하세요. 개발개입니다.
이번 글에서는 Spring/SpringBoot로 API 개발 과정에서 오류가 없는 것 같은데
@RequestBody 애노테이션으로 받은 json 데이터가 비어있을 때
확인해 볼 부분을 알아보도록 하겠습니다.
오타, 오류 혹은 기타 의견은 언제든지 환영합니다.
@RequestBody란?
HttpRequestBody를 Java객체로 매핑해주는 애노테이션
즉, 전송받은 JSON 데이터를 객체로 변환해서 받을 수 있습니다.
오류 상황
다음과 같이, JSON 데이터를 BODY에 담아 POST API로 전달할 때, 객체 내 필드 값이 null인 상황
- BODY에 담겨 전달되는 JSON 데이터
{
"PRODUCT_ID" : "0000000063",
"PATENTS" : ["RE027593", "RE027588", "08405470"]
}
- JSON을 담을 ProductDTO 클래스
@Data // getter/setter 등을 자동으로 생성해줌
public class ProductDTO {
private String productId;
private ArrayList<String> patents;
}
- JSON 데이터를 ProductDTO 타입으로 받고, 다시 리턴하는 간단한 Controller
@Slf4j
@RestController
@RequestMapping("/product")
public class ProductController {
@PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity postProduct(@RequestBody ProductDTO productDTO) {
return ResponseEntity.ok().body(productDTO);
}
}
테스트 / 디버깅 과정
위와 같은 전제 상황에서 브라우저 혹은 Postman과 같은 앱을 이용하여 API 테스트를 할 수 있는데
저는 Postman을 사용하도록 하겠습니다.
Header에 Content-Type을 application/json으로 설정하고,
JSON데이터를 Body에 붙여 POST 방식으로 요청(request)합니다.
하지만 JSON데이터와 ProductDTO가 매핑되지 못하고, 필드값이 null인 것을 확인 할 수 있습니다.
수정 내용 / 해결 방법
본 예제에서는 다음 두 가지를 모두 적용해야 원하는 데이터를 리턴받을 수 있다.
- JSON Key를 소문자로 시작하도록 수정하기
- JSON Key에 @JsonProperty 적용하기
수정 전
수정1.
JSON key를 소문자로 시작하도록 수정합니다. (POJO)
{
"product_id" : "0000000063",
"patent" : ["RE027593", "RE027588", "08405470"]
}
여기까지만 수정하면 patents는 매핑이 되지만,
네이밍 룰이 다르기 때문에 product_id와 productId는 매핑되지 않았습니다.
수정2.
Java의 Naming Rule은 camelCase인데, 본 예시처럼 JSON이 다른 규칙을 사용할 경우 (snake_case 등)
혹은 객체에서 다른 이름으로 매핑하고 싶은 경우 (userId -> id 등)
@JsonProperty를 적용합니다.
@Data
public class ProductDTO {
@JsonProperty("product_id")
private String productId;
private ArrayList<String> patents;
}
이제 모든 필드의 값이 잘 받아지는 것을 확인 할 수 있습니다.
# reference
https://ngdeveloper.com/reasons-requestbody-null-issue-spring-boot/
4 reasons for @RequestBody null issue in Spring Boot
1. Make sure you have first letter as lowercase in all your json request & keys This is specific to java POJO behaviours only. Invalid JSON Request: { “CouponId”:18, “StoreNam…
ngdeveloper.com