ÃֽŠ°Ô½Ã±Û(JAVA)
2018.10.18 / 16:40

Java EE 7 ¸¸À¸·Î REST API ¸¸µé±â

hanulbit
Ãßõ ¼ö 293

¿äÁò ¾îÇø®ÄÉÀ̼ÇÀÇ È­µÎ´Â ´Ü¿¬ ¾î¶»°Ô ºü¸£°Ô °³¹ßÇÏ¿© DeployÇÒ ¼ö Àִ°¡¿¡ ÀÖ´Â µí ÇÏ´Ù. »õ·Î¿î ÇÁ·ÎÁ§Æ®¸¦ SetupÇÏ°í DeployÇÏ´Â °úÁ¤ÀÌ ¿¹Àü¿¡ ºñÇؼ­ È®¿¬ÇÏ°Ô °£¼ÒÇØÁö°í »¡¶óÁ³´Ù. ÀÌ´Â °¢Á¾ SNS¸¦ ¼±µÎ·Î ÇÏ°í ÀÖ´Â ¸ð¹ÙÀÏ ¼­ºñ½º¿Í ¾ðÁ¦µç »õ·Î¿î ¼­ºñ½º¸¦ ºü¸£°í °£ÆíÇÏ°Ô ¿Ã¸®°í ¼øÀ§ °æÀï¿¡¼­ ¼±µÎ¸¦ ¿Ã·Á¾ß ÇÏ´Â ½ºÅ¸Æ®¾÷ SW¾÷°èÀÇ Æ¯¼ºÀ» ¹Ý¿µÇÑ´Ù. ¾ÈÁ¤¼ºº¸´Ù´Â ºü¸¥ ¹èÆ÷, º¯°æÁ¡ÀÌ »ý±æ ¶§ À绡¸® ³»¸®°í ´Ù½Ã ¿Ã¸± ¼ö ÀÖ´Â ±ä¹ÐÇÔÀÌ ´õ ¿ì¼±ÀÎ °æ¿ì°¡ ¸¹¾ÆÁ³´Ù.


