[SPRING] @RequestParam, @ModelAttribute, @RequestBody

wannabeing·2025년 3월 20일
0

SPARTA-TIL

목록 보기
7/22
post-thumbnail

✅ 클라이언트에서 서버로 데이터를 전달하는 방법은 크게 3가지가 있다.

  1. Query Parameter
  2. HTTP Form Data
  3. HTTP Request Body

1. (GET) 쿼리 파라미터

  • URL로 데이터를 전달하는 방법이다.
  • GET 메소드의 경우, RequestBody에 데이터를 직접 입력하지 않는다.
  • HttpServeletRequest/Response 객체를 사용한다.

@Controller
public class RequestParamController {

    @GetMapping("/request-params")
    public void params(
    	HttpServletRequest request,
        HttpServletResponse response) throws IOException {
															 		
        	String key1Value = request.getParameter("key1");
			String key2Value = request.getParameter("key2");
				
        	response.getWriter().write("success");
    }
}
  • request.getParameter()로 파라미터 값을 사용할 수 있다.
  • reponse.getWriter().write()로 응답데이터를 직접 다룰 수 있다.
  • Response 객체를 사용하므로써, Controller 어노테이션도 데이터를 다룰 수 있다.

2. (POST) HTML 폼

POST /form-data
content-type: application/x-www-form-urlencoded

key1=value1&key2=value2
@Controller
public class RequestParamController {

    @PostMapping("/request-params")
    public void params(
    	HttpServletRequest request,
        HttpServletResponse response) throws IOException {
															 		
        	String key1Value = request.getParameter("key1");
			String key2Value = request.getParameter("key2");
				
        	response.getWriter().write("success");
    }
}
  • POST 메소드를 사용하고, RequestBody에 쿼리파라미터로 전달하는 방법이다.
  • HttpServletRequest.getParameter()를 사용하면,
    모두 데이터 형식(key=value)이 같기 때문에 해당값에 접근할 수 있다.
  • (GET) 쿼리파라미터 형식과 같다!

3. (POST) HTTP Request Body에 직접 데이터 전달

  • HTTP 메소드는 POST, PUT, PATCH를 사용한다.
  • @RestController를 주로 사용하며, JSON형식으로 데이터를 전달한다.

1. 클라이언트 요청 예시 (POST)

  • /request-body URL 요청
  • POST HTTP 메소드 사용
  • Request Body에 JSON 데이터 저장
  • 서버에게 요청 및 응답 받기 ("success")

2. 서버 응답 예시 (POST)

  • 컨트롤러 어노테이션 지정
  • @PostMapping("/request-body")로 매핑
  • HttpServletRequest 객체로 JSON 데이터 받음
  • JSON 데이터를 변환하여 Board 객체를 생성
  • HttpServletResponse 객체를 이용하여 클라이언트에게 응답
// ✅ Board 클래스
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Board {
    private String title;
    private String content;
}
// ✅ Controller 어노테이션
@Controller
public class RequestBodyController {

    // JSON을 객체로 변환해주는 Jackson 라이브러리
    private ObjectMapper objectMapper = new ObjectMapper();
    
    // ✅ "/request-body" URL 요청
	// ✅ POST 요청만 허용
    @PostMapping("/request-body")
    public void requestBody(
            HttpServletRequest request,
            HttpServletResponse response
    ) throws IOException {
		
        // HTTP Request Body로 받은 데이터를 String 변환을 도와주는 변수들
        ServletInputStream inputStream = request.getInputStream();
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
		
        // ✅ JSON으로 클라이언트가 요청한 title, content 값으로 Board 클래스 생성
        Board board = objectMapper.readValue(messageBody, Board.clss);
		
        // ✅ 클라이언트에게 응답
        response.getWriter().write("success");

    }
    
}

1️⃣ 쿼리 파라미터를 더 간단하게 받아보자!

위에서는 HttpServlet객체를 이용해 데이터를 받고, 응답했는데
좀 더 쉽게 받고, 응답해보자.

@RequestParam

// ✅ BEFORE
@Slf4j
@Controller
public class RequestParamController {

    @GetMapping("/request-params")
    public void params(
    	HttpServletRequest request,
        HttpServletResponse response) throws IOException {
															 		
        	String key1Value = request.getParameter("key1");
			int key2Value = request.getParameter("key2");
            
            log.info("name={}", key1);
    		log.info("age={}", key2);
				
        	response.getWriter().write("success");
    }
}
// ✅ AFTER
@Slf4j
@RestController
public class RequestParamController {

