자바에서의 Restful 웹 서비스 튜토리얼

환영합니다. 자바에서 Restful 웹 서비스 튜토리얼에 오신 것을 환영합니다. RESTREpresentational State Transfer의 약자입니다. REST는 네트워크를 통해 액세스할 수 있는 응용 프로그램을 개발하기 위한 아키텍처 스타일입니다. REST 아키텍처 스타일은 2000년 Roy Fielding의 박사 논문에서 소개되었습니다.

Restful 웹 서비스

Restful 웹 서비스는 상태 없는 클라이언트-서버 아키텍처로, 웹 서비스는 리소스이며 URI로 식별할 수 있습니다. REST 클라이언트 응용 프로그램은 HTTP GET/POST 방법을 사용하여 Restful 웹 서비스를 호출할 수 있습니다. REST는 사용할 특정 프로토콜을 지정하지 않지만 대부분의 경우 HTTP/HTTPS를 통해 사용됩니다. SOAP 웹 서비스와 비교할 때 이러한 서비스는 가벼우며 표준을 준수하지 않습니다. 요청 및 응답에 XML, JSON, 텍스트 또는 기타 유형의 데이터를 사용할 수 있습니다.

Java RESTful 웹 서비스 API

Java RESTful 웹 서비스용 API (JAX-RS)는 REST 웹 서비스를 만들기 위한 Java API입니다. JAX-RS는 주석을 사용하여 웹 서비스의 개발 및 배포를 간소화합니다. JAX-RS는 JDK의 일부이므로 주석을 사용하려면 별도로 포함할 필요가 없습니다.

Restful Web Services Annotations

중요한 JAX-RS 어노테이션 중 일부는 다음과 같습니다:

  • @Path: 클래스와 메소드의 상대 경로를 지정하는 데 사용됩니다. Path 어노테이션 값을 스캔하여 웹 서비스의 URI를 얻을 수 있습니다.
  • @GET, @PUT, @POST, @DELETE@HEAD: 메소드에 대한 HTTP 요청 유형을 지정하는 데 사용됩니다.
  • @Produces, @Consumes: 요청 및 응답 유형을 지정하는 데 사용됩니다.
  • @PathParam: 메소드 매개변수를 경로 값에 바인딩하는 데 사용됩니다.

Restful Web Services and SOAP

  1. SOAP은 프로토콜이며, REST는 아키텍처 스타일입니다.
  2. SOAP 서버 및 클라이언트 응용 프로그램은 WSDL 계약과 엄격하게 결합되어 있지만, REST 웹 서비스 및 클라이언트에는 계약이 없습니다.
  3. REST 웹 서비스의 학습 곡선은 SOAP 웹 서비스와 비교하여 쉽습니다.
  4. REST 웹 서비스의 요청 및 응답 유형은 XML, JSON, 텍스트 등이 될 수 있지만, SOAP은 XML만 사용합니다.
  5. JAX-RS는 REST 웹 서비스를 위한 Java API이며, JAX-WS는 SOAP 웹 서비스를 위한 Java API입니다.

REST API 구현

JAX-RS API에는 두 가지 주요 구현이 있습니다.

  1. Jersey: Jersey는 Sun에서 제공하는 참조 구현입니다. JAX-RS 구현으로 Jersey를 사용하기 위해서는 web.xml에서 서블릿을 구성하고 필요한 종속성을 추가하면 됩니다. JDK의 일부인 JAX-RS API는 Jersey의 종속성 JAR를 애플리케이션에 추가해야 합니다.
  2. RESTEasy: RESTEasy는 JBoss 프로젝트로 JAX-RS 구현을 제공합니다.

Java Restful 웹 서비스 자습서

이제 Jersey와 RESTEasy를 사용하여 얼마나 쉽게 Restful 웹 서비스를 생성할 수 있는지 알아보겠습니다. 다음과 같은 메소드를 HTTP를 통해 노출하고 Chrome Postman 확장 프로그램을 사용하여 이를 테스트할 것입니다.

URI HTTP Method Description
/person/{id}/getDummy GET Returns a dummy person object
/person/add POST Adds a person
/person/{id}/delete GET Delete the person with ‘id’ in the URI
/person/getAll GET Get all persons
/person/{id}/get GET Get the person with ‘id’ in the URI

