새로운 프로젝트를 받으면서, 레거시 코드로 인해 발생한 간단한 해프닝을 공유하려고 한다. 레거시 코드라 PUT method에서 RequestParam으로 데이터를 받는 케이스가 있었다..!
문제 상황
- UDC에서 POST , PUT method에서 body로 보내지 않고, RequestParam 으로 데이터를 보냄
- 프론트 요청으로 queryParam에 Boolean? 값을 추가함
@PutMapping fun update( @RequestParam(required = false) name: String?, @RequestParam(required = false) isEnabled: Boolean?, ) - 프론트에서 “null” 을 넣어서 보내니 400에러가 발생한다고 문의가 들어옴. 값을 넣지 않으면 정상 동작(null로 들어감)
- 뿐만 아니라 string value에 null을 집어 넣으면 "null" 로 들어가서 db까지 null string으로 저장되는 문제 발생
원인 파악
- string value (”null”)을 boolean으로 converting하지 못하는 것으로 예상
- spring의 @RequestParam 에서 사용하는 converter 확인
- StringToBooleanConverter 코드
final class StringToBooleanConverter implements Converter<String, Boolean> { private static final Set<String> trueValues = new HashSet<>(8); private static final Set<String> falseValues = new HashSet<>(8); static { trueValues.add("true"); trueValues.add("on"); trueValues.add("yes"); trueValues.add("1"); falseValues.add("false"); falseValues.add("off"); falseValues.add("no"); falseValues.add("0"); } @Override @Nullable public Boolean convert(String source) { String value = source.trim(); if (value.isEmpty()) { return null; } value = value.toLowerCase(); if (trueValues.contains(value)) { return Boolean.TRUE; } else if (falseValues.contains(value)) { return Boolean.FALSE; } else { throw new IllegalArgumentException("Invalid boolean value '" + source + "'"); } } }
- StringToBooleanConverter 코드
- 코드를 보면, string "null" 값에 대한 처리는 없음
- spring의 @RequestParam 에서 사용하는 converter 확인
- string의 경우에는 별도의 convert 없이 받는 데이터 그대로 string으로 넘겨줌
- @RequestBody 의 경우 jackson converter로 json 객체를 parsing하고, json 객체에는 null과 "null" 을 구분할 수 있기 때문에 큰 문제가 없었음
해결 방법
- 별도의 converter 등록하기
위 converter에서 null string 체크 로직을 추가한 custom converter를 등록하면 된다. 그러나 requestParam은 url에서 파싱한 string 값이고, 이미 요청할 때 string 값을 넣은 것이기 때문에 null 변환이 있는게 더 어색해 보인다. - RequestParam → RequestBody 변환하기
PUT 요청에서는 requestBody를 쓰는게 일반적이기 때문에 더 자연스러워 보인다.
레거시 코드라서 볼 수 있었던 일종의 해프닝이다. 이 계기로 여러 converter들의 코드를 확인해보고, query string을 파싱방법을 리마인드 할 수 있어서 재밌었다.
'Spring' 카테고리의 다른 글
| FilterChain을 2번 호출한다고? (1) | 2024.09.14 |
|---|---|
| PermitAll의 함정 (0) | 2024.08.16 |
| 테스트 환경 설정하기 (1) | 2024.08.08 |