TIL/Spring

TIL 2024-11-06 (Spring 입문 - 요청 데이터)

myoma 2024. 11. 6. 21:08

1 ) @RequestBody, @ResponseBody

  • Spring에서 @RequestBody, @ResponseBody 어노테이션을 사용하면 각각 Request, Response 객체의 Body에 편하게 접근하여 사용할 수 있다.

 

  • @RequestBody
    • 요청 메시지 Body Data를 쉽게 조회할 수 있다.
  • @RequestHeader
    • 요청 헤더 정보 조회
  • @ResponseBody
    • 응답 메시지 바디에 쉽게 담아서 전달할 수 있도록 해준다.
    • View가 아닌 데이터를 반환한다.

 

 

  • 요청 파라미터, HTML Form Data에 접근하는 경우
    • @RequestParam, @ModelAttribute
  • Http Message Body에 접근하는 경우
    • @RequestBody를 사용한다.(JSON, XML, TEXT)

 

 


2 ) JSON

  • JSON은 @RestController에서 가장 많이 사용되는 데이터 형식이다.
  • 현재 대부분의 API는 Request, Response 모두 JSON 형태로 통신한다.

 

 

  • HttpServletRequest 사용
    • HttpServletRequest를 사용하여 HTTP Message Body 데이터를 Read하여 문자로 변환한다.
    • 문자로 만들어진 JSON을 Jackson 라이브러리의 objectMapper를 사용하여 Object로 변환
@Data
public class Tutor {
	private String name;
	private int age;
}

@RestController
public class JsonController {
	
	private ObjectMapper objectMapper = new ObjectMapper();

	@PostMapping("/v1/request-body-json")
	public void requestBodyJsonV1(
				HttpServletRequest request, 
				HttpServletResponse response
	) throws IOException {

		// request body message를 Read
		ServletInputStream inputStream = request.getInputStream();
		// UTF-8 형식의 String으로 변환한다.
		String requestBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

		// String requestBody를 ObjectMapper를 사용하여 변환 "{\"name\":\"wonuk\", \"age\":10}"
		Tutor tutor = objectMapper.readValue(requestBody, Tutor.class);
		
		// 응답
		response.getWriter().write("tutor" + tutor);
	}
}

 

 

  • @RequestBody
    • @RequestBody를 사용하여 HTTP Request Body의 Data에 접근한다.
@RestController
public class JsonController {
	
	private ObjectMapper objectMapper = new ObjectMapper();

	@PostMapping("/v2/request-body-json")
  public String requesBodytJsonV2(@RequestBody String requestBody) throws IOException {

      Tutor tutor = objectMapper.readValue(requestBody, Tutor.class);

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

 

 

  • ObjectMapper 제거
@RestController
public class JsonController {
	
	@PostMapping("/v3/request-body-json")
	public String requestBodyJsonV3(@RequestBody Tutor tutor) {
		
		Tutor requestBodyTutor = tutor;

		return "tutor = " + requestBodyTutor;
	}
}
  • 작동하는 이유?
    • @RequestBody 어노테이션을 사용하면 Object를 Mapping 할 수 있다.
    • HttpEntity<>, @RequestBody 를 사용하면 HTTPMessageConverter가 RequestBody의 Data를 개발자가 원하는 Spring이나 Object로 변환해준다.
    • 쉽게 설명하면 HTTP Message Converter가 ObjectMapper를 대신 실행한다.

 

 

  • @RequestBody는 생략할 수 없다.
    • @RequestRaram, @ModelAttribute는 생략 가능
    • 생략하는 @ModelAttribute가 된다.
      • 요청 파라미터를 처리하도록 설정된다.
    • Request Header의 contentType은 꼭 application/json 이여야한다.
      • 위 설정 정보를 기반으로 MessageConverter가 실행된다.
@Slf4j
@RestController
public class JsonController {
	
	@PostMapping("/v4/request-body-json")
  public String requestBodyJsonV4(Tutor tutor) { // @RequestBody 생략시 @ModelAttribute가 된다.

      Tutor requestBodyTutor = tutor;

      return "tutor.getName() = " + requestBodyTutor.getName() + " tutor.getAge() = " + requestBodyTutor.getAge();
  }
	
}

 

  • HttpEntity 사용
    • HttpEntity<Tutor>
      • Generic Type으로 Tutor가 지정되어 있기 때문에 해당 Class로 반환한다.
@RestController
public class JsonController {
	
	@PostMapping("/v5/request-body-json")
  public String requestBodyJsonV5(
          HttpEntity<Tutor> httpEntity
  ) {
      // 값을 꺼내서 사용해야한다!
      Tutor tutor = httpEntity.getBody();

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

 

 

  • ResponseBody
    • View를 조회하지 않고 Response Body에 Data를 입력해서 직접 반환한다.
    • 요청 뿐만이 아니라 응답에도 HttpMessageConverter가 동작한다.
      • Maapingjackson2HttpMessageConverter 적용
      • 응답 객체인 Tutor가 JSON으로 변환되어 반환된다.
    • HttpEntity를 사용해도 된다.
@Controller
public class JsonController {
	
	@ResponseBody // @RestController = @Controller + @ResponseBody
	@PostMapping("/v6/request-body-json")
    public Tutor requestJson(@RequestBody Tutor tutor) {
        return tutor;
  }
	
}