관리 메뉴

거니의 velog

(10) 스프링 REST API 사용하기 1 본문

Java_Spring Framework part2

(10) 스프링 REST API 사용하기 1

Unlimited00 2023. 11. 16. 13:49

* 스프링을 사용하는 웹 애플리케이션이 브라우저에 응답하는 방식은 주로 웹 페이지였다. 그러나 최근 모바일 기기가 등장하면서 다른 데이터 방식으로 연동하는 일이 잦아졌다. 이번에는 스프링에서 다양한 기기들과 연동하는 방식을 알아보자.


1. REST란?

* 지금은 PC뿐만 아니라 스마트폰, 태블릿, 스마트 TV 등에서도 인터넷 기반으로 웹 애플리케이션을 실행하여 기능을 제공한다. PC에서는 네트워크 전송 속도나 메모리 들이 풍부하므로 지금까지 실습한 대로 브라우저에서 요청 시 화면 정보(HTML, CSS, 자바스크립트 등)도 일일이 다시 전송해서 표시해도 아무 문제가 없었다. 그러나 스마트폰 같은 모바일 기기는 다르게 동작하는 경우가 많다.

* 아래 그림은 모바일 기기에서 상품을 조회한 후 나타나는 최초의 상품 목록 화면과 더보기를 클릭하면 상품 정보만 서버에서 가져와 기존 상품 목록에서 추가하여 보여주는 화면이다.

* 모바일 기기는 네트워크 전송량이 유선 기기보다 떨어지므로 PC에서 동작하는 것과는 달리 화면은 그대로 유지하면서 필요한 데이터만 전송 받아 빠르게 표시한다(Ajax를 이용하는 것이 대표적인 경우이다). 스프링에서도 모바일 기기와 연동하는 경우가 많아지면서 데이터만 전송하는 기능을 지원하게 되었고, 자연히 표준화의 필요성도 대두되었다. 그 결과 REST 라는 방식이 그 대안으로 등장하여 사용되고 있다.

* REST란 Representational State Transfer의 약자로, 하나의 URI가 고유한 리소스를 처리하는 공통 방식이다. 예를 들어 /board/112로 요청할 경우 이는 게시글 중 112번째 글을 의미한다. 그리고 전송 방식을 나타내는 method 속성의 값에 따라 리소스에 대한 추가 작업을 요청한다. REST 방식으로 제공되는 API를 REST API(또는 RESTful API)라고 하며, 이는 트위터와 같은 Open API에서 많이 사용하고 있다.


2. @RestController 사용하기

* 스프링 3 버전에서는 @ResponseBody 애너테이션을 지원하면서 REST 방식의 데이터 처리를 지원했다. 하지만 스프링 4 버전에서는 @RestController 애너테이션을 이용해 REST 방식의 데이터 처리를 지원한다.


(1) @RestController 이용해 REST 기능 구현하기

* 이번에는 스프링에서 지원하는 @RestController를 이용해 컨트롤러에서 브라우저로 기본형 데이터, VO 객체의 속성 값, Map에 저장된 데이터를 전송해 보자. Spring Legacy Project로 프로젝트 pro29를 만든 후 pom.xml을 통해 스프링 버전을 4.1.1로 업그레이드 한다.

1. pom.xml을 열어 스프링 버전을 4.1.1로 변경한 후 저장한다.

2. Maven Dependencies 에서 스프링 4 버전으로 업그레이드 되어 있는 것을 확인할 수 있다.


(2) @RestController 이용해 문자열 전달하기

* 그럼 브라우저로 @RestController를 이용해 문자열과 기본형 데이터를 전달해 보자.

1. TestController 클래스 파일을 준비한다.

2. JSP와 같은 뷰를 반환하는 것이 아니로 JSON, XML 같은 데이터를 브라우저로 전송하는 컨트롤러인 @RestController를 설정한다.

