Spring RESTful 웹 서비스

■ 참조 – Building a RESTful Web Service

■ 이 가이드는 Spring으로 ‘hello world’ RESTful 웹 서비스를 만드는 과정이다.  아래와 같이 HTTP GET 요청을하면

http://localhost:8080/greeting

인사말(greeting)에 대한 JSON 응답을 하는 서비스를 작성한다.

{"id":1,"content":"Hello, World!"}

쿼리 문자열에 선택적으로 name 파라메터를 추가하여 JSON응답을 커스터마이징 할 수 있다.

http://localhost:8080/greeting?name=User

name 파라메터는 기본값인 ‘World!’를 오버라이딩해서 응답에 반영된다.

{"id":1,"content":"Hello, User!"}

■ Eclipse에서 프로그램을 작성해 보자. 먼저 Maven Project를 생성한다.

Maven Project 생성

■ Group Id : net.iotinfra, Artifact Id : pilot.restful로 임의대로 입력하고 Packaging은 war이 아닌 jar로 선택한다.

Jar 타입으로 Packaging

■ Maven Project의 pom.xml은 아래와 같이 작성한다.

<project xmlns="http://maven.apache.org/POM/4.0.0"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0  http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>net.iotinfra</groupId>
  <artifactId>pilot.restful</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>    
</project>

■ Spring Boot Maven 플러그인은 많은 편리한 기능을 제공한다.

  • 클래스 패스에 있는 모든 jar를 모아 하나의 실행가능한 “über-jar”를 빌드하므로 서비스를 실행하고 전송하는 것이 더 편리하다.(über-jar는 패키징시 제작된 모듈과 디펜던시가 하나의 jar에 파일에 포함된 것을 의미. https://opennote46.tistory.com/110)
  • public static void main () 메서드를 검색하여 실행 가능한 클래스로 플래그를 지정한다.
  • Spring Boot 의존성에 맞게 버전 번호를 설정하는 빌트인 의존성 분석기를 제공한다. 원하는 버전을 무시할 수 있지만 기본적으로 Boot에서 선택한 버전 세트가 사용된다.

■ 이 서비스는 /greeting에 대한 GET 요청을 처리하며 선택적으로 쿼리 문자열에 name 매개변수를 사용한다. GET요청은 인사말(greeting)을 나타내는 본문에 JSON이 있는 200 OK 응답을 반환해야 한다. 다음과 같이 보일 것이다.

{
    "id": 1,
    "content": "Hello, World!"
}

■ 아래의 단계에서 볼 수 있듯이 Spring은 Jackson JSON 라이브러리를 사용하여 Greeting 유형의 인스턴스를 JSON으로 자동 마샬링한다.

GreetingController.java – RESTful 웹 서비스를 구현하는 Spring의 접근 방식에서 HTTP 요청은 컨트롤러에 의해 처리된다. 이러한 구성 요소는 @RestController 어노테이션으로 쉽게 식별 할 수 있으며 아래의 GreetingController는 Greeting 클래스의 새 인스턴스를 반환하여 /greeting에 대한 GET 요청을 처리한다.

package pilot.restful.hello;

import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value="name", defaultValue="World")  String name) {
        return new Greeting(counter.incrementAndGet(),
                            String.format(template, name));
    }
}

■ @RequestMapping 어노테이션은 /greeting에 대한 HTTP 요청이 greeting() 메소드에 매핑되도록 한다. 

@RequestMapping은 기본적으로 모든 HTTP 작업을 매핑하기 때문에 위의 예에서는 GET 대신 PUT, POST 등을 지정하지 않습니다. @RequestMapping (method = GET)을 사용하여이 매핑의 범위를 좁힌다.

@RequestParam은 쿼리 문자열 매개 변수 이름의 값을 greeting() 메서드의 name 매개 변수에 바인딩합니다. 요청에 name 매개 변수가 없으면 defaultValue “World”가 사용된다.

메소드 본문의 구현은 카운터의 다음 값을 기반으로 id 및 content 속성을 사용하여 새 Greeting 객체를 만들고 반환하며 인사말 템플릿을 사용하여 지정된 이름의 서식을 지정한다.

