Kotlin + SpringBoot + MySQL + Ngrok,你也可以快速上線一個后臺服務

文章寫于2017.11月,作者已長時間沒有再接觸 SpringBoot 了。
目前更推薦 nestjs,這里附上一個代碼倉庫,不同的 commits 增加了不同的功能,供感興趣的同學參考。nest-starter

從一開始只有一個IDEA,到上線一個外網可訪問的API。最后的效果是這樣的:

外網訪問API

開發環境:Win10 + IDEA + Gradle

主要技術:SpringBoot框架 + Kotlin語言 + MySQL數據庫

內容提要:

  1. 創建一個基于Gradle的項目
  2. 初始化SpringBoot
  3. 安裝、配置、關聯MySQL
  4. 構建一個簡單的API
  5. 打包一個可執行文件
  6. 使用ngrok做外網訪問

創建一個新項目

先用IDEA創建一個Gradle項目

創建項目

注意:

  1. 基于Gradle
  2. 使用Kotlin
  3. IDEA對JDK做了一些改進,比如把原來的Logging換成了SLF4J,在使用時有時會導致重復導包。為了避免麻煩,我們使用原生的JDK。
創建項目
創建項目

接下來一路Next。

如果你網絡沒問題的話,最后會是這樣一個項目結構:

項目結構

初始化SpringBoot

修改自動生成的build.gradle如下:

build.gradle

代碼如下:

buildscript {
    ext.kotlin_version = '1.1.51'
    ext.spring_boot_version = '1.5.8.RELEASE'

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version"
    }
}

apply plugin: 'kotlin'
apply plugin: 'org.springframework.boot'


repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
    compile 'org.springframework.boot:spring-boot-starter-web'
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

對上邊四個標注解釋:

  • 上邊三條,主要是添加了一個SpringBootgradle插件,作用如下:
    • 整合類路徑上所有的jar,并建立一個單一的,可運行的"über-jar"。(不用管,就是一個名字。)
    • 它搜索public static void main()方法來標記為可運行的類。
    • 它提供了一個內建的依賴解析器,設置了版本號,以匹配SpringBoot的依賴。您可以覆蓋任何你想要的版本,但它會默認引導的選擇版本的集合。可以注意到下邊對spring-boot-starter-web的依賴沒有設置版本。SpringBoot有很多組件,之后依賴的組件多了,就很很方便的管理版本了。
  • 最后一條,真正的引用。SpringBoot的Web基礎包。

接下來,我們創建一個入口文件添加一些簡單代碼并運行。注意:一定要創建包!

@Controller              //表明這是一個Controller,控制路由的東西
@EnableAutoConfiguration //告訴SpringBoot開始依據依賴路徑等添加Beans。
class SampleController {

    @RequestMapping("/") //映射最基礎的URL
    @ResponseBody        //表明這是一個Resopnse,而不是一個視圖名稱
    internal fun home(): String {
        return "Hello World!" //為請求返回一個字符串。
    }
}

fun main(args: Array<String>) {
    SpringApplication.run(SampleController::class.java, *args)
}
運行

不出錯的話,這時候訪問localhost:8080(默認的),會看到我們剛才設置的Hello World!

localhost主界面

表明SpringBoot運行正常。繼續下一步。


接入MySQL

首先,修改依賴,添加下面的依賴:

compile 'org.springframework.boot:spring-boot-starter-data-jpa'
compile 'mysql:mysql-connector-java'

結果如圖:

build.gradle

然后,需要連接到MySQL服務器。我們去下載一個MySQL
我是Windows的系統,所以按照Windows大致說下流程,很簡單的東西。推薦使用MySQL InstallerWindows下載地址,只有32位的包,但是安裝的時候可選安裝64位的組件。

MySQL下載

選擇要安裝的組件,我選了Custom和下面5個。不想安裝多的話,可以只安裝Server組件就可以了。自己決定選什么。

MySQL安裝

這個之后的配置,我只設置了root的密碼。(也可以不設置,一路next)。

接下來,配置一下數據庫:

先進入MySQL Server的目錄下面,我的是C:\Program Files\MySQL\MySQL Server 5.7\bin,用的頻繁的話可以加到環境變量里去,輸入命令mysql -u root -p并輸入密碼進入數據庫,然后執行下邊的數據庫命令:

mysql> create database db_example; -- 創建一個數據庫,名字自己設置。
mysql> create user 'springuser'@'localhost' identified by 'ThePassword'; -- 創建一個用戶,專門管理這個數據庫。也可以不創建用戶,等下直接使用root用戶。
mysql> grant all on db_example.* to 'springuser'@'localhost'; -- 把新建數據庫的所有權限都給到新建用戶

我的配置如下:

MySQL配置

然后在項目里關聯上數據庫:

resources目錄下,創建一個文件application.properties,內容如下:

spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://localhost:3306/(數據庫名字)
spring.datasource.username=(用戶名,比如我的是springuser或者root)
spring.datasource.password=(密碼,沒有就空著)
關聯MySQL

另外關于spring.jpa.hibernate.ddl-auto

  1. 幾個選項
    • none MySQL默認選項,不改變數據庫結構。
    • update 根據給定的實體結構改變數據庫。
    • create 每次都創建數據庫,但關閉的時候不刪除數據庫。
    • create-drop 創建數據庫,在SessionFactory關閉時刪除數據庫。
  2. 在這里,我們使用create是因為我們現在還沒有數據庫結構。第一次運行之后,我們可以根據需求切換到update或none。要改變數據庫結構時使用update。
  3. H2和其他嵌入式數據庫默認是create-drop,但對于其他類似MySQL的是none
  4. 數據庫處于生產狀態時使用none是很好的安全做法,你設置none,并移除連接到Spring應用程序的MySQL用戶的所有特權,然后只給增刪查改的權限。

