@RestController
vs @Controller
@Controller
는 반환 값이 데이터 타입 String
➜ 뷰 이름으로 인식
@RestController
는 반환 값을 뷰 이름으로 인식 ❌ ➜ 반환 값을 HTTP 메시지 바디에 바로 입력
❗ 따라서 실행 결과의 반환 값을 메세지로 받을 수 있다.
@RequestMapping
대부분의 속성을 배열 [ ]
로 제공하므로 다중 설정이 가능하다.
- ex) {"/hello-basic", "/hello-go"}
method 속성으로 HTTP 메서드를 지정할 수 있다.
지정하지 않으면 HTTP 메서드와 무관하게 호출
HTTP 메서드를 축약한 아래와 같은 애노테이션을 사용하는 것이 더 직관적
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@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
주로 아래 3가지 방법으로 클라이언트에서 서버로 요청 데이터를 전달한다.
1) GET - 쿼리 파라미터
2) POST - HTML Form
3) HTTP message body
GET 쿼리 파리미터 전송 방식이든, POST HTML Form 전송 방식이든 둘다 형식이 같으므로 구분없이조회할 수 있다. 이것을 간단히 요청 파라미터(request parameter) 조회라 한다.
HttpServletRequest
의 request.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");
}
@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)
요청 파라미터를 받아 필요한 객체를 만든 후, 객체에 값을 넣어줘야 하는 과정을 자동화해주는 기능
@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
를 사용할 수 없다.
@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");
}
@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 응답 메시지의 바디에 직접 결과 출력
@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 정보를 편리하게 조회
@ResponseBody
@PostMapping("/request-body-string-v4")
public String requestBodyStringV4(@RequestBody String messageBody) {
log.info("messageBody={}", messageBody);
return "ok";
}
@RequestBody
를 사용하면 HTTP 메시지 바디 정보를 편리하게 조회할 수 있다.
❗ 참고로 헤더 정보가 필요하다면HttpEntity
혹은@RequestHeader
를 사용하면 된다.
@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편 - 백엔드 웹 개발 핵심 기술 통해 학습한 내용을 요약 및 정리한 것입니다.