[springBoot]_resolveArgument 파라미터 커스텀

2023. 7. 11. 14:45[SpringBoot]_

728x90
반응형

개요

SpringBoot 에서 resolveArgument 를 상속받아

커스텀 Map 을 파라미터로 받고 로직을 추가하는 방법 서술

 

환경 

툴 : Intellij

빌더 :gradle 

버전 관리

  • springboot 2.7.3v
  • java 11v

목표 : ParamMap 이라는 형식을 지정하고, 원하는대로 핸들링 한 후 커스텀Map을 Controller 에서 사용할수 있게 한다.

화면에서 발송하는 값:

컨트롤러에서 받아서 사용할 ParamMap 의 데이터:

그리드 페이징 처리를 위해 start 와 end 로 분기하여 자동 key와 값이 들어가도록 만들 예정입니다.


1. CustomMap 선언

Map 을 상속받지 않는 커스텀 map 을 선언할 class를 생성한다

Map을 상속받게 되면 resolveArgument 에 해당하지 않기 때문이다.

public class ParamMap {
    Map<Object, Object> map = new HashMap<Object, Object>();

    public Object get(String key){
        return map.get(key);
    }

    public void put(String key, Object value){
        map.put(key, value);
    }

    public String toString(){
        return map.toString();
    }



}

2. CustomArgumentResolver.java 생성

public class CustomArgumentResolver implements HandlerMethodArgumentResolver {

    @Override // 받아온 파라미터가 Class로 지정한 값과 같은 타입인지 먼저 Check함
    public boolean supportsParameter(MethodParameter parameter) {
        return ParamMap.class.isAssignableFrom(parameter.getParameterType());
    }

    @Override // 체크에 성공하면 해당 함수로 진입하여 객체 핸들링
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {


        HttpServletRequest httpServletRequest = webRequest.getNativeRequest(HttpServletRequest.class);

        ParamMap collector = new ParamMap();


        try {

            String body = readBody(httpServletRequest);
            System.out.println(body);

            //String 으로 바꾼 body부를 JSON형태로 변환하여 사용
            org.json.simple.parser.JSONParser parser = new org.json.simple.parser.JSONParser();
            Object obj = parser.parse(body);


            JSONObject jsonObj = (JSONObject) obj;

            JSONObject json1 = (JSONObject) jsonObj.get("parameters");

            json1.keySet().forEach(key -> {

                System.out.println(key);
                collector.put(key.toString(), json1.get(key));

            });

            JSONObject json2 = null;

            // datasets 는 없이 보낼 수도 있다.
            if (jsonObj.containsKey("datasets")) {
                json2 = (JSONObject) jsonObj.get("datasets");

                Integer currentPage = Integer.parseInt(json2.get("currentPage").toString());
                Integer viewCount = Integer.parseInt(json2.get("viewCount").toString());

                int start = (currentPage - 1) * viewCount;
                int end = (viewCount * currentPage) - 1;

                collector.put("start", start);
                collector.put("end", end);
            }

            return collector;

        } catch (NullPointerException e) {
            return collector;
        }


    }


    //body 읽는 메소드
    public static String readBody(HttpServletRequest request) throws IOException {
        BufferedReader input = new BufferedReader(new InputStreamReader(request.getInputStream()));
        StringBuilder builder = new StringBuilder();
        String buffer;
        while ((buffer = input.readLine()) != null) {
            if (builder.length() > 0) {
                builder.append("\n");
            }
            builder.append(buffer);
        }
        return builder.toString();
    }


}

 

import org.springframework.web.method.support.HandlerMethodArgumentResolver;

를 상속받아

 

supportsParameter 메소드와

resolveArgument 메소드를 구현한다.

 

supportsParameter 의 경우 1번에서 지정한 ParamMap의 값과 같은 타입인지 먼저 체크하게 된다.

그 뒤에

resolveArgument 에 진입한다.

 

구현체에서는 jsonObj 을 읽어서 공통으로 지정한 값을 기준으로 파싱하고. 페이징 계산을 한뒤

하나의 Map으로 만들어서 반환한다.

 

이렇게 되면 Controller 에서는 ParamMap 만 받아서 사용하면 된다.


3. 빈등록

WebMvcConfigurer 을 상속받은 webConfig.java 가 있을것이다.

//CustomArgumentResolver (공통 paramMap) 빈 등록
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers){
    resolvers.add(customArgumentResolver());
}

//CustomArgumentResolver (공통 paramMap) 빈 등록
@Bean
public CustomArgumentResolver customArgumentResolver(){
    return new CustomArgumentResolver();
}

해당 클래스에 빈을 등록한다.

 

 

감사합니다.

 

728x90
반응형

'[SpringBoot]_' 카테고리의 다른 글

[IntelliJ]_Spring boot profiles 설정 (feat . gradle)  (0) 2023.06.21