[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 |
---|