Challenge Engineer Life !

エンジニア人生を楽しみたい!仕事や趣味で学んだ技術的なことを書いていくブログです。

Gitpod(Eclipse Theia)でJavaを書いてみる

GWにYouTubeでJava関連の動画を見ていたら、環境構築が大変だよね、みたいな話からDokojavaが紹介されていました。

個人的にはJavaの環境構築が大変だと思ったことはないのですが...学習する上ではブラウザ上で触れる環境があると楽という部分は一理あると思います。ただ、今ならDokojavaより良い環境があるのでは?と思って、Gitpodを触ってみたところ、思っていた以上に手軽でよかったです。Hello Worldレベルですが、簡単に流れを紹介したいと思います。

www.gitpod.io

*つい先日GitHub Codespacesが出てしまったのでGitpodどうなるん...って感じですが...
www.publickey1.jp

GitLabではなくGithubを使う前提です。

1. Githubでリポジトリを作成します
f:id:kikutaro777:20200510205843p:plain

2. ワークスペースを作成します
1で作成したレポジトリのURLを「https://gitpod.io/#」の後に指定します。(ブラウザ上です)
f:id:kikutaro777:20200510210144p:plain

しばらくするとVSCodeと同じ画面が表示されます。
f:id:kikutaro777:20200510210537p:plain

3. JDKディストリビューションの変更
デフォルトでZuluのJDK 11が入っていました。なのでHello Worldを書くこともできます。お手軽ですね。このままZuluで問題ない場合は4まで飛んでください。
f:id:kikutaro777:20200510210641p:plain

今回は他のディストリビューションを使う方法を紹介したいと思います。作成された環境にはSDKMANが入っているため、他のJDKを簡単に試せます。JDKの一覧を表示してみました。

sdk list java

f:id:kikutaro777:20200510210844p:plain

今回はAdoptOpenJDKの14(Hotspot)を入れてみました。

sdk install java 14.0.1.hs-adpt

f:id:kikutaro777:20200510210957p:plain

しばらく待つとインストールされ、デフォルトを変えることもできます。
f:id:kikutaro777:20200510211118p:plain

4. Javaファイルの作成と実行
新しくファイルを作成します。
f:id:kikutaro777:20200510211200p:plain

ファイル名は「Hello.java」にしました。
f:id:kikutaro777:20200510211347p:plain

あとはお決まりの内容を書くだけです。F5あるいはmain関数の上にある「Run」で実行できます。
f:id:kikutaro777:20200510211416p:plain

簡単ですね。
f:id:kikutaro777:20200510211515p:plain

もちろんコード補完もできます。
f:id:kikutaro777:20200510211556p:plain

JShellも使えるので、ちょっとしたお試しならファイルすらいらないですね。
f:id:kikutaro777:20200510211540p:plain

ちなみにMavenやGradleもデフォルトで入っているのですぐ使えました。

こんな感じでGitpodを使えばローカル環境にJavaをインストールしなくても簡単にJavaを触れました。普段VSCodeでJava開発している人にとっては操作もしやすいかもしれません。

今のJavaを知ることができる一冊「みんなのJava」 #minjava

技術評論社から発売された「みんなのJava」を献本いただき、3連休に読みました。ブログのタイトルにしていますが「今のJavaを知る」上で必須の一冊だと思います。

Javaは初心者です、という方は「Javaエンジニア養成読本」の巻頭記事+特集1 Java入門を読んだ後に読むとよさそうです。


第1章 Java 9からJava 14までに起こった変化から見る

きしださん(@kis)メインの章で、Project Valhallaのパートは吉田さん(@shinyafox)が書かれてます。

Java 9以降の変化がキュッとまとまっていて「こんな変更があったんだな」と一気にキャッチアップできる記事です。私自身、Java 8でラムダ式が入って以降Javaの技術情報を追えていなかったので、知識の整理に役立ちました。

「単一ファイルの実行」のように基本的なところでも変化があるため、こういった記事で知っておかないと新人さんに古い知識を教えてしまうなぁと感じました。通常はjavacでコンパイルしてから実行するけど、今こういうときはjavaコマンドですぐ実行できるよ!と、きちんと教えたいですよね。