package com.myspring.pro29.ex01;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test/*")
public class TestController {
	static Logger logger = LoggerFactory.getLogger(TestController.class);

	@RequestMapping("/hello")
	public String hello() {
		return "Hello REST!!";
	} // /hello로 요청 시 브라우저로 문자열을 전송한다.
    
}

3. 다음의 주소로 요청하여 전송된 문자열을 표시한다.

- http://localhost/pro29/test/hello

4. 그럼 전송된 데이터의 종류는 어떤 것인지 알아보자. 크롬 브라우저를 기준으로 살펴보자. F12를 눌러 콘솔창을 열고 Network 탭을 연다.

5. All을 클릭한 후 다시 브라우저에 재요청한다.

6. Name의 Hello를 클릭해 'Response Headers'의 Content-Type 속성을 확인한다.

* Response Headers 항목을 보면 전송된 데이터 타입을 나타내는 Content-Type 속성이 text/html로 지정된 것을 확인할 수 있다.


(3) @RestController 이용해 VO 객체 전달하기

* 이번에는 VO 객체의 속성 정보를 JSON 형식으로 전달하는 방법을 알아보자.

1. 다음과 같이 클래스 파일을 준비한다.

2. JSON 기능을 이용하기 위해 pom.xml에 JSON 관련 라이브러리를 추가한다.

		<!-- JSON  --> 
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.5.4</version>
		</dependency>

3. 컨트롤러에서 MemberVO 속성들을 JSON으로 변환하여 전송한다.

@RestController
@RequestMapping("/test/*")
public class TestController {

	@RequestMapping("/member")
	public MemberVO member() {
		MemberVO vo = new MemberVO();
		vo.setId("hong");
		vo.setPwd("1234");
		vo.setName("홍길동");
		vo.setEmail("hong@test.com");
		return vo;
	} // MemberVO 객체의 속성 값을 저장한 후 JSON으로 전송한다.

4. 회원 정보를 저장할 MemberVO 클래스를 구현한다.

package com.myspring.pro29.ex01;

public class MemberVO {
	private String id;
	private String pwd;
	private String name;
	private String email;

	public MemberVO() {}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	@Override
	public String toString() {
		String info = id + ", " + pwd + ", " + name + ", " + email;
		return info;
	} // 회원 속성 정보를 출력한다.

}

5. 다음의 주소로 요청하여 객체의 속성 값들이 JSON 형태로 전달되는 것을 확인할 수 있다.

- http://localhost/pro29/test/member


(4) @RestController 이용해 컬렉션 객체 전달하기

* 이번에는 List 같은 컬렉션을 JSON으로 만들어 전송해 보자.

[TestController.java]

@RestController
@RequestMapping("/test/*")
public class TestController {

	@RequestMapping("/membersList")
	public List<MemberVO> listMembers() {
		List<MemberVO> list = new ArrayList<MemberVO>(); // MemberVO 객체를 저장할 ArrayList 객체를 생성한다.
		for (int i = 0; i < 10; i++) {
			MemberVO vo = new MemberVO();
			vo.setId("hong" + i);
			vo.setPwd("123" + i);
			vo.setName("홍길동" + i);
			vo.setEmail("hong" + i + "@test.com");
			list.add(vo);
		} // MemberVO 객체를 10개 생성해 ArrayList에 저장한다.
		return list; // ArrayList를 JSON 으로 브라우저에 전송한다.
	}

* 브라우저에서 요청 시 List의 객체들을 JSON으로 전송한다.

- http://localhost/pro29/test/membersList


(5) @RestController 이용해 Map 전달하기

* 이번에는 Map에 저장된 데이터를 전송해 보자.

[TestController.java]

@RestController
@RequestMapping("/test/*")
public class TestController {

	@RequestMapping("/membersMap")
	public Map<Integer, MemberVO> membersMap() {
		Map<Integer, MemberVO> map = new HashMap<Integer, MemberVO>(); // MemberVO 객체를 저장할 HashMap 객체를 생성한다.
		for (int i = 0; i < 10; i++) {
			MemberVO vo = new MemberVO();
			vo.setId("hong" + i);
			vo.setPwd("123" + i);
			vo.setName("홍길동" + i);
			vo.setEmail("hong" + i + "@test.com");
			map.put(i, vo);
		} // MemberVO 객체를 HashMap에 저장한다.
		return map; // MemberVO 객체를 브라우저로 전송한다.
	}

* 브라우저에 요청 시 map 데이터를 JSON으로 전송한다.

- http://localhost/pro29/test/membersMap