超高速に初めるJAX-RS + Guice

JAX-RSの起動は前回さくっと終わらせた。
http://d.hatena.ne.jp/shin/20161204/p1

あとはロジック回り。今回はGoogle Guiceを使う。CDIを使うならWeldSEは使わずpayara microなどEEコンテナをちゃんと立ち上げたほうが良い。

Guiceとのコネクタは用意されているのでそれを使おう。

依存ライブラリの追加

前回の状態からさらに依存関係に以下の1行を追加する

compile "org.glassfish.hk2:guice-bridge:2.5+"

おわり。JAX-RSの依存も前回の1行だけだったのであわせて2行だけ。

やること

前回作ったCalcというリソースクラスにFormatLogicという文字列を返すクラスのシングルトンのインスタンスを注入する。
そのクラスを使い、結果を返す。

プログラム

今回もソースコード一つ。

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import java.net.URI;
import java.util.Scanner;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;

import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.jersey.ServiceLocatorProvider;
import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.jvnet.hk2.guice.bridge.api.GuiceBridge;
import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge;

public class Main {

    //--------------------------------------------------------------------------
    //サーバー起動
    //--------------------------------------------------------------------------
    public static void main(String[] args) {
        
        URI uri = UriBuilder.fromUri("http://localhost/").port(8080).build();
        ResourceConfig config = new ResourceConfig(GuiceFeature.class, Calc.class);
        JdkHttpServerFactory.createHttpServer(uri, config);

        //Enter押すまで待つ
        new Scanner(System.in).nextLine();

        System.exit(0);
    }
    
    //--------------------------------------------------------------------------
    //JAX-RSリソースクラス
    //--------------------------------------------------------------------------
    @Path("calc")
    public static class Calc {
        @Inject
        FormatLogic logic;
        

        //http://localhost:8080/calc?a=1&b=2
        @GET
        @Produces(MediaType.TEXT_PLAIN)
        public String add(@QueryParam("a") int a, @QueryParam("b") int b) {
//            System.out.println("calc:"+this);
            return logic.format(a, b);
        }
        
    }
    
    //--------------------------------------------------------------------------
    //GUICEのセットアップ
    //--------------------------------------------------------------------------
    public static class GuiceFeature implements Feature {
        @Override
        public boolean configure(FeatureContext context) {
            ServiceLocator locator = ServiceLocatorProvider.getServiceLocator(context);
            GuiceBridge.getGuiceBridge().initializeGuiceBridge(locator);
            final Injector injector = Guice.createInjector(new AbstractModule() {
                @Override
                protected void configure() {
                }
            });
            GuiceIntoHK2Bridge guiceBridge = locator.getService(GuiceIntoHK2Bridge.class);
            guiceBridge.bridgeGuiceInjector(injector);
            return true;
        }
    }
    
    //--------------------------------------------------------------------------
    //注入される
    //--------------------------------------------------------------------------
    @Singleton
    public static class FormatLogic{
        public String format(int a, int b){
//            System.out.println("logic:"+this);
            return String.format("%d + %d = %d", a, b, a+b);
        }
    }

}

実行

http://localhost:8080/calc?a=1&b=2

というURLをブラウザで表示すると

1 + 2 = 3

と表示される。