Spring @RestController

Rest(Representational State Transfer)란?

하나의 URI는 하나의 고유한 리소스(Resource)를 대표하도록 설계된다는 개념이다. 최근에는 서버에 접근하는 기기의 종류가 다양해 지면서 다양한 기기에서 공통으로 데이터를 처리할 수 있는 규칙을 만들려고 하는데 이러한 시도가 REST방식이다.

REST 방식은 특정한 URI는 반드시 그에 상응하는 데이터 자체라는 점을 의미하는 방식이다. 예를 들어 /boards/123 이라는 URI는 게시물 중 123번이라는 고유한 의미를 가지도록 설계하고, 이에 대한 처리는 GET, POST 방식과 같이 추가적인 정보를 통해 결정한다.

REST API는 외부에서 위와 같은 방식으로 특정 URI를 통해서 사용자가 원하는 정보를 제공하는 방식이다. 최근 Open API에서 많이 사용되면서 REST 방식으로 제공되는 외부 연결 URI를 REST API라고 하고, REST 방식의 서비스 제공이 가능한 것을 'Restfull'하다고 표현한다.


Spring과 REST

스프링3 버전부터 @ResponseBody 애노테이션을 지원하면서 본격적으로 REST 방삭의 처리를 지원하고 했다. 스프링4 버전에서는 REST전용 컨트롤러인 @RestController가 도입되었다.


@RestController 예제

스프링 3버전에서는 컨트롤러에 특정한 메소드에 @RseponseBody 어노테이션을 적용했다. 스프링 4버전부터 지원하는 @RestController라는 어노테이션을 컨트롤러에 지정하면, 해당 컨트롤러의 모든 메소드는 자동적으로 @RseponseBody 어노테이션이 적용된 것처럼 동작한다. 즉 @RestController가 적용된 컨트롤러의 모든 메소드는 jsp등의 뷰를 생성하지 않고 데이터만 반환하게 된다. 이 데이터는 크게 단순문자열, JSON, XML 등으로 나누어진다.

스프링에서 JSON 데이터를 처리하기 위해서는 일단 jackson 라이브러리가 필요하다. pom.xml에 jackson 라이브러리를 추가하자.

1
2
3
4
5
6
<!-- json 데이터 처리용 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.4</version>
</dependency>

그리고 아래는 @RestController가 적용된 테스트 컨트롤러이다. 단순 텍스트, json, list, map등을 REST로 반환하는 예제에다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package com.hanumoka.sample.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/resttest")
public class RestTestController {

@RequestMapping(value = "test", produces = "text/html; charset=utf8")
public String restText() {
return "rest 단순 문자열 반환";
}

@RequestMapping("/json")
public SampleVO restJson() {

SampleVO sampleVO = new SampleVO();
sampleVO.setNo(1);
sampleVO.setName("제이슨 객체입니다.");
return sampleVO;

}

@RequestMapping("/jsonList")
public List<SampleVO> sendList(){

List<SampleVO> list = new ArrayList<>();

for(int i =0; i < 10; i++) {
SampleVO sampleVO = new SampleVO();
sampleVO.setName( (i+1) +"번 데이터");
sampleVO.setNo(i+1);
list.add(sampleVO);
}

return list;
}

@RequestMapping("/sendMap")
public Map<Integer, SampleVO> sendMap(){

Map<Integer, SampleVO> map = new HashMap<>();

for(int i =0; i < 10; i++) {
SampleVO sampleVO = new SampleVO();
sampleVO.setName( (i+1) +"번 데이터");
sampleVO.setNo(i+1);
map.put(i, sampleVO);
}

return map;
}

}

class SampleVO{

private Integer no;
private String name;
public Integer getNo() {
return no;
}
public void setNo(Integer no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}


}

RestController에서 map을 반환하는 결과확인