이번 포스팅에서는 기본적인 스프링 어노테이션 사용법을 연습해 볼 것이다. 헷갈리는 어노테이션들이 많으니 예제를 보며 감을 익히는 것을 추천한다.
@Controller
@Controller 어노테이션은 HTTP 요청을 처리하는 컨트롤러를 의미하며, Spring MVC 뷰를 반환하는 데 사용된다. 즉 View(화면)을 리턴할 때 쓰인다.
아래의 예시처럼 리턴 타입이 String인 경우 src/main/resources/templates 경로에서 리턴값이 "home".html 파일을 찾아서 해당 뷰를 보여준다.
HomeController.java
@Controller
public class HomeController {
@GetMapping(value = "/")
public String home() {
return "home"; // src/main/resources/templates/home.html 반환
}
}
@RestController
@RestController는 @Controller + @Responsebody를 합친 것이라고 생각하면 된다.
@RestController 어노테이션은 RESTful 웹 서비스를 위한 컨트롤러를 의미하며, RESTful 웹 서비스의 JSON, XML 등의 응답을 반환하는 데 사용된다. @Controller와 달리 view 화면을 리턴하지 않고, 컨트롤러에서 Data를 리턴할 수 있다.
아래의 예시처럼 객체 데이터를 반환하기만 하면, JSON, XML 형식으로 HTTP 응답하게 된다.
HomeController.java
@RestController
public class HomeController {
@GetMapping(value = "/")
public BoardVO home() {
return new BoardVO("제목", "내용");
}
}
BoardVO.java
@AllArgsConstructor
@Getter
public class BoardVO {
String title; // 제목
String content; // 내용
}
아래와 같이 json 형식으로 데이터가 출력된다.
@Controller과 @RestController의 차이
@Controller는 일반적으로 HTTP 요청을 처리하고 뷰를 반환하는 데 사용된다.
@RestController는 HTTP 요청에 대한 RESTful 웹 서비스의 JSON, XML 등의 응답을 반환하는 데 사용된다.
경로 매핑(mapping)
아래 어노테이션들은 특정 경로(URL)를 매칭하는데 쓰인다.
어노테이션 | HTTP | 역할 | 예시 |
@RequestMapping | ALL | 요청 메서드와 URL 매핑을 함께 지정 | @RequestMapping(value="/users", method=RequestMethod.GET) |
@GetMapping | GET | 리소스 조회 | @GetMapping(value="/users") |
@PostMapping | POST | 리소스 생성 | @PostMapping(value="/users") |
@PutMapping | PUT | 리소스 갱신 | @PutMapping(value="/users") |
@PatchMapping | PATCH | 리소스 일부 갱신 | @PatchMapping(value="/users") |
@DeleteMapping | DELETE | 리소스 삭제 | @DeleteMapping(value="/users") |
@RequestMapping과 @XXMapping 중 무엇을 사용해야 할까?
간단한 HTTP 요청에 대해서는 @XXMapping을 사용하는 것이 코드 가독성과 유지보수성을 높일 수 있다. 하지만 여러 개의 HTTP 요청 메서드에 대해 하나의 메서드로 처리해야 하는 경우는 @RequestMapping을 사용해야 한다.
@RequestMapping(value="/users", method=RequestMethod.GET)
public String home() {
return "home";
}
@GetMapping(value = "/")
public String home() {
return "home";
}
요청 데이터 관련
@PathVariable
'URL 경로의 일부'를 매개변수로 전달받는 어노테이션이다. 예를 들어 http://localhost:8080/users/test123 로 호출하면 입력값인 'test123'을 매개변수로 받게 된다.
@RestController
@Slf4j
public class HomeController {
@GetMapping("/users/{id}")
public void getUserById(@PathVariable String id) {
log.info(id); // 출력 결과 : test123
}
}
@RequestParam
'HTTP 요청 파라미터'를 매개변수로 전달받는 어노테이션이다. 예를 들어 http://localhost:8080/users?name=개발새발 로 호출하면 key, value 형식에 따라 키값인 name에 맞는 '개발새발'을 매개변수로 받게 된다.
@RestController
@Slf4j
public class HomeController {
@GetMapping("/users")
public void getAllUsers(@RequestParam("name") String name) {
log.info(name); // 출력 결과 : 개발새발
}
}
@RequestBody
HTTP 요청의 '본문(body)'을 매개변수로 전달받는 어노테이션이다. 주의할 점은 GET 통신에서는 @RequestParam을 사용하지만, POST 통신에서는 @RequestBody를 사용한다. 따라서 POST 통신으로 전송하기 위해 home.html에 소스를 추가할 것이다.
home.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script type="text/javascript">
function createUser() {
const requestData = new Object();
requestData.userId = document.getElementById("userId").value;
requestData.userNm = document.getElementById("userNm").value;
const httpRequest = new XMLHttpRequest();
httpRequest.open('POST', '/users', true);
httpRequest.responseType = "json";
httpRequest.setRequestHeader('Content-Type', 'application/json');
httpRequest.send(JSON.stringify(requestData));
}
</script>
<body>
<form>
<table>
<thead>
<tr>
<th>아이디</th>
<th>이름</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" id="userId" /></td>
<td><input type="text" id="userNm" /></td>
</tr>
</tbody>
</table>
<button onclick="createUser()">등록</button>
</form>
</body>
</html>
위 소스를 실행하면 아래처럼 보여진다. 아이디와 이름을 입력하고 등록 버튼 클릭 시, POST 방식으로 json 문자열 데이터를 HTTP 요청으로 보내면 @RequestBody 어노테이션을 통해 객체 데이터를 매개변수로 전달받게끔 구현하고자 한다.
UserVO.java
@Getter
public class UserVO {
String userId; // 아이디
String userNm; // 이름
}
HomeController.java
@RestController
@Slf4j
public class HomeController {
@PostMapping("/users")
public void createUser(@RequestBody UserVO userVO) {
log.info(userVO.getUserId() + "/" + userVO.getUserNm()); // 출력 결과 : test123 / 개발새발
}
}
응답 데이터 관련
@ResponseBody
HTTP 응답의 본문(body)을 생성하는 메서드에 적용하는 어노테이션이다. 위에서 언급했듯이 @Controller + @Responsebody를 합친 것이 @RestController 이다. 추가 관련 내용은 @RequestBody / @ResponseBody 어노테이션 포스팅을 읽어보자.
@Controller
public class HomeController {
@GetMapping("/data")
public @ResponseBody List<String> getData() {
List<String> list = new ArrayList<>();
list.add("차은우");
list.add("카리나");
list.add("혜인");
return list;
}
}
출력 결과
@ResponseStatus
HTTP 응답의 상태 코드를 지정하는 어노테이션이다.
@RestController
public class HomeController {
@GetMapping("/users/{id}")
@ResponseStatus(HttpStatus.NOT_FOUND)
public void getUserById(@PathVariable String id) {
}
}
http 상태 코드는 HttpStatus 클래스에 따라 구체적으로 정의되고 있다.
@ResponseEntity
보통 RESTful API를 개발할 때 클라이언트와 서버 간의 통신에 필요한 정보를 제공해야 한다. 그럴 때 ResponseEntity를 사용하여, 적절한 정보를 생성해서 클라이언트에 전달할 수 있다. HTTP Response 메시지를 감싸는 어노테이션이므로 HTTP 상태코드, 응답 헤더, 응답 본문 데이터 등을 포함하여 전달하면 된다. 추가적인 내용은 ResponseEntity를 잘 쓰는 방법 포스팅을 참고하자.
@RestController
public class HomeController {
@GetMapping("/user")
public ResponseEntity<User> getUser() {
User user = userService.getUser();
return ResponseEntity.ok(user); // 성공을 의미하는 OK(200 code)와 함께 user 객체 리턴
}
}
MVC 패턴으로 REST API 개발 예시
- @Controller : 웹 화면(view)을 보여준다.
- @RestController <---> @Service <---> @Mapper : 클라이언트에서 요청한 데이터를 가져와서 응답한다.
- @Autowired : 보통 bean에 의존성 주입을 하고 싶을 때 사용한다. Spring Container가 관리하며, 이 어노테이션을 붙여주어야 두 클래스의 의존관계가 형성된다.
'Backend > Spring, SpringBoot' 카테고리의 다른 글
스프링부트 개발환경 구성하기 (6) Mybatis 연동과 게시판 목록 조회 (0) | 2023.10.16 |
---|---|
스프링부트 개발환경 구성하기 (5) DB 설계와 REST API 설계 (0) | 2023.10.12 |
스프링부트 개발환경 구성하기 (4) 메이븐 Local Repository 설정 (0) | 2023.09.27 |
스프링부트 개발환경 구성하기 (3) 스프링부트 프로젝트 생성 (0) | 2023.09.25 |
스프링부트 개발환경 구성하기 (2) STS 4 설치 (0) | 2023.09.24 |