《Kotlin 程序設(shè)計(jì)》第八章 Kotlin 集成Spring Boot開發(fā)

第八章 Kotlin 集成Spring Boot開發(fā)

Java整個(gè)生態(tài)系統(tǒng)經(jīng)過近20年的發(fā)展,已經(jīng)非常成熟完整了。相對(duì)于年輕的Kotlin而言,我們不可能一下子拋棄整個(gè)Java生態(tài)系統(tǒng)。至少在目前,運(yùn)行在全世界的互聯(lián)網(wǎng)服務(wù)器上的大多數(shù)服務(wù)依然是整個(gè)Java生態(tài)的天下。

然而,在Java生態(tài)中最為出色的莫過于Spring框架體系了。尤其是近兩年來,Spring Boot以及微服務(wù)的出現(xiàn),使得Spring框架更加出色。

在Spring 5 中,已經(jīng)增加了使用Kotlin的實(shí)現(xiàn)。

使用Kotlin 與 Spring Boot 開發(fā)真的是如絲般潤(rùn)滑。本章我們介紹使用Kotlin + Spring Boot創(chuàng)建一個(gè)RESTful服務(wù),并開發(fā)一個(gè)簡(jiǎn)單的Web系統(tǒng)。

Step1. html頁面加入頭文件 相應(yīng)的schema

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">

Step2.主頁面模板


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<th:block th:include="common/header :: head"></th:block>

<body>
<th:block th:include="common/header :: header"></th:block>

<div th:if="${not #lists.isEmpty(customers)}">
    <h2>Customer List</h2>
    <table id="customersTable" class="table table-striped">
        <thead>
        <tr>
            <th>Id</th>
            <th>FirstName</th>
            <th>LastName</th>
            <th>Created Time</th>
        </tr>
        </thead>

        <tbody>
        <tr th:each="customer : ${customers}">
            <td th:text="${customer.id}"><a href="/product/${product.id}">Id</a></td>
            <td th:text="${customer.firstName}">FirstName</td>
            <td th:text="${customer.lastName}">LastName</td>
            <td th:text="${customer.gmtCreated}">gmtCreated</td>
            <!--<td><a th:href="${ '/product/' + product.id}">View</a></td>-->
            <!--<td><a th:href="${'/product/edit/' + product.id}">Edit</a></td>-->
        </tr>
        </tbody>

    </table>

</div>

<th:block th:include="common/footer :: footer"></th:block>

</body>
</html>


Step3.include common模板說明

common/header.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en" th:fragment="head">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

    <link 
          th:href="@{/webjars/bootstrap/3.3.4/css/bootstrap.min.css}"
          rel="stylesheet" media="screen"/>


    <link href="../../static/css/jquery.dataTables.min.css"
          th:href="@{css/jquery.dataTables.min.css}" rel="stylesheet" media="screen"/>

    <link href="../../static/css/mini_springboot.css"
          th:href="@{css/mini_springboot.css}" rel="stylesheet" media="screen"/>

    <title>Mini SpringBoot Tutorial</title>
</head>

<body>

<div th:fragment="header">
    <nav class="navbar navbar-default">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" href="#" th:href="@{/}">Home</a>
                <ul class="nav navbar-nav">
                    <li><a href="#" th:href="@{/customers.do}">Customers</a></li>
                    <li><a href="#" th:href="@{/customer/new}">Create Customer</a></li>
                </ul>

            </div>
        </div>
    </nav>

    <div class="jumbotron">
        <div class="row text-center">
            <div class="">
                <h1 class="center">Springboot極簡(jiǎn)教程</h1>
                <h2>Mini SpringBoot Tutorial</h2>
                <h3>Spring Boot Kotlin Thymeleaf Web App</h3>
            </div>
        </div>
        <div class="row text-center">
            <iframe class="iframe" src="https://jason-chen-2017.github.io/Jason-Chen-2017/"></iframe>

            <!--![](../../static/images/home.png)-->
        </div>
    </div>

</div>

</body>
</html>

common/footer.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>


<div th:fragment="footer">

    <div class="footer">Springboot極簡(jiǎn)教程, Jason Chen, 2017</div>


    <script src="http://cdn.jsdelivr.net/webjars/jquery/2.1.4/jquery.min.js"
            th:src="@{/webjars/jquery/2.1.4/jquery.min.js}"></script>


    <script src="http://cdn.jsdelivr.net/webjars/bootstrap/3.3.4/js/bootstrap.min.js"
            th:src="@{/webjars/bootstrap/3.3.4/js/bootstrap.min.js}"></script>

    <script src="../../static/js/jquery.dataTables.min.js"
            th:src="@{js/jquery.dataTables.min.js}"></script>

    <script src="../../static/js/mini_springboot.js" th:src="@{js/mini_springboot.js}"></script>

</div>


</body>
</html>

重點(diǎn)看一下thymeleaf的語法設(shè)計(jì)風(fēng)格。

寫一個(gè)th:fragment="{id}"

<div th:fragment="footer">

    。。。

</div>

可以直接在其他頁面 th:include

<th:block th:include="common/footer :: footer"></th:block>

<h5>Step4. 配置build.gradle,添加spring-boot-starter-thymeleaf

Spring Boot默認(rèn)就是使用thymeleaf模板引擎的,所以只需要在build.gradle(pom.xml)加入依賴即可。

version = "0.0.1-SNAPSHOT"

buildscript {

    ext {
        springBootVersion = "1.5.2.RELEASE"
        kotlinVersion = "1.1.0"
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion")
        classpath("org.jetbrains.kotlin:kotlin-noarg:$kotlinVersion")
        classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
    }
}

apply {
    plugin("kotlin")
    plugin("kotlin-spring")
    plugin("kotlin-jpa")
    plugin("org.springframework.boot")
    plugin 'java'
    plugin 'eclipse'
    plugin 'idea'
//    plugin: 'spring-boot'
}

repositories {
    mavenCentral()
}

jar {
    baseName = 'mini_springboot'
    version = '0.0.1'
}


sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
//    compile("com.h2database:h2")
    compile("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
    compile("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
    compile("com.fasterxml.jackson.module:jackson-module-kotlin:2.8.4")
    testCompile("org.springframework.boot:spring-boot-starter-test")

    compile("org.springframework.boot:spring-boot-starter-web") {
        exclude module: "spring-boot-starter-tomcat"
    }
    compile("org.springframework.boot:spring-boot-starter-jetty")
    compile("org.springframework.boot:spring-boot-starter-actuator")
    compile('mysql:mysql-connector-java:5.1.13')

    testCompile("junit:junit")

//thymeleaf
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
//WebJars
    compile("org.webjars:bootstrap:3.3.4")
    compile("org.webjars:jquery:2.1.4")
    // https://mvnrepository.com/artifact/org.webjars/datatables
    compile group: 'org.webjars', name: 'datatables', version: '1.10.13'

}


Step5. 新建標(biāo)準(zhǔn)springboot resources目錄

Springboot web app有很多約定,根據(jù)這些約定,可以省去一大批繁冗的配置。請(qǐng)看標(biāo)準(zhǔn)的工程目錄結(jié)構(gòu)

.
├── META-INF
│   └── MANIFEST.MF
├── README.md
├── README_.md
├── build
│   └── kotlin-build
│       └── caches
│           └── version.txt
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── run.bat
├── run.sh
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   ├── kotlin
    │   │   └── jason
    │   │       └── chen
    │   │           └── mini_springboot
    │   │               ├── console
    │   │               │   └── HelloWorld.kt
    │   │               └── restful
    │   │                   ├── Application.kt
    │   │                   ├── biz
    │   │                   │   └── CustomerService.kt
    │   │                   ├── controller
    │   │                   │   └── CustomerController.kt
    │   │                   ├── entity
    │   │                   │   └── Customer.kt
    │   │                   └── utils
    │   │                       └── DateUtils.kt
    │   └── resources
    │       ├── application.properties
    │       ├── application.yml
    │       ├── static
    │       │   ├── css
    │       │   │   ├── jquery.dataTables.min.css
    │       │   │   └── mini_springboot.css
    │       │   ├── images
    │       │   │   ├── home.png
    │       │   │   ├── sort_asc.png
    │       │   │   ├── sort_both.png
    │       │   │   └── sort_desc.png
    │       │   └── js
    │       │       ├── jquery.dataTables.min.js
    │       │       └── mini_springboot.js
    │       └── templates
    │           ├── common
    │           │   ├── footer.html
    │           │   └── header.html
    │           ├── customers.html
    │           ├── index.html
    │           ├── productform.html
    │           ├── products.html
    │           └── productshow.html
    └── test
        ├── java
        ├── kotlin
        └── resources

30 directories, 35 files



Step5. 寫Controller

package jason.chen.mini_springboot.restful.controller

import jason.chen.mini_springboot.restful.biz.CustomerService
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.ResponseBody

@Controller
class CustomerController(val customerService: CustomerService) {

    @GetMapping(value = "/")
    fun index(): String {
        return "index"
    }

    @GetMapping("/customers.do")
    fun listAll(model: Model): String {
        val allCustomers = customerService.findAll()
        model.addAttribute("customers", allCustomers)
        return "customers"
    }

    @GetMapping("/listCustomers")
    @ResponseBody
    fun listCustomers(model: Model) = customerService.findAll()

    @GetMapping("/{lastName}")
    @ResponseBody
    fun findByLastName(@PathVariable lastName: String)
            = customerService.findByLastName(lastName)
}

Step6.運(yùn)行測(cè)試

運(yùn)行./gradlew bootRun, 啟動(dòng)完畢后,訪問http://127.0.0.1:9891/customers.do
效果如下

螢?zāi)豢煺?2017-03-11 22.23.13.png

本章節(jié)工程源碼:

https://github.com/EasyKotlin/mini_springboot

參考資料

1.https://kotlinlang.org/docs/tutorials/spring-boot-restful.html


Kotlin開發(fā)者社區(qū)

專注分享 Java、 Kotlin、Spring/Spring Boot、MySQL、redis、neo4j、NoSQL、Android、JavaScript、React、Node、函數(shù)式編程、編程思想、"高可用,高性能,高實(shí)時(shí)"大型分布式系統(tǒng)架構(gòu)設(shè)計(jì)主題。

High availability, high performance, high real-time large-scale distributed system architecture design。

分布式框架:Zookeeper、分布式中間件框架等
分布式存儲(chǔ):GridFS、FastDFS、TFS、MemCache、redis等
分布式數(shù)據(jù)庫:Cobar、tddl、Amoeba、Mycat
云計(jì)算、大數(shù)據(jù)、AI算法
虛擬化、云原生技術(shù)
分布式計(jì)算框架:MapReduce、Hadoop、Storm、Flink等
分布式通信機(jī)制:Dubbo、RPC調(diào)用、共享遠(yuǎn)程數(shù)據(jù)、消息隊(duì)列等
消息隊(duì)列MQ:Kafka、MetaQ,RocketMQ
怎樣打造高可用系統(tǒng):基于硬件、軟件中間件、系統(tǒng)架構(gòu)等一些典型方案的實(shí)現(xiàn):HAProxy、基于Corosync+Pacemaker的高可用集群套件中間件系統(tǒng)
Mycat架構(gòu)分布式演進(jìn)
大數(shù)據(jù)Join背后的難題:數(shù)據(jù)、網(wǎng)絡(luò)、內(nèi)存和計(jì)算能力的矛盾和調(diào)和
Java分布式系統(tǒng)中的高性能難題:AIO,NIO,Netty還是自己開發(fā)框架?
高性能事件派發(fā)機(jī)制:線程池模型、Disruptor模型等等。。。

合抱之木,生于毫末;九層之臺(tái),起于壘土;千里之行,始于足下。不積跬步,無以至千里;不積小流,無以成江河。

Kotlin 簡(jiǎn)介

