ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Boot] List의 null 값 처리하기1 - CustomConverter로 @RequestParam
    Backend/개발 2022. 4. 7. 17:18
    반응형

    요청이 컨트롤러에게 전해질 때 HandlerAdapter -> ArgumentResolver -> Handler(Controller)로 전해지는데
    이때 ArgumentResolver에서 Converter를 사용해서 값을 변경한다.

    @RequestParam으로 값을 받아올 때 ", "로 구분하면 List로 받아와 지는 것도 StringToCollectionConverter에서 변환이 이뤄지기 때문이다.

        public ResponseEntity<GameRecordResponseDto> result(
                @RequestParam(required = false) List<String> searchNames,
                @RequestParam(required = false) List<GameTypeCode> gameTypes) {
    
            // 빈 값 들어올 경우
            if (searchNames != null) {
                searchNames = searchNames.stream()
                        .filter(sn -> sn != null && !sn.equals(""))
                        .collect(Collectors.toList());
                if (searchNames.size() == 0) searchNames = null;
            }
            if (gameTypes != null) {
                gameTypes = gameTypes.stream()
                        .filter(gt -> gt != null && !gt.equals(""))
                        .collect(Collectors.toList());
                if (gameTypes.size() == 0) gameTypes = null;
            }
    
            if (searchNames != null && gameTypes != null) {
             } else if (searchNames != null && gameTypes == null) {
            } else if (searchNames == null && gameTypes != null) {
            }
    }

    List <String>, List <GameTypeCode>로 받아오는 파라미터가 있는데 만약에 클라이언트 쪽에서 실수로 "name1,, name2"로 보내버리면 중간에 null인 값이 리스트에 추가돼버려서 이걸 제거하는 처리를 컨트롤러 코드마다 해줬는데 컨버터를 이용해서 일괄적으로 처리할 수 있는 방법을 찾아봤다.

    @Component
    public class StringToListConverter implements Converter<String, List<?>> {
        @Override
        public List<?> convert(String source) {
    
            List<?> list = Arrays.asList(source.split(",")).stream()
                    .filter(sn -> sn != null && !sn.equals(""))
                    .collect(Collectors.toList());
    
            return list.size()==0 ? null : list;
        }
    }

     

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void addFormatters(FormatterRegistry registry) {
            registry.addConverter(new StringToListConverter());
        }
    }

    이렇게 Converter를 구현해서 설정해주면 된다!
    ",,,," 로 입력하면 List <String>에 null이 5개 들어가는 게 아니고 null이 반환되도록 해주었다.



    근데 그냥 빈 값을 같은 이름으로 여러번 담아서 요청 보내게 되면 이거는 또 ArrayToListConverter와 같은 형식으로 구현해줘야 한다,,

    public class ArrayToListConverter implements Converter<String[] , List<Long>> {
        @Override
        public List<Long> convert(String[] source) {
            if(source == null || source.length ==0 ) return null;
            List<Long> list = new ArrayList<>();
            for(int i=0; i<source.length; i++){
                if(source[i].isEmpty() || source[i]==null) continue;
                list.add(Long.valueOf(source[i]));
            }
            return list.isEmpty() ? null : list;
        }
    }

    이렇게 하는 건 뭔가 이 정도까지 추가할 건 아닌 것 같아서 @RequestParam List <@NotBlank String> 정도의 처리를 해주어야겠다.
    지금 하려는 처리는 빈 값이 들어오는 걸 무시하도록 하는 목적이어서 converter를 사용해봤는데 List로 된 값에 대해 검증이 필요하다면 커스텀 validator를 만들어서 (Collection Validation 검색) 처리해도 좋을 것 같다.

    추가) Enum에 올바른 값이 입력으로 왔는지는 List에 담아버리면 검증이 안돼서 다른 처리를 해줘야 할 것 같다..

     

    Is it possible to split request params in Spring controllers?

    I have a request like: example.com/search?sort=myfield1,-myfield2,myfield3 I would like to split those params to bind a List<String> sort in my controller or List<SortParam> where Sor...

    stackoverflow.com

    댓글

Designed by Tistory.