위의 전통적인 MVC 컨트롤러와 RESTful 웹 서비스 컨트롤러의 주요 차이점은 HTTP 응답 본문을 만드는 방법이다. 이 RESTful 웹 서비스 컨트롤러는 HTML에 대한 인사말 데이터의 서버 측 렌더링을 수행하기 위한 뷰 기술에 의존하기 보다는 단순히 Greeting 객체를 채우고 반환한다. 객체 데이터는 JSON으로 HTTP 응답에 직접 기록된다.

이 코드는 모든 메소드가 뷰 대신 도메인 객체를 반환하는 컨트롤러로 클래스를 표시하는 스프링 4의 새로운 @RestController 어노테이션을 사용한다. @Controller와 @ResponseBody를 함께 사용하는 것의 단축형이다.

Greeting 객체는 JSON으로 변환되어야 한다. Spring의 HTTP 메시지 변환기 지원 덕분에 이 변환을 수동으로 수행 할 필요가 없다. Jackson 2가 클래스 경로에 있기 때문에 Spring의 MappingJackson2HttpMessageConverter가 자동으로 선택되어 Greeting 인스턴스를 JSON으로 변환한다.

■ 애플리케이션을 실행가능하게 만들기

이 서비스를 외부 응용 프로그램 서버에 배포하기위한 기존 WAR 파일로 패키지화 할 수는 있지만 아래에 설명 된 간단한 방법은 독립 실행형 응용 프로그램을 만든다. 좋은 오래된 Java main () 메소드로 구동되는 실행 가능한 단일 JAR 파일로 모든 것을 패키지한다. 그동안 외부 인스턴스에 배포하는 대신 Tomcat 서블릿 컨테이너를 HTTP 런타임으로 포함시키기위한 Spring의 지원을 한다.

package pilot.restful.hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@SpringBootApplication은 다음을 모두 추가하는 편리한 어노테이션이다.

  • @Configuration은 클래스를 애플리케이션 컨텍스트의 Bean 정의 소스로 태그 지정한다.
  • @EnableAutoConfiguration은 Spring Boot에게 클래스 패스 설정, 다른 bean 및 다양한 속성 설정을 기반으로 bean 추가를 시작하도록 지시한다.
  • 일반적으로 @EnableWebMvc를 Spring MVC app에 추가하지만, Spring Boot는 classpath에서 spring-webmvc를 볼 때 자동으로 추가한다. 이것은 응용 프로그램에 웹 응용 프로그램으로 플래그를 지정하고 DispatcherServlet 설정과 같은 주요 동작을 활성화한다.
  • @ComponentScan은 Spring에게 hello 패키지의 다른 구성 요소, 구성 및 서비스를 찾아서 컨트롤러를 찾을 수 있게 한다.

main() 메소드는 Spring Boot의 SpringApplication.run () 메소드를 사용하여 애플리케이션을 시작한다. 한 줄의 XML도 없다. web.xml 파일도 없다. 이 웹 응용 프로그램은 100 % 순수 자바이며 연관 작업이나 인프라 구성에 대해 다룰 필요가 없다.

■ 실행가능한 JAR파일 만들기 – clean install을 maven Goals로 지정하고 빌드를 하면 target 폴더에 생성된 pilot.restful-0.0.1-SNAPSHOT.jar 파일을 확인할 수 있다.

프로젝트 빌드
완성된 프로젝트 구조 / 빌드된 JAR 파일

■ 애플리케이션 실행 방법 1 – Eclipse Menu > Run > Run Configurations… 선택하고 Project : pilot.restful 선택하고 Main class에 pilot.restful.hello.Application을 선택하고 Run 버튼을 클릭해서 애플리케이션을 실행한다.

Eclipse에서 애플리케이션 실행

■ 애플리케이션 실행 방법 2 – 도스창(CMD 창)에서 프로젝트 폴더로 이동후 다음과 같이 실행한다.

java -jar target/pilot.restful-0.0.1-SNAPSHOT.jar

■ 애플리케이션을 실행하면 Eclipse Console에서 아래와 같이 실행중인 것을 확인할 수 있다. Tomcat 서버가 8080포트에서 서비스중이다.

Tomcat 8080포트에서 실행중인 애플리케이션

■ 웹 브라우져 클라이언트에서 RESTful Web Service에 요청하면 아래와 같이 JSON응답을 한 것을 확인할 수있다.

JSON 응답