第2章 JDKに関する疑問と不安解消!JDKディストリビューション徹底解説

JDKソムリエの愛称で親しまれる山田さん(@yamadamn)の記事です。

先日オンラインで行われたJJUGナイトセミナーでも話題になっていましたが、現在、JDKには様々なディストリビューションがあるため選択に迷います。システムの環境に合わせて使う(例えばAWSならAmazon Corretto)のが無難だと思いますが、そういった制約もないような受託開発だと迷走しそうです。

この章では、JDKにはどんな選択肢があるのか?どういう観点を気にするべきか?どう選ぶと良いのか?を学べます。外部の参照リンクも豊富なので、記事を読んで気になったJDKを深掘りする上でも役立ちます。

まさにソムリエという感じの記事でした。

第3章 Java EEからJakarta EE へ 新しいEnterprise Java

日本GlassFish User Group会長の蓮沼さん(@khasunuma)によるJakarta EE解説です。

私が今書いているブログ「Challenge Engineer Life!」はもともと「Challenge Java EE!」というタイトルでした。書き始めた頃は「Java EE」という名前がなくなるとは思ってもみなかったです(^^;

kikutaro777.hatenablog.com

Java EEがJakarta EEとなって以降、歴史から現在の全体像をまとめた日本語記事はこれが初めてだと思います。J2EEやJava EEを触っている人は必読です。

Java EEを全く知らない人は前半を読むのが少しきついかもしれません。そういった方はとりあえず3-3から読んで、チュートリアルを眺めつつ雰囲気を掴むのもありだと思います。(チュートリアルは英語なので結構ヘビーですが、、)

第4章 MicroProfileが拓くJavaのマイクロサービス

MicroProfileってなんぞや、MicroProfileを構成する要素はなんぞや、が把握できます。記事の中でMicroProfile Starterが紹介されていますが、これを使えばサクッと触れるので実際に試しながら読むと良さそうです。

第5章 ネイティブイメージ生成で注目!Javaも他言語も高パフォーマンスGraalVM

Javaチャンピオン&Oracle Groundbreaker Ambassador、阪田さん(@jyukutyo)の記事です。

私自身GraalVM = いろんな言語が動かせる基盤&Polyglotの多言語プログラミング環境、みたいなフワッとしたイメージを持っているだけで中身は全然知らないレベルでした。記事を読んで、中身はこんな構成なんだなーと少しイメージが湧きました。(まだ自分の知識レベルが足りず、口ではうまく説明できなさそうですが)

実際に触る手順も紹介されていたので、時間を見て実際に触りながらもう一度記事を読みたいと思います。

第6章 マイクロサービス,クラウド,コンテナ対応[新世代]軽量フレームワーク入門

前多さん(@kencharos)による記事で、MicronautQuarkusHelidenが紹介されています。

軽量フレームワークと聞くとDropwizardとかSparkとかJavalinとか、おぉ簡単そう!と一瞬食いつくけど、気がつくとあまり見かけなくなっている...という印象が個人的にはあります(^^;でも今回の記事を読むと、紹介されている3つはそれぞれ一歩踏み込んだ特徴があって毛色が違いそうだな、という印象でした(Helidenはちょっとわからないですが...)。

それぞれ試す方法も紹介されているので、これも手を動かして比較するのが一番なのかなと思いました。Graal VM同様、時間を見て実際に触っていきたいです。

ググラビリティの低いPostman APIを呼び出す方法

タイトルのとおり、ググるのに苦戦したのでメモ。

PostmanのWorkspaceやCollectionをAPIで作れないのかな?と思って調べたのですが「Postman Web API」でググってもWeb APIを呼び出すツールとしてのPostman情報しか引っかかりませんでした。まぁ仕方ないですよね。

最終的にみつけたのがこちらのドキュメントです。

docs.api.getpostman.com

API Keyを発行すれば簡単に呼び出せるじゃん!と思って早速やろうとしたのですが、今度はどこからAPI Keyを作るのか辿り着くのに時間がかかりました…。

今だに画面のメニューからの辿り方がわからないのですが(ご存知の方、教えてください)、API Key作成画面のURLはこちら。

https://web.postman.co/integrations/services/pm_pro_api

ドキュメントでは次の赤線部分から辿れます。

Postman API
Postman API

遷移先の画面で「Get API Key」を押せばAPI Keyが発行されます。

Get API Key
Get API Key

こんな感じでJava標準のHttpClientでPostmanのWorkspaceを作成できました。

package tech.kikutaro;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse.BodyHandler;
import java.net.http.HttpResponse.BodyHandlers;

public class App {
    public static void main(String[] args) throws IOException, InterruptedException
    {
        HttpClient client = HttpClient.newHttpClient();

        HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.getpostman.com/workspaces"))
         .header("Content-Type", "application/json")
         .header("x-api-key", "xxxxx")
         .POST(BodyPublishers.ofString("{\"workspace\": {\"name\": \"test\",\"type\": \"personal\",\"description\": \"Some description\"}}"))
         .build();
        HttpResponse<String> res = client.send(req, BodyHandlers.ofString());
        System.out.println(res.statusCode());
        System.out.println(res.body());
    }
}

de:code 2019に参加しました!

5月29日と30日の2日間、Microsoft主催のde:code 2019に参加しました。前回の参加は2017年だったので約2年ぶりでした。当時の参加レポはこちらです。

de:code2016の西脇さんプレゼンが凄かった… - Challenge Java EE !
de:code2017で堀江さん・落合さんセッションが面白かった! - Challenge Java EE !

今回参加したのは次のセッションです。

【Day 1 5/29】

【Day 2 5/30】

以下、それぞれの感想を簡単にまとめます。

続きを読む

Java標準のHTTP ClientからSendGridを使ってメール送信する

2年ほど前に会社ブログでこんな記事を書きました。

JShellからSendGridでメール送信する | SendGridブログ

このときはSendGridのJavaライブラリを利用していたのですが、「あれ?そういえばJava 11で標準のHttp Clientが入ったって聞いた気がする」と思って試してみました。参考にした情報はこちらです。

OpenJDK 12.0.1のJShellで試しました。

jshell> import java.net.http.*
jshell> import java.net.http.HttpRequest.*
jshell> import java.net.http.HttpResponse.*
jshell> var client = HttpClient.newBuilder().build()
jshell> var req = HttpRequest.newBuilder().uri(URI.create("https://api.sendgrid.com/v3/mail/send")).header("Content-Type","application/json").header("Authorization", "Bearer SG.xxxxxxxxxxxxxxxxxxxxxxxxxxxx").POST(BodyPublishers.ofString("{\"personalizations\":[{\"to\":[{\"email\":\"to@example.com\"}]}],\"from\":{\"email\":\"from@example.com\"},\"subject\":\"hello\",\"content\":[{\"type\":\"text/plain\",\"value\":\"content\"}]}")).build()
jshell> client.send(req, BodyHandlers.ofString())

※APIキーとメアドはマスクしています。

JSONの部分はBodyPublishers.ofFileなどでJSONファイルから読み込むのが楽そうですが、とりあえず文字列で指定しました。Raw Stringの記法が入ったらもうちょっとシンプルになりそう。JDK 13待ちかな?

今までJavaでHTTPリクエストを投げるときはApache HttpClientUnirest for Javaを使ってきたので、JShellだとライブラリ読み込みなどが手間だったのですが、標準を使えばシンプルに実行できます。

SendGridのJavaライブラリはApacheのHttpClientに依存しているのだよなぁ。標準で書いてみようかな…。

Twilioを使ってJavaで電話を受けて音声を流そうとしたけど切れてしまう

最近Twilioで遊んでいます。先日、Javaで電話をかけることができました。
kikutaro777.hatenablog.com

今度は電話をうけて、音声を流してみようと思い、以下のQuickstartをやってみました。
jp.twilio.com

受信の仕組みは簡単で次のとおりです。
・Twilioの電話番号に電話をする
・あらかじめTwilioで設定したURLにWebhookで通知する
・Webhookを受けて処理を返す

Webhookの受信サーバとして、ドキュメントではJavaのWebフレームワークであるSparkを使っていましたが、自分はSpring Boot(2.1.3)でやりました。コードはいたってシンプルで次のとおりです。GETメソッドのhelloは確認用で、POSTメソッドが電話の受信処理です。

package tech.kikutaro.twiliowebhook;

import com.twilio.twiml.VoiceResponse;
import com.twilio.twiml.voice.Say;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@RestController
@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

	@GetMapping("/hello")
	public String getMethodName() {
		return "hello";
	}

	@PostMapping("/")
	public String callPhone() {
		Say say  = new Say.Builder("hello").build();
		VoiceResponse voiceResponse = new VoiceResponse.Builder()
				.say(say)
				.build();
		System.out.println(voiceResponse.toXml());
		return voiceResponse.toXml();
	}
}

ローカル環境で起動したサーバをインターネット上に公開するため、ngrokを利用します。

ngrok.exe http 8080

ForwardingのURLが生成されたので、コピーします。
f:id:kikutaro777:20190219225304p:plain

Twilioの「通話着信時」の部分へ設定します。
f:id:kikutaro777:20190219224806p:plain

これで準備が整ったので、自分のスマホからTwilioの電話番号に電話をかけました。すると、電話の応答とともにWebhookでPOSTメソッドが呼び出され、コンソールにも応答で返す以下の内容が表示されました。

<?xml version="1.0" encoding="UTF-8"?><Response><Say>hello</Say></Response>

で、電話から「hello」と流れてくるのを期待していたのですが、なぜかすぐに切れてしまいます。なぜ…?

応答コードなどに問題があるのかと思って、以下の通話ログを確認してみました。

f:id:kikutaro777:20190219225717p:plain

f:id:kikutaro777:20190219225754p:plain

応答は200で、Bodyにしっかりリクエストは入っていて、問題ないようにみえる。。。
f:id:kikutaro777:20190219225837p:plain

とりあえずWebhookで受信はできたけど、音声は流れず残念な結果でした。ググってみたけど意外と情報がなかったので、もうちょっと調べる必要がありそうです。

Twilioを使ってJavaでSMSを送る

今の時代SMS(Short Message Service)を送る需要がどこまであるのか自分はあまりわからないのですが試してみました。

先日、Javaで電話をかける方法を書きました。
kikutaro777.hatenablog.com

SMSの送信も電話同様に簡単で、先日のコードでCallクラスを利用していた部分をMessageクラス(com.twilio.rest.api.v2010.account.Message)にするだけです。

String from = "+xxxxxxxxxx";
String to = "+xxxxxxxxxx";

Message message = Message
        .creator(new PhoneNumber(to),
                 new PhoneNumber(from),
                 "乃木坂46は最高ですね!")
        .create();

が、実行したら以下のエラーとなりました。

Exception in thread "main" com.twilio.exception.ApiException: The From phone number +xxxxxxxxxx is not a valid, SMS-capable inbound phone number or short code for your account.
	at com.twilio.rest.api.v2010.account.MessageCreator.create(MessageCreator.java:505)
	at com.twilio.rest.api.v2010.account.MessageCreator.create(MessageCreator.java:25)
	at com.twilio.base.Creator.create(Creator.java:45)
	at tech.kikutaro.App.main(App.java:32)

先日購入した電話番号はSMSに対応していないものだったのが原因でした。ということで、改めてSMSに対応した番号を購入しました。
f:id:kikutaro777:20190218221608p:plain

fromの電話番号を変えて再度実行すると…SMSが届いた!
f:id:kikutaro777:20190218221743j:plain

うーむ、これまた手軽ですね。

Azure Functionsで環境変数を使う(Java編)

最近、JavaでAzure Functionsを触っています。環境構築の方法は以前Qiitaにまとめました。
qiita.com

今回は環境変数の設定方法について調べました。公式ドキュメントはこちらですが、具体的な設定方法が読み取りにくかったので実際に試した結果とあわせてまとめます。
docs.microsoft.com

内容的には以下の記事そのままです(^^;
jonathangiles.net

ローカルの開発環境の場合

local.settings.jsonValues属性を使います。

local.settings.jsonを開いて
f:id:kikutaro777:20190217094057p:plain

環境変数「MY_ENV_VALUE」を追加しました。

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "java",
    "MY_ENV_VALUE": "env value!"
  }
}

