본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Spring framework

Spring RequestBody, RequestParam의 컨트롤러(Controller)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2020. 12. 7.

 

"연동"과 관련된 이슈중 하나는 요청 방법에 따른 데이터 매핑과 관련된 이슈 입니다.
스프링 프레임워크에서 사용 할 수 있는 에노테이션인 @RequestBody, @RequestParam 및 @ModelAttribute등을 사용하면 사용자의 요청 데이터를 쉽게 매핑할 수 있습니다.


대신 이러한 에노테이션을 사용하려면 방법을 정해야 합니다.
헤더에서의 content-type에 따라 json방식, application/x-www-form-urlencoded 방식 및 text/plain방식 등 다양한 방법이 존재하며,
마찬가지로 get과 post에 따라서 요청하는 body가 있을수도 있고 없을 수도 있습니다.

간단한 예로 @RequestBody 에노테이션은 json 형식의 데이터 값만 매핑 할 수 있으며, @RequestParam 은 json형식의 데이터를 매핑 할 수 없습니다.

* 참고 : lts0606.tistory.com/436

 

Spring RequestBody RequestParam(스프링 RequestParam RequestBody)

전자정부 프레임워크나 스프링(Spring) 프레임 워크로 개발을 하다보면 사용자(Client)의 요청을 쉽게 받기위한 방법이 필요 합니다. 일반적으로를 Request객체에서 getAttribute 메소드를 호출하는 방식

lts0606.tistory.com

일반적인 application과 같은 요청 방식에서는 아래처럼 쉽게 요청한 key, value를 가져올 수 있습니다.

    private static Map<Object, Object> getBodyItor(HttpServletRequest webRequest){
        Map<Object, Object> _param = new HashMap<>();
        webRequest.getParameterMap().forEach((key, value)->{  //forEach를 통해서 key와 value를 받습니다.
            if(value != null && value.length > 1) {
                _param.put(key, value);    
            } else {
                _param.put(key, value[0]);
            }
        });
        return _param;
    }    

 

그런데 만약 요청하는 방식이 json이라면 조금 달라집니다.
json방식으로 요청한 경우에는 getParameterMap() 메소드를 호출 하여 보았자 데이터가 존재하지 않습니다.
이럴 때는 request객체에서 getInputStream() 메소드를 호출하여 데이터를 전부 읽은 다음에 json을 파싱하여주면 쉽게 가능 합니다.

    private static Map<Object, Object> getBody(HttpServletRequest request) {
        String body = null;
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            InputStream inputStream = request.getInputStream();  //스트림에서 데이터를 전부 읽습니다.
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException ex) { ex.printStackTrace(); } }
        }
        body = stringBuilder.toString();
        try {
            org.json.simple.parser.JSONParser parser = new org.json.simple.parser.JSONParser();
            org.json.simple.JSONObject jsonObj = (org.json.simple.JSONObject) parser.parse(body);		
            return jsonObj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new HashMap<>();
    } 

 

이렇게 2개의 메소드를 준비하고 나면 컨트롤러에서 할 일은 해당 데이터가 json방식인지 아닌지를 판별 하는 것 입니다.

요청한 헤더에서의 컨텐트(content-type) 타입을 확인하여 위 2개의 메소드를 적절하게 동작하도록 하여 줍니다.

    @RequestMapping(value="/요청")
    @ResponseBody
    public Map<Object, Object> test(HttpServletRequest request){  //HttpServletRequest객체로 받습니다.
        Map<Object, Object> param = null;
        if(request.getHeader("content-type") == null || request.getHeader("content-type").indexOf("json") == -1 ){  //json이 아닌 요청
            param = getBodyItor(request);
        } else if(request.getHeader("content-type").indexOf("json") > -1){  //json 요청
            param = getBody(request);
        } 
        return param;
    }

 

에노테이션 @RequestBody, @RequestParam 등이 없이도 위 방식을 통해서 작업을 하면 사용자가 어떠한 요청을(Multipart제외) 하던지 간에 데이터를 Map형태로 받아서 표현 할 수 있습니다.
패키지(package) 대부분이 Spring과 java에서 제공하는 기본 패키지라 따로 명시하지는 않았습니다.

 

만약 해당 기능을 특정 에노테이션으로 만들고 HandlerMethodArgumentResolver같은 에노테이션 감지용 클래스에 붙여준다면 조금 더 깔끔해지지 않을 까 합니다.


응답 형태에 따른 매핑방법에 대해서 살펴보았습니다!
궁금한 점이나 틀린점은 언제든지 연락주세요. ^^

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글