스프링 MVC 1편 - HTTP 요청 기능

hyuk·2023년 11월 19일
0
post-thumbnail

📌 요청 매핑

@RestController vs @Controller

  • @Controller는 반환 값이 데이터 타입 String ➜ 뷰 이름으로 인식

  • @RestController는 반환 값을 뷰 이름으로 인식 ❌ ➜ 반환 값을 HTTP 메시지 바디에 바로 입력

❗ 따라서 실행 결과의 반환 값을 메세지로 받을 수 있다.

@RequestMapping

  • 대부분의 속성을 배열 [ ] 로 제공하므로 다중 설정이 가능하다.
    - ex) {"/hello-basic", "/hello-go"}

  • method 속성으로 HTTP 메서드를 지정할 수 있다.
    지정하지 않으면 HTTP 메서드와 무관하게 호출
    HTTP 메서드를 축약한 아래와 같은 애노테이션을 사용하는 것이 더 직관적

  1. @GetMapping

  2. @PostMapping

  3. @PutMapping

  4. @DeleteMapping

  5. @PatchMapping

@PathVariable (경로 변수)

최근 HTTP API는 리소스 경로에 식별자를 넣는 스타일을 선호한다

@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {
	log.info("mappingPath userId={}", data);
	return "ok";
}

또한, 변수명이 같을 경우 생략이 가능하다.
ex) @PathVariable("userId") String userId -> @PathVariable userId


📌 HTTP 요청

주로 아래 3가지 방법으로 클라이언트에서 서버로 요청 데이터를 전달한다.

1) GET - 쿼리 파라미터
2) POST - HTML Form
3) HTTP message body

요청 파라미터

-1) HttpServletRequest

GET 쿼리 파리미터 전송 방식이든, POST HTML Form 전송 방식이든 둘다 형식이 같으므로 구분없이조회할 수 있다. 이것을 간단히 요청 파라미터(request parameter) 조회라 한다.

HttpServletRequestrequest.getParameter() 사용하여 요청 파라미터 조회

@RequestMapping("/request-param-v1")
public void requestParamV1(HttpServletRequest req, HttpServletResponse res) 
														throws IOException {
 	String username = req.getParameter("username");
 	int age = Integer.parseInt(req.getParameter("age"));
    
 	log.info("username={}, age={}", username, age);
 	res.getWriter().write("ok");
}

-2) @RequestParam

스프링이 제공하는 @RequestParam을 사용하여 요청 파라미터 조회

@RequestMapping("/request-param-v2")
public String requestParamV2(@RequestParam("username") String memberName,
 							 @RequestParam("age") int memberAge) {
    
 	log.info("username={}, age={}", memberName, memberAge); 
    return "ok";
}

변수명 생략 : HTTP 파라미터 이름과 변수 이름이 같을 경우에 생략 가능
ex) public String v3(@RequestParam String memberName, @RequestParam int memberAge)

추천 ❌
@RequestParam 생략 : String , int , Integer 등의 단순 타입이면 @RequestParam 생략 가능
ex) public String v4(String username, int age)

-3) @ModelAttribute

요청 파라미터를 받아 필요한 객체를 만든 후, 객체에 값을 넣어줘야 하는 과정을 자동화해주는 기능

@ResponseBody
@RequestMapping("/model-attribute-v1")
public String modelAttributeV1(@ModelAttribute HelloData hd) {
 	log.info("username={}, age={}", hd.getUsername(), hd.getAge());
 	return "ok";
}

@ModelAttribute를 생략할 수 있지만, @RequestParam도 생략이 가능하기에 혼동이 생길 수 있다.

따라서 스프링은 해당 생략시 다음과 같은 규칙을 적용한다.
String , int , Integer 같은 단순 타입 = @RequestParam
나머지 = @ModelAttribute (Argument Resolver 로 지정해둔 타입 외)


요청 메시지 - 단순 텍스트

요청 파라미터와 달리 HTTP 메시지 바디를 통해 데이터가 넘어오는 경우는 @RequestParam , @ModelAttribute를 사용할 수 없다.

-1) HttpServletRequest

@PostMapping("/request-body-string-v1")
public void requestBodyString(HttpServletRequest req,
							  HttpServletResponse res) throws IOException {
                                
 	 ServletInputStream inputStream = request.getInputStream();
 	 String messageBody = StreamUtils.copyToString(inputStream,StandardCharsets.UTF_8);
  	 log.info("messageBody={}", messageBody);
	 response.getWriter().write("ok");
 }

-2) Input, Output 스트림

@PostMapping("/request-body-string-v2")
public void requestBodyStringV2(InputStream inputStream, Writer resWriter) 
														throws IOException {
                                                        
	 String messageBody = StreamUtils.copyToString(inputStream,StandardCharsets.UTF_8);
 	 log.info("messageBody={}", messageBody);
 	 resWriter.write("ok");
}

InputStream(Reader) : HTTP 요청 메시지 바디의 내용을 직접 조회
OutputStream(Writer) : HTTP 응답 메시지의 바디에 직접 결과 출력

-3) HttpEntity

@PostMapping("/request-body-string-v3")
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) {
 	String messageBody = httpEntity.getBody();
 	log.info("messageBody={}", messageBody);
	
    return new HttpEntity<>("ok");
}

HttpEntity : HTTP header, body 정보를 편리하게 조회

-4) @RequestBody

@ResponseBody
@PostMapping("/request-body-string-v4")
public String requestBodyStringV4(@RequestBody String messageBody) {
 	log.info("messageBody={}", messageBody);
 	return "ok";
}

@RequestBody를 사용하면 HTTP 메시지 바디 정보를 편리하게 조회할 수 있다.
❗ 참고로 헤더 정보가 필요하다면 HttpEntity 혹은 @RequestHeader를 사용하면 된다.


요청 메시지 - JSON

@ResponseBody
@PostMapping("/request-body-json-v5")
public HelloData requestBodyJsonV5(@RequestBody HelloData data) {
 	log.info("username={}, age={}", data.getUsername(), data.getAge());
 	return data;
}

@ResponseBody 생략 시, @ModelAttribute 적용됨으로 생략 ❌

  • @RequestBody 요청
    JSON 요청 ➜ HTTP 메시지 컨버터 ➜ 객체

  • @ResponseBody 응답
    객체 ➜ HTTP 메시지 컨버터 ➜ JSON 응답


📌 본 포스트는 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 통해 학습한 내용을 요약 및 정리한 것입니다.

profile
차곡차곡쌓아가는학습노트

0개의 댓글