JavaのソースコードではSystem.getenv()を使って環境変数の値を取得できます。

String env = System.getenv("MY_ENV_VALUE");
return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name + " and Env=" +env).build();

実行結果
f:id:kikutaro777:20190217095137p:plain

Azure Functions環境の場合

デプロイ後の実行環境で環境変数を使うには「アプリケーション設定」で設定が必要でした。
f:id:kikutaro777:20190217095406p:plain

設定画面の下のほうにある「アプリケーション設定」にローカル環境で追加した環境変数を定義します。
f:id:kikutaro777:20190217095650p:plain

追加したら「保存」を忘れずに。自分は最初ここの保存を忘れて「あれ、反映されない」と少しハマっていました;
f:id:kikutaro777:20190217095746p:plain

しばらくすると設定が反映されて、アクセスすると、次のように環境変数の結果が表示されました。
f:id:kikutaro777:20190217095953p:plain

Twilioを使ってJavaで電話をかけて音声を流す

ご存知の方も多いかと思いますが、SendGridは2/1に正式にTwilioの中に入りました。

せっかくなのでTwilioを触ってみようと思って、早速Javaを使って遊んでみました。びっくりするぐらい簡単に自分の携帯へ電話をかけて、音声を流すことができたのでまとめます。チュートリアル通りに進めるだけで電話をかけて&英語で話をする、というのができます。音声の内容はTwiMLというマークアップを使って簡単に定義できるので、そこだけプラスアルファしました。

