2017年4月23日日曜日

gradle で Jersey 入門

概要

Jersey は RESTful な API を開発するための Java のフレームワークです
今回は Hello World として gradle を使って Jersey を動作させてみました
また、テストも作成しています

環境

  • Ubuntu 16.04
  • gradle 3.5
  • OpenJDK 8u121-b13
  • Jersey 2.14

事前作業

gradle のインストールはこちら

  • apt -y install openjdk-8-jdk

プロジェクト作成

  • mkdir gradle-jersey
  • cd gradle-jersey
  • vim build.gradle
apply plugin: 'java'
apply plugin: 'jetty'

repositories {
  mavenCentral()
}

dependencies {
  testCompile 'junit:junit:4.11'
  testCompile 'org.hamcrest:hamcrest-all:1.3'
}

test {
  exclude '**/*IntegrationTest*'
}

task integrationTest(type: Test) {
  include '**/IntegrationTest*'
  doFirst {
    jettyRun.httpPort = 8080
    jettyRun.daemon = true
    jettyRun.execute()
  }
  doLast {
    jettyStop.stopPort = 8091
    jettyStop.stopKey = 'stopkey'
    jettyStop.execute()
  }
}
  • gradle build

でとりあえずビルドが成功することを確認しましょう

テスト作成

  • mkdir -p src/test/java/com/hawksnowlog/hello/webapp
  • vim src/test/java/com/hawksnowlog/hello/webapp/HelloIntegrationTest.java
package com.hawksnowlog.hello.webapp;

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;

import org.junit.Test;

public class HelloIntegrationTest {

    private static String HELLO_URL = "http://localhost:8080/hello";

    @Test
    public void testHello() throws Exception {
        Client client = ClientBuilder.newClient();
        WebTarget wt = client.target(HELLO_URL);
        String r = wt.request().get(String.class);
        assertThat(r, is("Hello World!"));
    }

}
  • vim build.gradle

一部抜粋

dependencies {
  testCompile 'junit:junit:4.11'
  testCompile 'org.hamcrest:hamcrest-all:1.3'
  compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.14'
}
  • gradle integrationTest

と実行すると specified for property 'webAppSourceDirectory' does not exist. と言われるのでとりあえずプロパティを追加する

  • vim build.gradle

一部抜粋

task integrationTest(type: Test) {
  include '**/*IntegrationTest*'
  doFirst {
    jettyRun.webAppSourceDirectory = file("src/main/java/com/hawksnowlog/hello/webapp")
    jettyRun.contextPath = '/'
    jettyRun.httpPort = 8080
    jettyRun.daemon = true
    jettyRun.execute()
  }
  doLast {
    jettyStop.stopPort = 8091
    jettyStop.stopKey = 'stopkey'
    jettyStop.execute()
  }
}

で再度実行して 404 のエラーとなりテストがこけることを確認する
javax.ws.rs.NotFoundException at HelloIntegrationTest.java:20

web アプリのコード作成

404 にならないように本体のアプリを作成する

  • mkdir -p src/main/java/com/hawksnowlog/hello/webapp
  • vim src/main/java/com/hawksnowlog/hello/webapp/HelloWebapp.java
package com.hawksnowlog.hello.webapp;

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/hello")
public class HelloWebapp {

    @GET()
    public String hello() {
        return "Hello World!";
    }
}
  • mkdir -p src/main/webapp/WEB-INF/
  • vim src/main/webapp/WEB-INF/web.xml
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Jetty Gradle Hello World</display-name>
  <servlet>
    <servlet-name>HelloWorldServlet</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>com.hawksnowlog.hello.webapp</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>HelloWorldServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

web.xml の内容は正直自分もよくわかっていないのでおまじないです
一番のポイントは jersey.config.server.provider.packages でアプリのパッケージを指定しているところだと思います

  • gradle integrationTest

でビルドが成功すると思います
この状態で curl localhost:8080/hello を実行してみると「Hello World!」が返ってくることも確認できると思います
(本当は doLast で jettyStop しているので止まるはずなんですが、止まらない、、、)

ちなみに web.xml を作成後は build.grdle で定義している jettyRun.webAppSourceDirectory = file("src/main/java/com/hawksnowlog/hello/webapp") は削除しても動作します

最後に

gradle で Jersey を試してみました
あとは Path を追加するなり DAO 的なのを作ったりしていけば OK じゃないかなと思います

Java の場合 war ファイルを作成する必要もあるので、そのあたりのビルドフローも build.gradle に追加すればいんじゃないかなと思います
久しぶりに Java を使ってみましたが、やはり Java は辛いイメージです

「Hello World」を表示するだけなのにこれだけコードを記述する必要があるのが辛い点です

参考サイト

0 件のコメント:

コメントを投稿