1. 개요
Jooby 는 가장 많이 사용되는 NIO 웹 서버 위에 구축된 확장 가능하고 빠른 마이크로 웹 프레임워크 입니다. 매우 간단하고 모듈식이며 현대 웹 아키텍처에 맞게 명확하게 설계되었습니다. Javascript 및 Kotlin 도 지원합니다.
기본적으로 Jooby 는 Netty, Jetty 및 Undertow 를 훌륭하게 지원합니다 .
이 기사에서는 전반적인 Jooby 프로젝트 구조와 Jooby를 사용하여 간단한 웹 애플리케이션을 빌드하는 방법에 대해 알아봅니다 .
2. 애플리케이션 아키텍처
간단한 Jooby 애플리케이션 구조는 다음과 같습니다.
├── public
| └── welcome.html
├── conf
| ├── application.conf
| └── logback.xml
└── src
| ├── main
| | └── java
| | └── com
| | └── baeldung
| | └── jooby
| | └── App.java
| └── test
| └── java
| └── com
| └── baeldung
| └── jooby
| └── AppTest.java
├── pom.xml
여기서 주목할 점은 공용 디렉토리에 css/js/html 등과 같은 정적 파일을 넣을 수 있다는 것입니다. conf 디렉토리에는 logback.xml 또는 application.conf 등과 같이 애플리케이션에 필요한 모든 구성 파일을 넣을 수 있습니다 .
3. 메이븐 의존성
pom.xml 에 다음 의존성을 추가하여 간단한 Jooby 애플리케이션을 만들 수 있습니다 .
<dependency>
<groupId>org.jooby</groupId>
<artifactId>jooby-netty</artifactId>
<version>1.1.3</version>
</dependency>
Jetty 또는 Undertow 를 선택하려는 경우 다음 의존성을 사용할 수 있습니다.
<dependency>
<groupId>org.jooby</groupId>
<artifactId>jooby-jetty</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.jooby</groupId>
<artifactId>jooby-undertow</artifactId>
<version>1.1.3</version>
</dependency>
Central Maven Repository 에서 최신 버전의 Jooby 프로젝트를 확인할 수 있습니다 .
Jooby 에는 전용 Maven 원형도 있습니다. 이를 사용하여 필요한 모든 의존성이 미리 빌드된 샘플 프로젝트를 만들 수 있습니다.
다음 스크립트를 사용하여 샘플 프로젝트를 생성할 수 있습니다.
mvn archetype:generate -B -DgroupId=com.baeldung.jooby -DartifactId=jooby
-Dversion=1.0 -DarchetypeArtifactId=jooby-archetype
-DarchetypeGroupId=org.jooby -DarchetypeVersion=1.1.3
4. 애플리케이션 구축
4.1. 서버 시작
임베디드 서버를 시작하려면 다음 코드 스니펫을 사용해야 합니다.
public class App extends Jooby {
public static void main(String[] args) {
run(App::new, args);
}
}
일단 시작되면 서버는 기본 포트 8080 에서 실행됩니다 .
사용자 정의 포트 및 사용자 정의 HTTPS 포트 로 백엔드 서버를 구성할 수도 있습니다 .
{
port( 8081 );
securePort( 8443 );
}
4.2. 라우터 구현
Jooby 에서 경로 기반 라우터를 만드는 것은 매우 쉽습니다 . 예를 들어 다음과 같은 방법으로 ' /login ' 경로에 대한 라우터를 만들 수 있습니다 .
{
get( "/login", () -> "Hello from Baeldung");
}
비슷한 방식으로 POST, PUT 등과 같은 다른 HTTP 메서드를 처리하려는 경우 아래 코드 스니펫을 사용할 수 있습니다.
{
post( "/save", req -> {
Mutant token = req.param( "token" );
return token.intValue();
});
}
여기에서는 요청에서 요청 매개변수 이름 토큰을 가져옵니다. 기본적으로 모든 요청 매개변수는 Jooby 의 Mutant 데이터 유형으로 유형 변환됩니다. 기대에 따라 지원되는 기본 데이터 유형으로 변환할 수 있습니다.
다음과 같은 방법으로 모든 URL 매개변수를 확인할 수 있습니다.
{
get( "/user/{id}", req -> "Hello user : " + req.param("id").value() );
get( "/user/:id", req -> "Hello user: " + req.param("id").value() );
}
우리는 위의 것을 사용할 수 있습니다. 고정 콘텐츠로 시작하는 매개변수를 찾는 것도 가능합니다. 예를 들어 다음과 같은 방법으로 ' uid:' 로 시작하는 URL 매개변수를 찾을 수 있습니다.
{
get( "/uid:{id}", req -> "Hello User with id : uid" +
req.param("id").value());
}
4.3. MVC 패턴 컨트롤러 구현
엔터프라이즈 애플리케이션의 경우 Jooby 는 Spring MVC와 같은 다른 MVC 프레임워크와 마찬가지로 MVC API와 함께 제공됩니다.
예를 들어 ' /hello ' 라는 경로를 처리할 수 있습니다 .
@Path("/hello")
public class GetController {
@GET
public String hello() {
return "Hello Baeldung";
}
}
매우 유사하게 @POST , @PUT, @DELETE 등의 어노테이션 을 사용하여 다른 HTTP 메서드를 처리하는 핸들러를 만들 수 있습니다 .
4.4. 정적 콘텐츠 처리
HTML, Javascript, CSS, 이미지 등과 같은 정적 콘텐츠를 제공하려면 해당 파일을 공용 디렉터리에 배치해야 합니다.
배치되면 라우터에서 모든 URL을 다음 리소스에 매핑할 수 있습니다.
{
assets( "/employee" , "form.html" );
}
4.5. 취급 양식
기본적으로 Jooby의 요청 인터페이스는 수동 유형 캐스팅을 사용하지 않고 모든 양식 개체를 처리합니다.
양식을 통해 직원 세부 정보를 제출해야 한다고 가정해 보겠습니다. 첫 번째 단계에서 데이터를 보유하는 데 사용할 Employee 빈 객체를 생성해야 합니다.
public class Employee {
String id;
String name;
String email;
// standard constructors, getters and setters
}
이제 양식을 만들기 위해 페이지를 만들어야 합니다.
<form enctype="application/x-www-form-urlencoded" action="/submitForm"
method="post">
<input name="id" />
<input name="name" />
<input name="email" />
<input type="submit" value="Submit"/>
</form>
다음으로 이 양식을 처리하고 제출된 데이터를 가져오는 포스트 핸들러를 생성합니다.
post( "/submitForm", req -> {
Employee employee = req.params(Employee.class);
// ...
return "empoyee data saved successfullly";
});
여기서 주목해야 할 점 은 동적 양식 바인딩을 지원하려면 양식 enctype 을 application/x-www-form-urlencoded 로 선언해야 한다는 것 입니다.
Request.file(String filename) 을 통해 업로드된 파일을 검색할 수 있습니다.
post( "/upload", req -> {
Upload upload = req.file("file");
// ...
upload.close();
});
4.6. 필터 구현
즉시 사용 가능한 Jooby 는 전역 필터와 경로 기반 필터를 정의할 수 있는 유연성을 제공합니다.
Jooby 에서 필터를 구현 하는 것은 URL 경로를 필터에 대해 한 번, 핸들러에 대해 다시 한 번, 두 번 구성해야 하기 때문에 약간 까다롭습니다 .
예를 들어 ' /filter' 라는 URL 경로에 대한 필터 를 구현해야 하는 경우 이 경로에 명시적으로 필터를 구현해야 합니다.
get( "/filter", ( req, resp, chain ) -> {
// ...
chain.next( req, resp );
});
구문은 Servlet 필터와 매우 유사합니다. 요청을 제한하고 Response.send(Result result) 메서드 를 호출하여 필터 자체에서 응답을 다시 보낼 수 있습니다.
필터가 구현되면 요청 핸들러를 구현해야 합니다.
get("/filter", (req, resp) -> {
resp.send("filter response");
});
4.7. 세션
Jooby 에는 두 가지 유형의 세션 구현이 있습니다. 인 메모리 및 쿠키 기반.
메모리 내 세션 관리를 구현하는 것은 매우 간단합니다. EhCache, Guava, HazleCast, Cassandra, Couchbase, Redis, MongoDB 및 Memcached 와 같이 Jooby 에서 사용할 수 있는 처리량이 많은 세션 저장소를 선택할 수 있는 옵션이 있습니다 .
예를 들어 Redis 기반 세션 저장소를 구현하려면 다음 Maven 의존성을 추가해야 합니다.
<dependency>
<groupId>org.jooby</groupId>
<artifactId>jooby-jedis</artifactId>
<version>1.1.3</version>
</dependency>
이제 아래 코드 조각을 사용하여 세션 관리를 활성화할 수 있습니다.
{
use(new Redis());
session(RedisSessionStore.class);
get( "/session" , req -> {
Session session = req.session();
session.set("token", "value");
return session.get("token").value();
});
}
여기서 주목할 점 은 application.conf 에서 Redis url을 'db' 속성 으로 구성할 수 있다는 것 입니다.
쿠키 기반 세션 관리를 활성화하려면 cookieSession() 을 선언해야 합니다 . 쿠키 기반 접근 방식을 선택한 경우 application.conf 파일 에서 application.secret 속성 을 선언해야 합니다. 서명되는 각 쿠키는 이 비밀 키로 서명되므로 항상 긴 임의 문자열 조각을 비밀 키로 사용하는 것이 좋습니다.
인 메모리 및 쿠키 기반 접근 방식 모두에서 application.conf 파일에 필요한 구성 매개 변수를 선언해야 합니다. 그렇지 않으면 응용 프로그램이 시작할 때 IllegalStateException 이 발생합니다.
5. 테스트
경로가 일부 클래스의 전략에 바인딩되어 있기 때문에 MVC 경로를 테스트하는 것은 실제로 쉽습니다. 이렇게 하면 모든 경로에 대해 단위 테스트를 쉽게 실행할 수 있습니다.
예를 들어 기본 URL에 대한 테스트 사례를 빠르게 만들 수 있습니다.
public class AppTest {
@ClassRule
public static JoobyRule app = new JoobyRule(new App());
@Test
public void given_defaultUrl_expect_fixedString() {
get("/").then().assertThat().body(equalTo("Hello World!"))
.statusCode(200).contentType("text/html;charset=UTF-8");
}
}
여기서 주목해야 할 점은 @ClassRule 어노테이션을 사용하면 모든 테스트 사례에 대해 하나의 서버 인스턴스만 생성된다는 것입니다. 모든 테스트 케이스에 대해 별도의 서버 인스턴스를 구축해야 하는 경우 정적 수정자 없이 @Rule 어노테이션을 사용해야 합니다.
또한 Jooby의 MockRouter 를 사용 하여 동일한 방식으로 경로를 테스트할 수 있습니다.
@Test
public void given_defaultUrl_with_mockrouter_expect_fixedString()
throws Throwable {
String result = new MockRouter(new App()).get("/");
assertEquals("Hello World!", result);
}
6. 결론
이 예제에서는 Jooby 프로젝트와 그 필수 기능을 살펴보았습니다.
항상 그렇듯이 전체 소스 코드는 GitHub에서 사용할 수 있습니다 .