※アカウントは作成済の前提です

電話番号を取得

ダッシュボードから「番号を取得する」を押します。
f:id:kikutaro777:20190215223021p:plain

国を選んで使える電話番号を検索します。国は自由に選べますが、アメリカだと月額150円で、日本だと月額108円でした。国によっては高い(トリニダードトバゴは4,050円とか)です。今回は日本を選びました。
f:id:kikutaro777:20190215223219p:plain

好きな番号を選んで「購入」します。
f:id:kikutaro777:20190215223757p:plain

購入確認がでるので「この番号を購入する」を押します。
f:id:kikutaro777:20190215223912p:plain

以上で電話番号の取得は終わりです。

Javaアプリケーションを作成

チュートリアルによるとJDKは7以上であればよいそうです。自分の環境はOracle JDK 1.8.0_152を使いました。(Java 11を入れていたのですが、別途触っていたAzure Functionsが動かず古いものに戻したため。。)

Mavenを使ってプロジェクトを作成し、pom.xmlに以下を加えました。チュートリアルにあるバージョンは7.17.0でしたが、新しい7.35.0を使いました。

<dependency>
    <groupId>com.twilio.sdk</groupId>
    <artifactId>twilio</artifactId>
    <version>7.35.0</version>
</dependency>

まずはチュートリアルそのままのコードを試しました。