Jersey Restful 웹 서비스

다이내믹 웹 프로젝트를 만들고 Maven으로 변환하여 웹 서비스 프로젝트의 뼈대를 얻으세요. 아래 이미지는 최종 프로젝트의 프로젝트 구조를 보여줍니다. pom.xml 파일에서 Jersey 종속성을 살펴보겠습니다.

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>JAXRS-Example</groupId>
  <artifactId>JAXRS-Example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  
  <dependencies>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.19</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-servlet</artifactId>
            <version>1.19</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.19</version>
        </dependency>
  </dependencies>
  
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.6</version>
        <configuration>
          <warSourceDirectory>WebContent</warSourceDirectory>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

우리는 jersey-client 종속성을 추가할 필요는 없지만, Jersey를 사용하여 REST 웹 서비스를 호출하는 Java 프로그램을 작성한다면 필요합니다. 이제 Jersey를 웹 애플리케이션에 구성하는 방법을 배우기 위해 배포 설명자를 살펴봅시다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>JAXRS-Example</display-name>

<!-- Jersey Servlet configurations -->
    <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>com.journaldev</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
  <!-- Jersey Servlet configurations -->

</web-app>

이것이 우리의 웹 애플리케이션에 Jersey를 플러그인하기 위해 필요한 모든 것입니다. 우리의 Java 코드에서는 JAX-RS 주석을 사용할 것입니다. init 매개변수 com.sun.jersey.config.property.packages의 값에 주목하여 웹 서비스 리소스와 메서드를 스캔할 패키지를 제공하세요.

REST 예제 모델 클래스

먼저 애플리케이션 데이터용 Person과 클라이언트 시스템에 응답을 보내기 위한 Response 두 개의 모델 빈을 생성할 것입니다. XML 응답을 보낼 것이므로 빈에는 @XmlRootElement가 있어야 합니다. 따라서 이 클래스가 필요합니다.