ÀÚ¹ÙÀÇ °æ¿ìµµ ÀÌ·± Ư¼ºÀ» ¹Ý¿µÇÏµí ºü¸¥ ConfigurationÀÌ °¡´ÉÇÏ°í Ãʱ⠼³Á¤Àº ÃÖ´ëÇÑ ÁÙÀÏ ¼ö ÀÖ°í, ¹èÆ÷´Â »¡¸® ÇÒ ¼ö Ç÷§ÆûÀÌ »ý°Ü³µ´Âµ¥, Spring Boot°¡ ´ëÇ¥ÀûÀÎ °æ¿ì·Î, Spring Initializr(https://start.spring.io/)¿¡¼­ ÇÁ·ÎÁ§Æ®¸¦ ¼Â¾÷ÇÏ°í °£´ÜÇÑ REST API¸¦ ¸¸µé¾î¼­ ½ÇÇàÇϱ⠱îÁö 5ºÐ Á¤µµ¸é ÃæºÐÇÏ´Ù. 


ÀÌ´Â ¿¹Àü J2EE ±â¹ÝÀÇ ¼­¹öȯ°æ¿¡¼­ EJB±â¹ÝÀÇ Web ApplicationÀ» °³¹ßÇÏ°í, À̸¦ WAS¿¡ ¿Ã¸®±â À§ÇØ °Þ¾ú´ø ³ë·Â¿¡ ºñÇÏ¸é ¾öû³ª°Ô °£¼ÒÇÏ°í ºÒÇÊ¿äÇÏ°Ô ¹Ýº¹µÇ´Â ÀÛ¾÷À» ȹ±âÀûÀ¸·Î ÁÙ¿©ÁØ °ÍÀÌ´Ù. 


ÇÏÁö¸¸ »ç½Ç Java EE 7¸¸À¸·Îµµ º°´Ù¸¥ ÀÇÁ¸¼º ¾øÀÌ °£´ÜÇÏ°í ºü¸£°Ô REST API¸¦ ¸¸µé ¼ö ÀÖ´Ù. Spring Boot´Â Dependency°¡ Spring Boot¿Í Spring¿¡¼­ Á¦°øÇÏ´Â Spring Framework (Data, Security, Web, µî)¿¡ Àֱ⠶§¹®¿¡ Single OutputÀ¸·Î ¸¸µé¾îÁø JAR Package´Â ¿ë·®ÀÌ »ó´çÇÏ´Ù. 


ÀÌ´Â º¯°æÀÌ °¡´ÉÇÑ Äڵ忡 ºñÇؼ­, Â÷ÁöÇÏ´Â ÀÇÁ¸ ¶óÀ̺귯¸®°¡ ¸¹±â ¶§¹®¿¡ ¹ÎøÇÑ º¯°æ°ú ¹èÆ÷¿¡ ´ëÇؼ­´Â ´ÜÁ¡ÀÌ µÉ ¼ö ÀÖ°Ú´Ù. ÄÁÅ×ÀÌ³Ê ±â¹ÝÀÇ Docker·ÎÀÇ ¹èÆ÷¸¦ ¿¹·Î µéÀÚ¸é, ÀûÃþÀûÀ¸·Î ÇÊ¿äÇÑ ¶óÀ̺귯¸®¸¦ ½×¾Æ°¡´Â (OS->WAS->APP) ÇüÅ¿¡ ´ëÇؼ­, ¾ðÁ¦µç º¯°æ °¡´ÉÇÑ APPÀÇ ¿ë·®ÀÌ ´õ ¸¹ÀÌ Â÷ÁöÇÏ°Ô µÇ´Â »óȲÀÌ µÉ ¼öµµ ÀÖ°Ú´Ù.


ÀÌ¿¡ ¿À´ÃÀº ¼ø¼ö Java EE¸¸À» °¡Áö°í REST API¸¦ ¸¸µå´Â ¹æ¹ýÀ» »ìÆ캸°íÀÚ ÇÑ´Ù. 


Âü°í·Î, ¿¹Á¦¿¡ »ç¿ëµÈ ȯ°æÀº ´ÙÀ½°ú °°´Ù. 


  • OS : Windows 7

  • Java : JDK 1.8

  • IDE : IntelliJ Ultimate Edition

  • WAS : WildFly(http://wildfly.org/) - °¡Àå ÃֽŠ¹öÁ¯ JBOSS EAP¸¦ ¹Þ¾Æ¼­ ¼³Ä¡Çß´Ù.

  • REST Test Tool : POSTMAN(https://www.getpostman.com/) (Chrome App)


Ãʱâ ÇÁ·ÎÁ§Æ® ¼Â¾÷ - MavenÀ¸·Î WebAppÀÇ Skeleton ÇÁ·ÎÁ§Æ®¸¦ ¸¸µç´Ù.

CLI (Command Line Interface)¿¡¼­ Maven ¸í·É¾î¸¦ ÀÌ¿ëÇÏ¿© ¸¸µé°Å³ª, IDE¿¡¼­ MavenÇÁ·ÎÁ§Æ®¸¦ ¸¸µé ¼ö ÀÖ´Ù. ¿©±â¼­´Â ù¹ø° ¹æ¹ý(CLI Maven ¸í·É¾î)À» ÇÁ·ÎÁ§Æ®¸¦ »ý¼ºÇØ º¸°Ú´Ù.


CLI¿¡¼­ Maven ¸í·É¾î¸¦ ÀÌ¿ëÇÏ¿© ÇÁ·ÎÁ§Æ® »ý¼º.

mvn archetype:generate -Dfilter=com.airhacks:javaee7-essentials-archetype


À§¿Í °°ÀÌ ÇÁ·ÎÁ§Æ®¸¦ »ý¼ºÇÏ°íÀÚ ÇÏ´Â »óÀ§ µð·ºÅ丮¿¡¼­ ÀÔ·ÂÇÑµÚ ÇÁ·ÎÁ§Æ®¸¦ »ý¼ºÇÒ ¼ö ÀÖ´Ù. 



´ÙÀ½°ú °°ÀÌ ºôµå°¡ ¼º°øÇÑ´Ù. 



´ÙÀ½°ú °°Àº Æú´õ ±¸Á¶°¡ »ý¼ºµÈ´Ù. (À§¿¡¼­ ÆÐÅ°Áö¸¦ com.moondeuk À¸·Î ¼³Á¤ÇßÁö¸¸ ArchetypeÀÇ Group ID·Î ÆÐÅ°Áö°¡ ¸¸µé¾îÁ³´Ù.)




À̸¦ IDE¿¡¼­ MavenÇÁ·ÎÁ§Æ®·Î OpenÇϵµ·Ï ÇÏ°Ú´Ù.




»ý¼ºµÇ¾îÁø ÇÁ·ÎÁ§Æ®ÀÇ POM ÆÄÀÏ (pom.xml)Àº ´ÙÀ½°ú °°´Ù. ÀÇÁ¸¼ºÀº javaee-api Çϳª·Î, ±×°Íµµ provided·Î WAS°¡ Á¦°øÇÑ´Ù.

<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>com.moondeuk</groupId>
<artifactId>car-build-javaee</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>car-build-javaee</finalName>
</build>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
</project>
view rawpom.xml hosted with ❤ by GitHub


ÀÌÁ¦ º»°ÝÀûÀ¸·Î Code¸¦ ÀÛ¼ºÇØ º¸µµ·Ï ÇÏ°Ú´Ù. ÀÌ ÇÁ·ÎÁ§Æ®ÀÇ ¸ñÀûÀº ÀÏ´Ü 2°¡Áö API¸¦ °®´Â REST ¼­ºñ½º¸¦ ¸¸µå´Â °ÍÀÌ´Ù. 


GET: /cars

POST: /cars


GET ¸Þ¼­µå¿¡¼­´Â ÇöÀç °¡Áö°í ÀÖ´Â CAR¸¦ JSON ÇüÅ·Πº¸¿©ÁÖ°í, POST ¸Þ¼­µå¿¡¼­´Â »õ·Î¿î CAR¸¦ »ý¼ºÇÒ ¼ö ÀÖ´Ù.


Model ClassÀÎ Car¸¦ Á¤ÀÇÇØ º¸µµ·Ï ÇÏÀÚ.


package com.moondeuk;
import javax.validation.constraints.NotNull;
public class Car {
@NotNull
private String pono;
private String model;
private String color;
private String type;
private String year;
public Car() {
}
public Car(String pono, String model, String color, String type, String year) {
this.pono = pono;
this.model = model;
this.color = color;
this.type = type;
this.year = year;
}
public String getPono() {
return pono;
}
public void setPono(String pono) {
this.pono = pono;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Car{");
sb.append("pono='").append(pono).append('\'');
sb.append(", model='").append(model).append('\'');
sb.append(", color='").append(color).append('\'');
sb.append(", type='").append(type).append('\'');
sb.append(", year='").append(year).append('\'');
sb.append('}');
return sb.toString();
}
}
view rawCar.java hosted with ❤ by GitHub



´ÙÀ½ Controller ¿ªÇÒÀ» ÇÏ´Â Class¸¦ ¿ì¼± ¸¸µé¾î º¸µµ·Ï ÇÏ°Ú´Ù.


package com.moondeuk;
import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
@Path("cars")
@Consumes(MediaType.APPLICATION_JSON)
public class CarResource {
@Inject
CarService carService;
@GET
public JsonArray getCars() {
return carService.getCars().stream().map( c ->
Json.createObjectBuilder()
.add("pono", c.getPono())
.add("color", c.getColor())
.add("type", c.getType())
.add("year", c.getYear()).build())
.collect(Json::createArrayBuilder, JsonArrayBuilder::add, JsonArrayBuilder::add).build();
}
@POST
public void createCar(@Valid Car car){
carService.createCar(car);
}
}
view rawCarResource.java hosted with ❤ by GitHub


JAVAÀÇ Ç¥ÁØ REST APIÀÎ JAX-RS´Â ´ÙÀ½°ú °°Àº AnnotationÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. 


@Path - URI path¸¦ ÁöÁ¤ÇÑ´Ù.

@PathParam - URI pathÀÇ parameter¸¦ ³ªÅ¸³½´Ù.

@Consumes - Resource ClassÀÇ ¸Þ¼Òµå°¡ »ç¿ëÇÒ ¹Ìµð¾î ŸÀÔ(XML, PLAIN, JSON, µî)À» ÁöÁ¤ÇÑ´Ù.

@Produces - Resouce ClassÀÇ ¸Þ¼Òµå°¡ »ý¼ºÇÒ ¹Ìµð¾î ŸÀÔ(XML, PLAIN, JSON, µî)À» »ý¼ºÇÑ´Ù.

@GET - GET request¿¡ ¹ÝÀÀÇÏ´Â ¸Þ¼Òµå

@POST - POST request¿¡ ¹ÝÀÀÇϴ ¸Þ¼Òµå

@PUT - PUT request¿¡ ¹ÝÀÀÇÏ´Â ¸Þ¼Òµå

@HEAD - HEAD request¿¡ ¹ÝÀÀÇÏ´Â ¸Þ¼Òµå

@DELETE - DELETE request¿¡ ¹ÝÀÀÇÏ´À ¸Þ¼Òµå

@QueryParam - URLÀÇ Query StringÀÇ Parameter¸¦ ³ªÅ¸³½´Ù.

@HeaderPAram - headerÀÇ parameter¸¦ ³ªÅ¸³½´Ù.

@CookieParam - cookieÀÇ parameter¸¦ ³ªÅ¸³½´Ù.


Âü°í - https://www.javatpoint.com/jax-rs-annotations-example


ÀÌ¿¡ Cars¸¦ ¹ÝȯÇÏ´Â getCars() ¸Þ¼Òµå¿Í »õ·Î¿î Car¸¦ ÀԷ¹ÞÀ» ¼ö ÀÖ´Â createCar(Car car) ¸Þ¼Òµå¸¦ ¸¸µé¾ú´Ù.

¸ÕÀú ÀÌ·¸°Ô Resource¸¦ ¸¸µé°í, ¿¡·¯°¡ ³ª´Â °÷¿¡¼­ IDEÀÇ ÀÚµ¿ »ý¼º ±â´ÉÀ» ÀÌ¿ëÇØ ÇÊ¿äÇÑ ResourceµéÀ» ¸¸µé ¼ö ÀÖ´Ù. (TDDÁ¢±Ù ¹æ½Ä°ú ºñ½ÁÇÏ´Ù.)







±×·¸°Ô Çؼ­ CarService Classµµ »ý¼ºÇÑ´Ù. CarService´Â EJB·Î¼­ ÀÇÁ¸¼º ÁÖÀÔÀ» ¹Þ±â À§ÇØ @Inject¶ó´Â AnnotationÀ» »ç¿ëÇÑ´Ù. ÀÌ·¸°Ô Çϸé WAS Container°¡ °°Àº TypeÀÇ EJB¸¦ ÁÖÀÔÇÏ¿© ÁØ´Ù.

CarService´Â Controller¿¡¼­ »ç¿ëÇϱâ À§ÇÑ EJBÀ̹ǷÎ, @Stateless¶ó´Â EJB AnnotationÀ» »ç¿ëÇÑ´Ù.


package com.moondeuk;
import javax.ejb.Stateless;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Stateless
public class CarService {
public List<Car> cars = new ArrayList<>();
public List<Car> getCars() {
return cars;
}
public void createCar(Car car) {
cars.add(car);
}
}
view rawCarService.java hosted with ❤ by GitHub


pono property À§¿¡ ÀÖ´Â @NotNull AnnotationÀº validator·Î¼­ ÇØ´ç property¿¡ ´ëÇؼ­ NullÀÌ ÀÔ·Â µÇÁö ¾Êµµ·Ï validation¼³Á¤À» ÇÒ ¼ö ÀÖ´Ù.  Resource¿¡¼­ ¹ÞÀº °ªÀÌ NullÀÌ¸é ¿¡·¯¸¦ returnÇÒ °ÍÀÌ´Ù.


¸¶Áö¸·À¸·Î, Å×½ºÆ® ¸ñÀûÀÇ ¼­ºñ½ºÀ̹ǷÎ,  ¹Ì¸® µ¥ÀÌÅ͸¦ ÀÔ·ÂÇØ ³õ±â À§ÇØ serviceÀÇ »ý¼ºÀÚ¿¡ ¾Æ·¡¿Í °°Àº Äڵ带 Ãß°¡Çϵµ·Ï ÇÑ´Ù.


public CarService() {
cars.addAll(Arrays.asList(new Car("A00001", "m01", "blue", "t01", "2017"),
new Car("A00002", "m02", "black", "t01", "2017"),
new Car("A00003", "m01", "white", "t01", "2017"),
new Car("A00004", "m02", "red", "t01", "2017")));
}
view rawCarService.java hosted with ❤ by GitHub


ÀÌ·¸°Ô Çϸé ÀÏÂ÷ÀûÀ¸·Î JAVA EE 7 Container°¡ ½ÇÇàÇÒ ¼ö ÀÖ´Â ·ÎÁ÷Àº ¸¸µé¾îÁø ¼ÀÀÌ´Ù. ¿À´ÃÀº Å×½ºÆ® ¸ñÀûÀ̹ǷΠ°£´ÜÈ÷ ¿©±â±îÁö ÀÛ¼ºÇÑÈÄ ÀÌÁ¦ WAS¿¡ deployÇغ¸µµ·Ï ÇÏ°Ú´Ù.


ÀÏ´Ü JBOSS°¡ runningµÇ°í ÀÖÁö ¾ÊÀ¸¸é ¸ÕÀú ¼­¹ö¸¦ ½ÇÇàÇϵµ·Ï ÇÑ´Ù.



óÀ½ ÇÁ·ÎÁ§Æ®¸¦ »ý¼ºÇÒ¶§ POMÆÄÀÏ¿¡´Â javaee-api ¿Ü¿¡ ´Ù¸¥ ÀÇÁ¸¼ºÀº ¾ø¾úÁö¸¸, JBOSS¿¡ ½±°í ºü¸¥ deploy¸¦ À§Çؼ­ ÇÑ°¡Áö plug inÀ» Ãß°¡Çϵµ·Ï ÇÏ°Ú´Ù.


<build>
<plugins>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>1.2.0.Final</version>
<configuration>
<domain>
<server-groups>
<server-group>${wildfly.domain.serverGroup}</server-group>
</server-groups>
</domain>
</configuration>
</plugin>
</plugins>
</build>
view rawplugin.xml hosted with ❤ by GitHub


JBOSSÀÇ ¼­¹ö±×·ìÀ» ¼³Á¤ÇÑ´Ù. º°´Ù¸¥ ¼³Á¤¾øÀÌ ¼³Ä¡ÇßÀ¸¸é, default·Î ¼³Ä¡µÇ´Â server groupÀÎ main-server-groupÀ» ÀÔ·ÂÇÏ¿© ÁØ´Ù.


ÀÌ·¸°Ô Çϸé, ÀÌÁ¦ MavenÀÇ Ç÷¯±×ÀÎÀ¸·Î JBOSS¿¡ ¼Õ½±°Ô WARÆÄÀÏÀ» DeployÇÒ ¼ö ÀÖ°Ô µÈ´Ù. CLIâ¿¡¼­ ´ÙÀ½À» ÀÔ·ÂÇÑ´Ù.


mvn wildfly:deploy 



¼º°øÀûÀ¸·Î BUILD°¡ µÇ¾ú´Ù´Â °á°ú°¡ ³ª¿À¸é Á¤»óÀûÀ¸·Î build°¡ ¿Ï·áµÇ°í, deploy±îÁö ¿Ï·áµÇ¾ú´Ù´Â »óÅÂÀÌ´Ù.


ÀÚ ÀÌÁ¦ ½ÇÁ¦ ÀÛµ¿ÇÏ´ÂÁö È®ÀÎÇغ¸µµ·Ï ÇÏ°Ú´Ù.


REST API¸¦ Å×½ºÆ®ÇÏ´Â ToolÀÎ Chrome AppÀÇ POSTMANÀ» »ç¿ëÇÏ¿© URI¿¡ ±âº»Æ÷Æ®ÀÎ 8080°ú Maven ÇÁ·ÎÁ§Æ®ÀÇ Final NameÀÎ "car-build-javaee", JAXRSConfiguration¿¡ ¼³Á¤µÈ ApplicationPathÀÎ "resources", ±×¸®°í resourceŬ·¡½ºÀÇ PathÀÎ "cars"¸¦ ÀÌ¿ëÇÏ¿©, ¾Æ·¡¿Í °°Àº URI¸¦ ÀÔ·ÂÇÑ´Ù.


http://localhost:8080/car-build-javavaee/resources/cars 


±×¸®°í Method´Â GETÀ» ¼±ÅÃÇÏ¿©, SEND¸¦ ´©¸£¸é ¾Æ·¡¿Í °°Àº °á°ú°¡ ³ªÅ¸³­´Ù.



POST ¸Þ¼­µåµµ Å×½ºÆ®¸¦ Çغ¸ÀÚ. ´ÙÀ½°ú °°ÀÌ Body¿¡ JSON Çü½ÄÀÇ µ¥ÀÌÅ͸¦ ³Ö°í ¹Ìµð¾î ŸÀÔÀ» JSONÀ¸·Î ÇØÁØ´Ù. ±×¸®°í ³ª¼­, SEND¸¦ ´©¸£¸é, 204 No Content °¡ ³ª¿À¸é Á¤»óÀÌ´Ù. 



±×¸®°í ³ª¼­ ´Ù½Ã GET ¸Þ¼­µå·Î µ¥ÀÌÅ͸¦ È®ÀÎÇغ¸¸é, POST·Î ÀÔ·ÂÇÑ µ¥ÀÌÅÍ°¡ Á¤»óÀûÀ¸·Î ÀԷµǾúÀ½À» ¾Ë ¼ö ÀÖ´Ù. 



ÀÌ·¸°Ô ¼ø¼ö Java EE·Î¸¸ Code¸¦ ÀÛ¼ºÇÏ¿©, WAR ÆÐÅ°Áö·Î WAS¿¡¼­ ±¸µ¿ÇÏ´Â ¹æ¹ýÀ» °£·«È÷ »ìÆì º¸¾Ò´Ù. ÀÌ·¸°Ô Ãʱⱸ¼º°ú °£´ÜÇÑ API¸¦ ±¸¼ºÇϴµ¥, ¸¹Àº ½Ã°£À» µéÀÌÁö ¾Ê°í °³¹ßÇÒ ¼ö ÀÖÀ½À» ¾Ë ¼ö ÀÖ¾ú´Ù. ÆÐÅ°ÁöµÈ warÆÄÀÏÀÇ ¿ë·®Àº ºÒ°ú 7 KB¿¡ ºÒ°úÇÏ´Ù.



Å×½ºÆ®¿¡ »ç¿ëµÈ source code´Â ¾Æ·¡ Github¿¡ ÀÖÀ¸´Ï Âü°íÇϱ⠹ٶõ´Ù.


https://github.com/moondeuk/car-build-javaee



Ãâó: http://moondeuk.tistory.com/102 [Moondeuk]

Ãâó: http://moondeuk.tistory.com/102 [Moondeuk]