백엔드/spring boot

[Spring Boot] @RequestParam & @RequestBody

STUFIT 2023. 9. 18. 11:30
반응형

리퀘스트에서는 @RequestBdoy, @RequestParam 으로 리퀘스트 전달값을 받는 어노테이션이 존재한다.

해당 어노테이션은 서블렛과 유사하지만 더 편의성의 증대된 어노테이션으로 아래에서 설명하고자 한다.

1. @RequestParam

  • 보통 @RequestMapping은 클래스 위에 붙여서 기본적인 엔드포인트를 지정하는데, 아래의 예제에서는 각각의 엔드포인트를 설정하도록 메서드 위에 붙여놓았다.
package hello.springmvc.basic.request;

import hello.springmvc.basic.HelloData;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Map;

// 로그 생성(log.info, log.warn 등...)
@Slf4j
// 이 부분은 @RestController 로 변경하면 컨트롤러에 @ResponseBody 등을 안붙여도 된다.
@Controller 
public class RequestParamController {


		// 1. 서블렛으로 파람형식으로 받는 경우
    @RequestMapping("/request-param-v1")
    public void requestParamV1(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String username = request.getParameter("username");
        int age = Integer.parseInt(request.getParameter("age"));
        log.info("username = {}, age = {}", username, age);
        response.getWriter().write("ok");
    }

		// 2. @requestParam 으로 파람을 받는 경우
		// 1) 결과값을 @ResponseBody를 붙여야 해당
    @ResponseBody
    @RequestMapping("/request-param-v2")
    public String requestParamV2(@RequestParam("username") String memberNm,
                                 @RequestParam("age") int memberAge) {
        log.info("username = {}, age = {}", memberNm, memberAge);
        return "ok";
    }

    /**
     * @RequestParam에서 () 생략 가능 =>파라미터명과 변수명이 같으면 생략 가능
     * @param username
     * @param age
     * @return
     */
    @ResponseBody
    @RequestMapping("/request-param-v3")
    public String requestParamV3(@RequestParam String username,
                                 @RequestParam int age) {
        log.info("username = {}, age = {}", username, age);
        return "ok";
    }

    /**
     * @RequestParam 생략 가능 => String, int, Integer 같은 단순 타입이면 @RequestParam도 생략 가능
     * @param username
     * @param age
     * @return
     */
    @ResponseBody
    @RequestMapping("/request-param-v4")
    public String requestParamV4(String username,
                                  int age) {
        log.info("username = {}, age = {}", username, age);
        return "ok";
    }

    /**
     * @RequestParam.required => 필수 파라미터
     * Integer 는 null 들어가도 되서 Integer로 바꿔준다.
     * @param username
     * @param age
     * @return
     */
    @ResponseBody
    @RequestMapping("/request-param-required")
    public String requestParamRequired( @RequestParam(required = true) String username,
                                        @RequestParam(required = false) Integer age
                                        ) {
        log.info("username = {}, age = {}", username, age);
        return "ok";
    }

    @ResponseBody
    @RequestMapping("/request-param-default")
    public String requestParamDefault( @RequestParam(defaultValue = "guest") String username,
                                        @RequestParam(defaultValue = "-1") int age
    ) {
        log.info("username = {}, age = {}", username, age);
        return "ok";
    }

    /**
     * @RequestParam Map => 파라미터를 Map으로 조회
     * @param paramMap
     * @return
     */
    @ResponseBody
    @RequestMapping("/request-param-map")
    public String requestParamMap(@RequestParam Map<String, Object> paramMap
                                  ) {
        log.info("username = {}, age = {}", paramMap.get("username"), paramMap.get("age"));
        return "ok";
    }

    @ResponseBody
    @GetMapping("/model-attribute-v1")
    public String modelAttributeV1(@RequestParam String username,
                                   @RequestParam int age){
        HelloData helloData = new HelloData();
        helloData.setUsername(username);
        helloData.setAge(age);
        log.info("username = {}, age = {}", helloData.getUsername(), helloData.getAge());
        log.info("helloData = {}", helloData);
        return "ok";
    }

    @ResponseBody
    @GetMapping("/model-attribute-v2")
    public String modelAttributeV2(@ModelAttribute HelloData helloData){
        log.info("username = {}, age = {}", helloData.getUsername(), helloData.getAge());
        log.info("helloData = {}", helloData);
        return "ok";
    }

    @ResponseBody
    @GetMapping("/model-attribute-v3")
    public String modelAttributeV3(HelloData helloData){
        log.info("username = {}, age = {}", helloData.getUsername(), helloData.getAge());
        log.info("helloData = {}", helloData);
        return "ok";
    }

}

2. @RequestBody

package hello.springmvc.basic.request;


import com.fasterxml.jackson.databind.ObjectMapper;
import hello.springmvc.basic.HelloData;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

@Slf4j
@Controller
public class RequestBodyJson {

    private ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 서블렛을 사용한 리퀘스트를 바디로 받을때 형식
     * @param request
     * @param response
     * @throws IOException
     */
    @PostMapping("/request-body-json-v1")
    public void requestBodyJsonV1(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
        log.info("messageBody = {}", messageBody);
        HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
        log.info("username = {}, age = {}", helloData.getUsername(), helloData.getAge());
        response.getWriter().write("ok");
    }

    /**
     * @RequestBody를 사용한 리퀘스트 바디를 받을때 형식
     * @ResponseBody를 사용한 리스폰스 바디를 보낼때 형식
     * @param messageBody
     * @return
     * @throws IOException
     */
    @ResponseBody
    @PostMapping("/request-body-json-v2")
    public String requestBodyJsonV2(@RequestBody String messageBody) throws IOException{
        log.info("messageBody = {}", messageBody);
        HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
        log.info("username = {}, age = {}", helloData.getUsername(), helloData.getAge());
        return "ok";
    }

    /**
     * @RequestBody를 사용한 리퀘스트 바디를 받을때 형식
     * 이 때, HelloData(인터페이스) 자체로 받을 수 있음.
     * @param messageBody
     * @return
     */
    @ResponseBody
    @PostMapping("/request-body-json-v3")
    public String requestBodyJsonV3(@RequestBody HelloData messageBody)  {
        log.info("messageBody = {}", messageBody);
        return "ok";
    }

    @ResponseBody
    @PostMapping("/request-body-json-v4")
    public String requestBodyJsonV4(HttpEntity<HelloData> httpEntity)  {
        HelloData data = httpEntity.getBody();
        log.info("username = {}, age={}", data.getUsername(), data.getAge());
        return "ok";
    }

    /**
     * @RequestBody를 사용한 리퀘스트 바디를 받을때 형식
     * return 값으로 HelloData(인터페이스)를 사용할 수 있음.
     * @param messageBody
     * @return
     */
    @ResponseBody
    @PostMapping("/request-body-json-v5")
    public HelloData requestBodyJsonV5(@RequestBody HelloData messageBody)  {
        log.info("messageBody = {}", messageBody);
        return messageBody;
    }
}
반응형