package com.journaldev.jaxrs.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement (name="person")
public class Person {
	private String name;
	private int age;
	private int id;

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	
	@Override
	public String toString(){
		return id+"::"+name+"::"+age;
	}

}
package com.journaldev.jaxrs.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Response {

	private boolean status;
	private String message;

	public boolean isStatus() {
		return status;
	}

	public void setStatus(boolean status) {
		this.status = status;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
}

REST 웹 서비스 튜토리얼 서비스

URI 구조를 기반으로 아래는 서비스 인터페이스와 그 구현 코드입니다.

package com.journaldev.jaxrs.service;

import com.journaldev.jaxrs.model.Person;
import com.journaldev.jaxrs.model.Response;

public interface PersonService {

	public Response addPerson(Person p);
	
	public Response deletePerson(int id);
	
	public Person getPerson(int id);
	
	public Person[] getAllPersons();

}
package com.journaldev.jaxrs.service;


import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.journaldev.jaxrs.model.Person;
import com.journaldev.jaxrs.model.Response;

@Path("/person")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public class PersonServiceImpl implements PersonService {

	private static Map<Integer,Person> persons = new HashMap<Integer,Person>();
	
	@Override
	@POST
    @Path("/add")
	public Response addPerson(Person p) {
		Response response = new Response();
		if(persons.get(p.getId()) != null){
			response.setStatus(false);
			response.setMessage("Person Already Exists");
			return response;
		}
		persons.put(p.getId(), p);
		response.setStatus(true);
		response.setMessage("Person created successfully");
		return response;
	}

	@Override
	@GET
    @Path("/{id}/delete")
	public Response deletePerson(@PathParam("id") int id) {
		Response response = new Response();
		if(persons.get(id) == null){
			response.setStatus(false);
			response.setMessage("Person Doesn't Exists");
			return response;
		}
		persons.remove(id);
		response.setStatus(true);
		response.setMessage("Person deleted successfully");
		return response;
	}

	@Override
	@GET
	@Path("/{id}/get")
	public Person getPerson(@PathParam("id") int id) {
		return persons.get(id);
	}
	
	@GET
	@Path("/{id}/getDummy")
	public Person getDummyPerson(@PathParam("id") int id) {
		Person p = new Person();
		p.setAge(99);
		p.setName("Dummy");
		p.setId(id);
		return p;
	}

	@Override
	@GET
	@Path("/getAll")
	public Person[] getAllPersons() {
		Set<Integer> ids = persons.keySet();
		Person[] p = new Person[ids.size()];
		int i=0;
		for(Integer id : ids){
			p[i] = persons.get(id);
			i++;
		}
		return p;
	}

}

대부분의 코드는 자명합니다. JAX-RS 어노테이션 @Path, @PathParam, @POST, @GET, @Consumes, 그리고 @Produces에 익숙해지는 데 시간을 할애하십시오.

Restful 웹 서비스 테스트

그것입니다. 우리의 웹 서비스가 준비되었습니다. WAR 파일로 내보내어 Tomcat 웹앱 디렉토리에 넣거나 원하는 다른 컨테이너에 배포하십시오. 아래는 이 웹 서비스에 대해 Postman 크롬 익스텐션을 사용하여 수행한 일부 테스트입니다. 아래 이미지에서와 같이 요청 헤더에 “application/xml” 값을 Accept 및 Content-Type으로 제공해야 합니다.

  • getDummy
  • 추가
  • 얻다
  • 모두 얻다
  • 삭제

Jersey JAX-RS 구현을 사용하여 웹 서비스를 생성하는 데 필요한 모든 내용입니다. 대부분의 코드가 JAX-RS 어노테이션을 사용하고 Jersey는 배포 설명자 및 종속성을 통해 통합되었음을 확인할 수 있습니다.

RESTEasy RESTful 웹 서비스 예제

프로젝트 전체 비즈니스 로직은 Jersey 프로젝트에서 개발된 것을 사용할 것이지만, 동일한 프로젝트에 변경을 가하는 대신에 새로운 프로젝트를 만들었습니다. 동적 웹 프로젝트를 생성하고 Maven 프로젝트로 변환하세요. 그런 다음 모든 Java 클래스 – Person, Response, PersonService 및 PersonServiceImpl을 복사하세요. 아래는 모든 변경 사항이 완료된 후 최종 프로젝트입니다. pom.xml 파일에 아래 RESTEasy 종속성을 추가하세요.

<dependency>
	<groupId>org.jboss.resteasy</groupId>
	<artifactId>resteasy-jaxrs</artifactId>
	<version>3.0.13.Final</version>
</dependency>
<dependency>
	<groupId>org.jboss.resteasy</groupId>
	<artifactId>resteasy-jaxb-provider</artifactId>
	<version>3.0.13.Final</version>
</dependency>

아래는 Resteasy 서블릿을 구성하는 web.xml 파일입니다.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>JAXRS-Example-RestEasy</display-name>
     
    <listener>
      <listener-class>
         org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
      </listener-class>
   	</listener>
   
    <servlet>
        <servlet-name>resteasy-servlet</servlet-name>
        <servlet-class>
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
        </servlet-class>
        <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.journaldev.jaxrs.resteasy.app.MyApp</param-value>
    </init-param>
    </servlet>
  
    <servlet-mapping>
        <servlet-name>resteasy-servlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
	
</web-app>

여기서는 MyApp 클래스를 값으로 제공하는 init-param에 주목하세요. 여기서는 javax.ws.rs.core.Application 클래스를 확장하고 있습니다.

package com.journaldev.jaxrs.resteasy.app;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;

import com.journaldev.jaxrs.service.PersonServiceImpl;

public class MyApp extends Application {
	
	private Set<Object> singletons = new HashSet<Object>();

	public MyApp() {
		singletons.add(new PersonServiceImpl());
	}

	@Override
	public Set<Object> getSingletons() {
		return singletons;
	}

}

RESTEasy 웹 서비스 테스트

이게 전부입니다. RESTEasy JAX-RS 구현을 사용하는 웹 서비스가 준비되었습니다. Postman 크롬 익스텐션 테스트에서 얻은 일부 결과는 아래에 나와 있습니다.

  • getDummy
  • 추가하다
  • 얻다

이것으로 Restful 웹 서비스 튜토리얼이 모두입니다. JAX-RS 어노테이션에 대해 배우고 표준 API를 가지는 이점을 이해하여 코드를 재사용하고 Jersey에서 RESTEasy로 이동하는 것이 얼마나 쉬운지 배웠으면 좋겠습니다.

Source:
https://www.digitalocean.com/community/tutorials/restful-web-services-tutorial-java