반응형
HttpRequestServlet과는 다르게 어노테이션이 붙은 Spring 문법은 '자바 객체로 변환' 시켜준다는 공통점을 갖고 있다.
HttpRequestServlet
public String getTest(HttpRequestServlet request){
System.out.println(request.getParameter("cmd"));
}
- Get 방식으로 받아온 데이터를 쓴다.
- Post 방식으로 받아온 데이터는 커스텀 메소드를 작성해서 Decode를 한 후에 사용한다.
@RequestParam
public String getTest(@RequestParam("name") String name){
System.out.println(name);
}
- Get 형태의 Query Parameter를 가져올 수 있다.
- Post 방식에도 쓸 수는 있지만 Post에서는 일반적으로 form-url-encoded 데이터를 가져온다. JSON 형식의 Body Type을 매핑시킬 순 없다.
- 어노테이션이 생략이 가능하다. 다만 Primitive 타입인 경우에만 생략이 가능하고 객체인 경우엔 ModelAttribute로 매핑된다.
- 비슷한 방식으로는 @PathVariable이 있다.
- 해당 Param이 없으면 404 error가 나며 이런 경우를 방지하고자 기본값을 아래와 같이 설정할 수 있다.
@RequestParam("name",required=false,defaultValue="")
@RequestBody
@ResponseBody
public String getTest(@RequestBody Info info) {
return body;
}
- AJAX 비동기 요청, REST API에서 content type을 Post 데이터인 json으로 설정해서 많이 사용한다. 왜냐면 직렬화, 역직렬화 기능이 있기 때문이다.
- @RequestBody는 Get, Post 둘 다 가능하며 원칙상 요청 Body 안에 Json만 포함한다면 가능하다.
그렇지만 웬만해선 Post만 사용해야 한다. @RequestBody는 Body안에 Json을 포함해야하는 것이 룰이지만 Get은 Header에 Query String 형태로 보내는 것이 일반적이기 때문이다. Post로 Body에 Json으로 요청하는 것이 일반적이고 Restful Semantics, 의미론적으로 개발자간의 협업이 어려울 수 있기 때문에 Post는 Post 답게 Get은 Get 답게 쓰는 것을 권장한다. - @RequestBody는 JSON 요청 데이터를 Java객체로 변환해주며 반대로 @ReponseBody는 Java객체를 Http에서 사용할 수 있는 데이터 JSON 응답 데이터로 변환 시켜준다.
- Primitive Type(보통 HashMap)으로도 받을 수 있지만 위처럼 DTO 클래스(Info 클래스)를 통해서도 받는 것을 권장한다.(DTO는 Jackson에 의해 기본 생성자가 필요하다)
- DTO에 Setter가 필요없다. HttpMessageConverter에 의해 자바 객체로 변환될 때 DTO의 기본생성자만 가지고 리플렉션을 이용해 값을 세팅한다. 하지만 Setter가 존재한다면 기본생성자 매핑 이후에 Setter로 인해 한번더 정제돼서 매핑된다. setter를 이용해서 값을 커스터마이징 할 수 있다.
@ModelAttribute
@Getter
@Setter
public class TestDto {
private String name;
private int age;
}
public class TestController {
@RequestGetMapping(value = "/hi")
public void getTest(@ModelAttribute("test") TestDto test){
System.out.println("이름 : " + test.getName());
System.out.println("나이 : " + test.getAge());
}
}
- ModelAttribute는 Form 형태 기반의 요청들을 받는다.
- REST API에서는 주로 GET 형태 기반의 요청들을 받는다.
- Primitive 타입인 경우엔 @RequestParam으로 매핑되고 객체인 경우엔 @ModelAttribute로 매핑된다.
- ModelAttribute는 Get, Post 다 사용 가능하다. Get인 경우에는 Query String을 요청 데이터로 보내고 Post인 경우엔 x-www-form-urlencoded 형태로 요청 데이터를 보낸다. 그렇기 때문에 Post는 항상 Form 형태여야하고 Get은 Form이 아니어도 URI만 전달하면 된다.
- 각각의 값을 DTO에 바인딩 할 때 기본 생성자가 존재하는 경우엔 Setter를 통해 바인딩한다. Setter가 없으면 바인딩 되지 않는다. @AllargsConstructor로 파라미터가 포함된 생성자를 만들면 기본 생성자와 Setter는 필요없이 값이 바인딩 된다. 이럴땐 @AllargsConstructor와 Getter만 구현한다.
- DTO로 가져온 값은 Return 할 때 자동으로 포함되어 리턴된다. "test"가 return 될 때의 리턴 객체를 뜻하며 View 영역에서 test.name 형식으로 사용하도록 지정할 수 있다.
- 위의 코드에서 ("test")를 생략하고 @ModelAttribute TestDto test라고 쓴다면 자동으로 test 변수의 이름의 객체로 Return한다.
- 아예 @ModelAttribute를 생략하는 것도 가능하다. TestDto test라고 쓰면 Spring은 내부적으로 @ModelAttribute("test")를 붙여서 사용하는 것과 같다.
@ResponseBody
리턴하는 DTO에 Getter가 없으면 리턴하지 못한다.
728x90
'🍃 Spring' 카테고리의 다른 글
@PostConstruct와 bean 생명주기 (0) | 2022.09.19 |
---|---|
Redirect와 Forward 차이점, 특징 및 실무 사용법 (0) | 2022.09.15 |
Spring과 Spring Boot의 예외 처리와 에러 페이지 처리 방식 (1) | 2022.07.30 |
Spring Boot에서 파일 저장을 위한 상대경로 getRealPath() 사용 금지 (0) | 2022.06.14 |
Spring Boot application Property와 yml 작성 방법 (0) | 2021.04.30 |