1. @RestController Annotation활용
@Controller와 다른 점?
@Controller는 반환 값이 String이면 뷰 이름으로 인식하고 뷰로 렌더링!
반면, @RestController는 반환 값으로 HTTP MESSAGE BODY에 바로 입력
2. @RequestMapping및 @GetMapping의 활용방법에 대하여 알아봅니다 :)
1. 간단한 요청 매핑
@RequestMapping에 HTTP Method(GET,HEAD,POST,PUT,PATCH,DELETE)등을 직접 명시하여 주는 것을 의미합니다.
ex)
@RequestMapping(value = "/mapping-get-method", method = RequestMethod.GET)
public String mappingGetMehod() {
return "ok";
}
method를 직접 명시하는 것이 아닌 @RequestMapping을 @GetMapping,@PostMapping등으로 축약하는 것을 의미합니다.
ex)
@GetMapping(value = "/mapping-get")
public String mappingGet() {
return "ok";
}
1번에서의 두 가지 방식은 value도 함축해서 사용할 수 있습니다.
ex)
@RequestMapping( "/mapping-get-method", method = RequestMethod.GET)
public String mappingGetMehod() {
return "ok";
}
@GetMapping( "/mapping-get")
public String mappingGet() {
return "ok";
}
스프링에서 value를 자동으로 인식하게 됩니다.
경로 변수를 사용하는 것입니다. url에 /{userId}처럼 {}된 부분을 매핑하여 자바에서 사용할 수 있습니다.
ex)
@GetMapping("/mapping-get/{userId}")
public String mappingGet(@PathVariable("userId") String data) {
log.info(userId);
return "ok";
}
@PathVariable이름과 파라미터의 이름이 같으면 생략할 수 있습니다.
ex)
@GetMapping("/mapping-get/{userId}")
public String mappingGet(@PathVariable String userId) {
log.info(userId);
return "ok";
}
특정 파라미터의 조건에 맞을 경우에만 매핑 됩니다.
ex)
@GetMapping("/mapping-get-param",params="status=ok")
public String mappingGetParam() {
return "ok";
}
http://localhost:8080/mapping-get-param?status=ok 이런 식으로 와야 합니다.
Client의 요청의 Content-Type헤더를 기반으로 미디어 타입을 매핑할 수 있습니다.
ex)
@GetMapping("/mapping-get-consume",consumes="text/html")
public String mappingGetCosume() {
return "ok";
}
@GetMapping("/mapping-get-produce",produces="text/html")
public String mappingGetProduce() {
return "ok";
}
consumes은 즉 request가 어떤 형식으로 와야한다는 것을 의미하고 produces는 즉 client가 어떤 형식을 accept가능한지를 의미 합니다.
스프링 기술 없이 단순히 자바 servlet이 제공하는 기능을 사용
ex)
@RequestMapping("/request-param-servlet")
public void requestParamServlet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
response.getWriter().write("ok");
}
스프링이 제공하는 기술. 요청 받은 파라미터를 바로 매핑할 수 있음
ex)
@RequestMapping("/request-param")
public String requestParam(@RequestParam("username") String username) {
log.info(username);
return "ok";
}
만일 요청 파라미터와 파라미터 이름이 같으면 요청 파라미터의 이름을 생략 가능
ex)
@RequestMapping("/request-param")
public String requestParam(@RequestParam String username) {
log.info(username);
return "ok";
}
String,int,Integer의 단순 타입 같은 경우는 @RequestParam도 생략 가능하다고 합니다^^
@RequestParam(required=True)와 같은 기능도 사용 가능합니다. 즉 저렇게 설정된 요청 파라미터는 필수로 들어와야한다는 것을 의미 합니다.
ex)
@RequestMapping("/request-param")
public String requestParam(@RequestParam(required=true) String username) {
log.info(username);
return "ok";
}
즉 username 파라미터가 필수적으로 들어와야한다는 것을 의미 합니다.
주의 사항. 만일,/request-param?username= 이런식으로 파라미터 이름만 있고 값이 없는 경우는
String일 경우에는 빈문자로 통과 됩니다. 하지만, int와 같은 기본형에는 null이 입력되므로 예외가 발생 하게 되죠 따라서, int형을 null도 받을 수 있는 Integer객체로 변경하거나, defaultValue를 설정해놔야 합니다.
ex)
@RequestMapping("/request-param")
public String requestParam(@RequestParam(required=true,defaultValue="-1") int age) {
log.info(age);
return "ok";
}
파라미터를 Map으로도 조회 가능 합니다
ex)
@RequestMapping("/request-param")
public String requestParam(@RequestParam Map(String,Object> param) {
log.info(param.get("age"));
return "ok";
}
@RequestParam을 주구장창 사용하기에는 역시 번거로움이 당연히 있게 됩니다. 따라서, 요청 파라미터에 필요한 데이터들이 있는 객체를 만들고 바로 매핑 가능하도록 설정이 가능하게 됩니다.
먼저 객체를 하나 만들어 보도록 합시다
@Data
public class UsernameAndAge{
private String username;
private int age;
}
ex)
@PostMapping("/model-attribute")
public String Modelattribute(@ModelAttribute UsernameAndAge usernameAndAge) {
log.info(usernameAndAge.getUsername());
return "ok";
}
스프링은 @ModelAttribute를 마주치게 되면 요청파라미터의 이름으로 UsernameAdnAge객체의 프로퍼티를 찾은 다음 setter를 호출하여 매핑 시켜 줍니다.
물론 @ModelAtribute도 생략 가능합니다.
@RequestParam의 생략과 구분을 위해 @RequestParam은 단순 타입에서 생략시 적용되고 그 외의 타입에는 @ModelAttribute가 적용 됩니다.
ex)
@PostMapping("/request-json")
pulic UsernameAndAge requestJson(@RequestBody UsernameAndAge date){
log.info("username={} , age={}",usernameAndAge.getUsername(),usernameAndAge.Age())
return data;
}
@RequestBody는 @ModelAttribute와 비슷하게 해당 객체에 setter를 호출합니다.
HTTP 메시지 컨버터가 HTTP메시지 바디의 내용을 우리가 원하는 문자나 객체 등으로 변환하여 줍니다. 즉 JSON요청이 오게 되면 컨버트를 거친 뒤 객체로 만들어 집니다.
@RequestBody는 생략 불가능 합니다.
추가로
@PostMapping("/request-json")
pulic ResponseEntity<UsernameAndAge> requestJson(HttpEntity<UsernameAndAge> httpentity){
UsernameAndAge data=httpEntity.getBody();
log.info("username={} , age={}",usernameAndAge.getUsername(),usernameAndAge.Age())
return ResponseEntity.status(HttpStatus.OK).body(data);
}
ResponseEnttiy와 HttpEntity를 활용하여 상태코드를 직접 설정하여 반환도 가능 하게 됩니다.
HttpEntity는 메시지 바디 정보를 직접 조회하는 기능으므로 요청 파라미터를 조회하는 기능과는 관계가 없습니다.
이 글은 인프런 김영한님의 '스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술'을 수강하고 작성합니다.
출처:https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard