Kotlin meets Java EE 8!!!
KotlinサイトとGlass Fishサイトより引用
KotlinサイトとGlass Fishサイトより引用
Java EE 8 MVC 1.0がKotlinで動くの?
はい、動きます。
しなくてもいい苦労をしたくなる僕です。
元ネタ
MVC 1.0(Java EE 8)をとりあえず動かしてみた - Java EE 事始め!
Java EE 8 のearly draftとやら。MVC1.0と言われるJAX-RSとかあたりによく似てる気がしないでもないやつです。
前提
ビルドツール Mavenでやってみます。
正直このぐらいならIDE無くても(頑張れば)出来ます。
IDEとしてEclipseで、Kotlinプラグインを試してみたんだけど上手く行かず。。。。アルファ版出たのに。
・Win7だと上手く言ったんですが、Mac OSXだからなのか。
やること
・Java EE 8動く環境の準備。GlassFish 4.1とか
・プロジェクト作成
・pom変更
・jsp作成
GlassFish 4.1インストール
はしょります
プロジェクト作成
makingさんのブログがとても参考になった。
Kotlinことはじめ - BLOG.IK.AM
ということでだいたいこんな感じで出来上がる。
mvn -B archetype:generate -DgroupId=kotlinweb -DartifactId=kotlin-web -Dversion=1.0.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-quickstart
今回はEclipseで使おうかなぁという気分なので、
mvn eclipse:eclipse
で、Eclipseのプロジェクトファイルも作っておく。
pom変更
pomはこんな感じに変えます。
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>hello</groupId> <artifactId>kotlin-web</artifactId> <packaging>war</packaging> <version>1.0.0-SNAPSHOT</version> <name>KotlinWeb</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>com.oracle.ozark</groupId> <artifactId>ozark</artifactId> <version>1.0.0-m01</version> <scope>compile</scope> </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>KotlinWeb</finalName> <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory> <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory> <plugins> <plugin> <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <version>${kotlin.version}</version> <configuration /> <executions> <execution> <id>compile</id> <phase>process-sources</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>test-compile</id> <phase>process-test-sources</phase> <goals> <goal>test-compile</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <properties> <kotlin0.11.91.1</kotlin <projectUTF-8</project <failOnMissingWebXml>false</failOnMissingWebXml> </properties> </project>
よし、これでpomに僕は今後困らない(たぶん)。
web.xml作成
ブランクというか、すっからかんの作ります。
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> </web-app>
@yy_yank よくよく見ると、Mavenの警告が気になるだけですか?
それだけなら、failOnMissingWebXmlをfalseにすればよいのでは?
— かずひら (@kazuhira_r) 2015, 4月 3
ということで、この作業不要でした!!!
pomのmavenのwarプラグインの設定で解決できます。
クラス作成
これに関しても元記事のほぼパクリですね。
丸パクリも味気無いので、足し算するアプリケーションに変更してみました。
まず、アプリケーションクラス。
MyApplication.kt
package ozarksample import javax.ws.rs.ApplicationPath import javax.ws.rs.core.Application [ApplicationPath("calc")] public class MyApplication : Application() { }
続いて、コントローラクラス
CalcController.kt
package ozarksample.controller import com.oracle.ozark.engine.JspViewEngine import javax.enterprise.context.RequestScoped import javax.inject.Inject import javax.mvc.Controller import javax.mvc.Models import javax.mvc.Viewable import javax.ws.rs.GET import javax.ws.rs.Path import javax.ws.rs.PathParam import java.math.BigDecimal as Decimal [Path("add")] RequestScoped public open class CalcController() { private Inject var models : Models? = null private val pattern = "\\d{1,}".toRegex() open fun isNumericLeftAndRight(left : String, right : String) = pattern.matcher(left).matches() && pattern.matcher(right).matches() open fun putToModels(kvList : List<Pair<String, String>>) { kvList.forEach{ models?.put(it.component1(), it.component2()) } } open fun add(left : String, right : String) = Decimal(left).add(Decimal(right)).toString() GET Controller [Path("{left}/{right}")] open fun calc([PathParam("left")] left : String, [PathParam("right")] right : String) : String { if (!isNumericLeftAndRight(left, right)) { return "error.jsp" } val formulaAndAnswer = listOf( Pair("left", left), Pair("right", right), Pair("answer", add(left, right)) ) putToModels(formulaAndAnswer) return "result.jsp"; } }
JSP作成
これも特に個性なし。
error.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <h1>えらーっぽい<h1> </body> </html>
result.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <%-- EL式でnameを表示 --%> <h1>${left} + ${right} = ${answer}</h1> </body> </html>
デプロイ
mvn clean packageして出来上がったwarをホホイとデプロイ!
そんでこう!
http://localhost:8080/KotlinWeb/calc/add/1/1にアクセス
続いてこう! そんでこう!
http://localhost:8080/KotlinWeb/calc/add/hogehoge/1にアクセス
ということで、簡単にクソアプリが出来ましたとさ。
まとめ
KotlinでJava EE関連のあれこれするのは辛い。
Java EEはJavaのためにあるのであって、
おとなしくKotlin好きな人はWasabiとかkara使おう!
辛いところは。。。。
・フィールドインジェクションが辛い
・open付けないといけないのが辛い
コンストラクタインジェクションにしようかと思ったけど、
CDIでは引数なしのコンストラクタも求められるので、
美しく書けなかった。
siosioさんがやってるみたいにコンストラクタインジェクションが出来れば
varとnullリテラル潰せてちょっとKotlinらしくなるんだけどなぁ。
ということで、そこだけ見ればKotlinでSpring boot使ったほうがいいかなとか
(それでも辛さありそうだけど笑)
KotlinでSpring Bootしてみた - しおしお(´・ω・`)
Kotlin M11からはマルチコンストラクタに対応したが、それでも綺麗には書けないのよね。
こういう感じにしか書けなかったし、これだとインジェクションが上手く行かなかった。
(ここらへんは僕の勘違いがあるかもしれないし、今後仕様が変わる可能性がある)
class="code">public open class CalcController { private Inject var models : Models? = null constructor () { } constructor (val models : Models) { this.models = models } }
こういうのも考えたが、上手く動いてくれなかった。あたりまえだけど。
public open class CalcController { constructor () { } constructor (val models : Models) { GET Controller [Path("{left}/{right}")] open fun calc([PathParam("left")] left : String, [PathParam("right")] right : String) : String { if (!isNumericLeftAndRight(left, right)) { return "error.jsp" val formulaAndAnswer = listOf( Pair("left", left), Pair("right", right), Pair("answer", add(left, right)) ) putToModels(formulaAndAnswer) return "result.jsp"; } } }
openつけないといけないのは、MVC1.0がfinalなメソッドを許してくれないから。
あと、このサンプルだとコントローラーの責務でかくなってきそうだし
Fatな感じになってるのは許して・・・!
という感じでした。
0 件のコメント:
コメントを投稿