開始構建一個簡單的服務

我們要做的:

  1. 有一個User的表
  2. 可以通過請求增加一個User,也可以查找所有的User信息

先創建一個User

package hello

import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Id


@Entity // 告訴Hibernate依據這個類創建一個表
class User {
    @Id //主鍵
    @GeneratedValue(strategy = GenerationType.AUTO) //自增長
    var id: Int? = null

    var name: String? = null

    var email: String? = null
}

再創建一個操作數據的接口

// Spring會自動生成一個名為userRepository(注意是首字母小寫)Bean用來操作增刪改查
interface UserRepository : CrudRepository<User, Long>

再創建一個Controller處理請求

@Controller    // 申明這是一個Controller
@RequestMapping(path = arrayOf("/demo")) // 匹配路徑以/demo開頭的URL
class MainController(@Autowired private val userRepository: UserRepository) {//@Autowired 使用該注解可自動找到之前Spring自動創建的名為userRepository的Bean來填充數據

    val allUsers: Iterable<User>
        @GetMapping(path = arrayOf("/all"))
        @ResponseBody
        get() = userRepository.findAll()

    @GetMapping(path = arrayOf("/add")) 
    @ResponseBody
    fun addNewUser(@RequestParam name: String, @RequestParam email: String): String {
        // @RequestParam 請求參數

        val n = User()
        n.name = name
        n.email = email
        userRepository.save(n)
        return "Saved"
    }
}

注意:@GetMapping只匹配Get請求,是@RequestMapping(method=GET)的簡寫。同理還有@PostMapping等。如果只寫@RequestMapping不指明請求方式表示匹配所有類型的請求。

最后,修改一下我們的入口類App.kt

@SpringBootApplication
open class Application

fun main(args: Array<String>) {
    SpringApplication.run(Application::class.java, *args)
}

注意:

  1. 不加open修飾符會報錯。kotlin中不加open修飾符類默認為final類,而SpringBootApplication不能是final類。
  2. 關于@SpringBootApplication,其實是以下幾個注解的簡便寫法。
    • @Configuration 標記類為bean定義的應用程序上下文的來源
    • @EnableAutoConfiguration 之前已經提到過了告訴SpringBoot開始依據依賴路徑等添加Beans。
    • 通常你會添加@EnableWebMvc一個Spring MVC的應用程序,但是當它看到春天開機自動將其添加彈簧webmvc在classpath。此標志的應用程序作為Web應用程序和激活密鑰的行為,如設立DispatcherServlet。
    • @ComponentScan告訴Spring在hello包自動尋找其他組件,配置,控制器。

這時候我們再運行一下:

用Get方法傳遞一個User信息,它會執行保存操作,并返回結果:

add

獲取所有User信息:

all

奇怪的是一個請求會執行兩次,在隱身模式下就不會這樣,我還在找原因。

好了,現在一個基本的Api已經搭建好了,在本地已經能訪問了。接下來,我們看如何打包運行,以及連接外網。

打包運行

由于SpringBoot的特性,使用Gradle可以方便的生成jar文件。

打包

生成的文件在這里:

包文件

把生成的文件復制到桌面上并運行,為了方便我給它改了一個簡單點的名字:

運行jar文件

和之前的效果一模一樣的。


使用ngrok連接外網

我使用的ngrok.cc,因為可以免費綁定自己的域名。

流程如下:

  1. 注冊賬戶
  2. 開通一個隧道,選第三個免費的。
    1. 選http
    2. 隧道名稱隨便起
    3. 前置域名[***.free.ngrok.cc]
    4. 本地端口,比如我們使用的127.0.0.1:8080
    5. http用戶名密碼,先不用管
    6. 添加
  3. 簡單教程下載對應版本的軟件,啟動。
  4. 開啟你的SpringBoot服務,把之前的localhost:8080換成***.free.ngrok.cc即可訪問。***換自己起的前置域名。

如果你有一個域名,可以來替換掉這個免費域名:

點擊隧道管理 -> 選中隧道 -> 修改

修改隧道

按規定設置域名解析,比如我的是阿里云的域名:

設置解析

設置好等一會即可。另外注意,ngrok.cc目前還不支持https訪問,所以使用自己的域名時也要注意使用http進行訪問。


除了上邊提到的錯誤,我還遇到了另外一個錯誤,顯示端口占用。解決方法如下。

先打開CMD命令行命令netstat ?ano,找到占用8080端口的進程的PID

找到占用8080端口的進程PID

去進程詳情里找到該進程,結束掉,重新啟動SpringBoot服務。

找到占用8080端口的進程

相關文檔

本文內容主要來自:

  1. 實現簡單的Web服務
  2. 訪問MySQL

推薦:一個比較完整的REST服務


最后,SpringBoot能做的東西還很多,本文只是和你一起搭了一個很基本的框架,你可以不斷的去添加新的內容進去,去嘗試構造你自己的優雅的API,做更多的事。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,182評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,489評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,290評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,776評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,510評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,866評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,860評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,036評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,585評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,331評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,536評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,058評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,754評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,154評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,469評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,273評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,505評論 2 379

推薦閱讀更多精彩內容

  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,922評論 6 342
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,826評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,733評論 25 708
  • 人生最大的敵人其實是自己,無論在哪個方面,只有自己才能毀了自己,又或者讓自己的潛力發揮到最高點,所以我們在一...
    元寶_H閱讀 748評論 0 2
  • 從鐮倉離開后的每一個風輕云淡的夜晚,那些關于鐮倉的細微畫面總會跳出腦海,每一個細枝末節都可以像日劇電影一樣被一幀幀...
    金日成閱讀 617評論 2 2