Kotlin是一門非研究性的語言,它是一門非常務(wù)實(shí)的工業(yè)級(jí)編程語言,它的使命就是幫助程序員們解決實(shí)際工程實(shí)踐中的問題。使用Kotlin 讓 Java程序員們的生活變得更好,Java中的那些空指針錯(cuò)誤,浪費(fèi)時(shí)間的冗長(zhǎng)的樣板代碼,啰嗦的語法限制等等,在Kotlin中統(tǒng)統(tǒng)消失。Kotlin 簡(jiǎn)單務(wù)實(shí),語法簡(jiǎn)潔而強(qiáng)大,安全且表達(dá)力強(qiáng),極富生產(chǎn)力。

Java誕生于1995年,至今已有23年歷史。當(dāng)前最新版本是 Java 9。在 JVM 生態(tài)不斷發(fā)展繁榮的過程中,也誕生了Scala、Groovy、Clojure 等兄弟語言。

Kotlin 也正是 JVM 家族中的優(yōu)秀一員。Kotlin是一種現(xiàn)代語言(版本1.0于2016年2月發(fā)布)。它最初的目的是像Scala那樣,優(yōu)化Java語言的缺陷,提供更加簡(jiǎn)單實(shí)用的編程語言特性,并且解決了性能上的問題,比如編譯時(shí)間。 JetBrains在這些方面做得非常出色。

Kotlin語言的特性

用 Java 開發(fā)多年以后,能夠嘗試一些新的東西真是太棒了。如果您是 Java 開發(fā)人員,使用 Kotlin 將會(huì)非常自然流暢。如果你是一個(gè)Swift開發(fā)者,你將會(huì)感到似曾相識(shí),比如可空性(Nullability)。 Kotlin語言的特性有:

1.簡(jiǎn)潔

大幅減少樣板代碼量。

2.與Java的100%互操作性

Kotlin可以直接與Java類交互,反之亦然。這個(gè)特性使得我們可以直接重用我們的代碼庫,并將其遷移到 Kotlin中。由于Java的互操作性幾乎無處不在。我們可以直接訪問平臺(tái)API以及現(xiàn)有的代碼庫,同時(shí)仍然享受和使用 Kotlin 的所有強(qiáng)大的現(xiàn)代語言功能。

3.擴(kuò)展函數(shù)

Kotlin 類似于 C# 和 Gosu, 它提供了為現(xiàn)有類提供新功能擴(kuò)展的能力,而不必從該類繼承或使用任何類型的設(shè)計(jì)模式 (如裝飾器模式)。

4.函數(shù)式編程

Kotlin 語言一等支持函數(shù)式編程,就像Scala一樣。具備高階函數(shù)、Lambda 表達(dá)式等函數(shù)式基本特性。

5.默認(rèn)和命名參數(shù)

在Kotlin中,您可以為函數(shù)中的參數(shù)設(shè)置一個(gè)默認(rèn)值,并給每個(gè)參數(shù)一個(gè)名稱。這有助于編寫易讀的代碼。

6.強(qiáng)大的開發(fā)工具支持

而由于是JetBrains出品,我們擁有很棒的IDE支持。雖然Java到Kotlin的自動(dòng)轉(zhuǎn)換并不是100% OK 的,但它確實(shí)是一個(gè)非常好的工具。使用 IDEA 的工具轉(zhuǎn)換Java代碼為 Kotlin 代碼時(shí),可以輕松地重用60%-70%的結(jié)果代碼,而且修改成本很小。

Kotlin 除了簡(jiǎn)潔強(qiáng)大的語法特性外,還有實(shí)用性非常強(qiáng)的API以及圍繞它構(gòu)建的生態(tài)系統(tǒng)。例如:集合類 API、IO 擴(kuò)展類、反射API 等。同時(shí) Kotlin 社區(qū)也提供了豐富的文檔和大量的學(xué)習(xí)資料,還有在線REPL。

A modern programming language that makes developers happier. Open source forever

圖來自《Kotlin從入門到進(jìn)階實(shí)戰(zhàn)》 (陳光劍,清華大學(xué)出版社)
圖來自《Kotlin從入門到進(jìn)階實(shí)戰(zhàn)》 (陳光劍,清華大學(xué)出版社)

https://kotlinlang.org/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容