    @GetMapping("/request-params")
    public void params(
    	// ✅ @RequestParam 어노테이션 사용
    	@RequestParam String key1,
        @RequestParam int key2
    ) { 		
        	log.info("name={}", key1);
    		log.info("age={}", key2);
				
        	return "success"
    }
}
  • required 속성 (default = True)
    		@RequestParam(required = true) String name, // 필수
    		@RequestParam(required = false) int age	// 필수가 아님
  • default 속성
    파라미터의 기본 값을 설정해준다.
    		@RequestParam(required = true, defaultValue = "unknwon") String name,
    		@RequestParam(required = false, defaultValue = "20") int age	

2️⃣ HTML 폼데이터로 객체를 좀 더 쉽게 생성해보자!

@ModelAttribute

  • 필요한 객체로 바인딩 해준다.
  • HTTP Method POST인 경우 사용된다.
  • 주로 HTML 폼으로 받을 때, 사용한다.
// ✅ 기존 방법
@RestController
public class ModelAttributeController {

  @PostMapping("/tutor")
  public String requestTutor(
          @RequestParam String name,
          @RequestParam int age
  ) {
  	  // ✅ 3줄로 작성 
      Tutor tutor = new Tutor();
      tutor.setName(name);
      tutor.setAge(age);
		
      // 응답
      return "tutor name = " + name
            	+ " age = " + age;
  }
}
// ✅ @ModelAttibute 어노테이션 적용
@RestController
public class ModelAttributeController {

  @PostMapping("/tutor")
  public String requestTutor(
  			// ✅ 한줄로 작성!
  			@ModelAttribute Tutor tutor
  ) {
  		// 응답
        return "tutor name = " + tutor.getName()
	            + " age = " + tutor.getAge();
  }

}

동작순서

  1. @ModelAttribute가 Tutor 객체를 생성한다.
  2. 객체 필드(Tutor)의 Setter를 호출해서 바인딩한다.
    a. 파라미터 이름이 name 이면 setName(value); 메서드를 호출한다.
    b. 파라미터 이름과 필드 이름이 반드시 같아야 한다!

3️⃣ Request Body 데이터를 더 쉽게 다뤄보자!

@Controller
public class RequestBodyStringController {
	
  @ResponseBody
  @PostMapping("request-body-text")
  public String requestBodyText(
          @RequestBody String body,
          @RequestHeader HttpHeaders headers
  ) {
      // HttpMessageConverter가 동작해서 아래 코드가 동작하게됨
      String bodyMessage = body;

      return "request header = " + headers
		      + " response body = " + bodyMessage;
  }
}
  • HTTP Request Body로 데이터가 올 경우, HTTPMessageConverter를 통해 바인딩 된다.
  • @RequestBody
    • Request Body 데이터를 쉽게 조회할 수 있다.
  • @RequestHeader
    • Request Header 데이터 조회
  • @ResponseBody
    • Response Body에 값을 담아서 전달할 수 있도록 해준다.
    • View가 아닌 데이터를 반환한다.

💡 HTTPMessageConverter

  • HTTP 요청과 응답을 변환하는 인터페이스이다.
  • 요청 데이터를 자바 객체로 변환하거나, 자바 객체를 응답 본문으로 변환한다.

JSON 형태의 데이터를 다룰 경우

1) @RequestBody 사용

@RestController
public class JsonController {
	@PostMapping("request-body-json")
    public String requesBodytJson(@RequestBody Tutor tutor) {
	
    	Tutor reqTutor = tutor;

		return "reqTutor.getName() = " + reqTutor.getName() 
        		+ "reqTutor.getAge() = " + reqTutor.getAge();
	} 
}

2) @ModelAttribute 사용

@RestController
public class JsonController {
	@PostMapping("request-body-json")
    // ✅ 어노테이션 생략시, @ModelAttribute 적용
    public String requesBodytJson(Tutor tutor) {

		return "tutor.getName() = " + tutor.getName() 
        		+ "tutor.getAge() = " + tutor.getAge();
	} 
}
  • Header의 contentType은 꼭 application/json이여야 한다.
    위 설정 정보를 기반으로 MessageConverter가 실행된다.

3) @ResponseBody 사용

@Controller
public class JsonController {
	// ✅ Controller + ResponseBody = RestController
	@ResponseBody
	@PostMapping("request-body-json")
    public Tutor requesBodytJson(@RequestBody Tutor tutor) {
		return tutor
	} 
}
  • 객체를 반환할 경우, HttpMessageConverter가 동작한다.
  • MappingJackson2HttpMessageConverter 를 사용하여서,
    응답 객체를 JSON으로 반환한다.

✅ 따라서

  1. QueryParameter, HTTP Form Data에 접근하는 경우
    • @RequestParam, @ModelAttribute 사용
  2. Http Request Body에 접근하는 경우
    • @RequestBody를 사용 (JSON, XML, TEXT)

출처

내일배움캠프 스프링 입문 5주차

profile
wannabe---ing

0개의 댓글