package tech.kikutaro;

import java.net.URI;
import java.net.URISyntaxException;

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Call;
import com.twilio.type.PhoneNumber;

public class App {
    public static final String ACCOUNT_SID = "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    public static final String AUTH_TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

    public static void main(String[] args) throws URISyntaxException
    {
        Twilio.init(ACCOUNT_SID, AUTH_TOKEN);

        String from = "+81xxxxxxxxx"; //取得した電話番号
        String to = "+81xxxxxxxxx"; //通話相手の電話番号(今回は自分の持ってるスマホの電話番号)

        Call call = Call.creator(new PhoneNumber(to), new PhoneNumber(from),
                new URI("http://demo.twilio.com/docs/voice.xml")).create();

        System.out.println(call.getSid());
    }
}

ACCOUNT_SIDAUTH_TOKENはダッシュボードに表示されているので、これを使うだけです。
f:id:kikutaro777:20190215225451p:plain

Javaアプリケーションを実行

実行すると、こんな感じで普通に電話がかかってきます。
f:id:kikutaro777:20190215230020p:plain

電話に出ると「Thanks for trying our documentation. Enjoy!」と英語の音声が流れて、そのあとに切れます。めっちゃ簡単!!!

この音声の定義はCallクラスの定義で指定している「http://demo.twilio.com/docs/voice.xml」のXMLで決まります。このXMLはTwiMLというマークダウンです。
f:id:kikutaro777:20190215230147p:plain

音声の内容を変える

どうせなら日本語の音声を流したいなー、と思ってやってみました。TwiMLの定義も画面から簡単にできるようになっていて、RuntimeのメニューからTwiMLを選んで作成するだけです。
f:id:kikutaro777:20190215230646p:plain

内容を次のようなものにしました。sayで指定可能な属性より日本語を指定しました。loopは繰り返しです。
f:id:kikutaro777:20190215230738p:plain

これでもう一度電話をかけると、日本語で「乃木坂フォーティーシックスっていいグループですよね」という音声が2回流れます。うーむすごい。簡単すぎる。

Javaで脳内メーカーみたいなサービスを作ってみた

先日、久しぶりに「脳内メーカー」を試したときに

「同じ名前を入れると結果が同じだけど、どういう仕組みなんだろう?」
「どうやって画像を作っているんだろう?」

と内部的なところに興味がでて、自分も似たようなWebアプリを作ってみたいなぁと考えるようになりました。Javaを使って自分だったらどう実装するか考えたり調べたりしながら、ここ1ヶ月コツコツとプログラミングしてました。

まだ細かいエラー処理などの実装が必要ですが、とりあえず乃木坂46 21枚目の選抜発表に合わせて7/1にリリースしました。

www.rpgparty.sakamichi46.com

トップページはこんな感じで、ゲーム感を出してみました。

f:id:kikutaro777:20180702233924g:plain

メッセージがピコピコ流れていますが、これは iTyped.js というJavaScriptライブラリを使って、タイプライター風に表示しています。

フォントは PixelMplus(ピクセル・エムプラス)を使いました。漢字まで含まれていて素晴らしすぎる…。ライセンスの自由度も素晴らしすぎる…。
itouhiro.hatenablog.com

アプリの内容は脳内メーカーと同じです。名前を入れたらランダムで乃木坂メンバーをピックアップしてRPGパーティを組むというもの。完全なランダムではなく、名前の文字が同じであれば同じパーティとなります。

f:id:kikutaro777:20180703005804p:plain

「キクタロー」の結果はこちらです。

f:id:kikutaro777:20180702233359j:plain

豪華すぎる結果になってますが、開発者が有利になるような仕組みは入っておりませんのであしからず(^^;

ちなみにドット絵も頑張って作りました(^^;dotpictというアプリが素晴らしくて、スマホで簡単にドット絵を作れるので、外にいるときでも空き時間とかに作っていました。

dotpicko.net

以下のサイトでベースを作って、あとは乃木坂の制服や衣装にあわせた感じです。

ちびキャラを描いてみよう編【現役ゲームクリエイターによるドット基礎講座 第2回】 - Creatures Garage

「Peing - 質問箱 -」なども大流行りですが、あれはツイートしたときに表示されるカード画像が目立つことが人気の一端になっていると思っています。なので、自分もああいう仕組みも入れたいなと思いました。画像はJavaのGraphicを使って生成しているのですが、最初はそれをbase64にしてhtml表示していました。ただ、これだとTwitter Cardで表示されないという…。どうやら静的なURLが必要なようです。(この辺? 詳しい方いたら教えて欲しい…)

AWSのS3とか使って画像を保存させるしかないのか…と思っていたのですが、調べてみたら Cloudinary という画像・ビデオのアップロード&加工が簡単にできるサービスがありました。試したら便利だったので今はこれを利用しています。

cloudinary.com

Freeプランでもかなり使えます。
f:id:kikutaro777:20180703004342p:plain

これで以下のような形でTwitter Cardがしっかり表示できるようになりました。この辺は実装してみないとわからないものですね。

Webのフロントhtmlは Netlify に置いて、パーティや画像の生成をするサーバサイドは Heroku を使っています。Webフレームワークは Spring Boot + Thymeleaf です。

乃木坂ファンをターゲットに作っていますが、乃木坂46をあまり知らない方も是非お試し欲しいなと思います。そして出て来たメンバーを是非知ってもらえると嬉しいです><;需要があれば、欅坂46、けやき坂46(ひらがなけやき)にも対応します!

にほんブログ村 IT技術ブログへ
にほんブログ村 にほんブログ村 IT技術ブログ Javaへ
にほんブログ村