Одностраничный сайт на Kotlin и SpringBoot без использования JSP

Дисклеймер

Автор не прогер, кодить не умеет
Я не являюсь гуру или крутым специалистом ни в Котлине, ни в Spring, ни в любой другой технологии используемой в данной статье. Я обычный java junior, который решил опробовать kotlin. Все сделано в «Сапсане» на коленке по дороге с techtrain


Для кого

Для java разработчиков, которые только слышали про котлин, но руками его пока не трогали


Для чего

Показать что kotlin отлично работает с spring boot, а в сочетании с DSL в части работы с html быть удобнее классического подхода с jsp.


Конфигурация для spring boot

Тут все мало отличается от java


  1. Создать проект (kotlin)
  2. Добавить repository jcenter, dependency на kotlin-stdlib и spring-boot-starter-web, плагин kotlin-maven-plugin
  3. Обязательно создать пакет для работы, иначе Spring свалится
  4. Создать open класс Application
  5. В Application добавить метод main со строчкой runApplication (*args)
  6. Добавить контроллер HelloWorld, который вернет приветствие миру

Код
pom.xml


    4.0.0

    com.example
    habr-sample
    1.0-SNAPSHOT
    
        
            jcenter
            jcenter
            https://jcenter.bintray.com
        
    

    
        
            
                org.jetbrains.kotlin
                kotlin-maven-plugin
                RELEASE
                
                    
                        compile
                        compile
                        
                            compile
                        
                    
                
                
                    1.8
                
            
        
    

    
        
            org.jetbrains.kotlin
            kotlin-stdlib
            RELEASE
        
        
            org.springframework.boot
            spring-boot-starter-web
            RELEASE
        
    


Классы
package example

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
open class Application

fun main(args: Array) {
    runApplication(*args)
}
package example

import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody

@Controller
class HelloWorld{
    @RequestMapping("/")
    @ResponseBody
    fun mainPage(): String {
        return "Привет Хабр"
    }
}

Добавляем kotlinx.html

Kotlin имеет расширение в виде DSL для удобной работы с html. Оно позволяет смешать декларативный подход html c императивный подходом обычного языка.

table {//Объявление тега
    thead{
        tr {
            td {
                +"Имя" //+ добавляет контент в элемент
            }
            td {
                +"Возраст"
            }
        }
    }
    for (person in PersonGenerator().generate()) { //Обычный for из kotlin
        tr {

            td {
                +person.name
            }
            td {
                text(person.age)  //аналог "+" который принимает не только String
            }
        }

    }
}

Этот код сформирует html страницу в которой будет табличка с именами людей и их возрастом


Результат

1k4h1zkeukhftbhs38j9k5yxl-g.png


Код
pom.xml


    4.0.0

    com.example
    habr-sample
    1.0-SNAPSHOT
    
        
            jcenter
            jcenter
            https://jcenter.bintray.com
        
    

    
        
            
                org.jetbrains.kotlin
                kotlin-maven-plugin
                RELEASE
                
                    
                        compile
                        compile
                        
                            compile
                        
                    
                
                
                    1.8
                
            
        
    

    
        
            org.jetbrains.kotlin
            kotlin-stdlib-jdk8
            RELEASE
        
        
            org.springframework.boot
            spring-boot-starter-web
            RELEASE
        
        
            org.jetbrains.kotlinx
            kotlinx-html-jvm
            RELEASE
        
    


Классы
package example

data class Person(val name: String,var age: Int)
package example
import java.util.*
import kotlin.collections.ArrayList

class PersonGenerator{
    private val nameList = arrayOf("Петя", "Вася", "Женя", "Марк", "Иван", "Леопольд");
    fun generate(): List {
        val random = Random()
        val personList = ArrayList()
        for (i in 1..15) {
            personList.add(Person(nameList.get(random.nextInt(nameList.size)), random.nextInt(30) + 18))
        }
        return personList;
    }
}

package example
import kotlinx.html.*
import kotlinx.html.stream.createHTML
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody

@Controller
class HelloWorld {

    @RequestMapping("/")
    @ResponseBody
    fun mainPage(): String {
        return createHTML()
                .html {
                    body {
                        table {
                            thead() {
                                tr {
                                    td {
                                        +"Имя"
                                    }
                                    td {
                                        +"Возраст"
                                    }
                                }
                            }
                            val personList= PersonGenerator().generate()
                            for (person in personList ) {
                                tr {

                                    td {
                                        +person.name
                                    }
                                    td {
                                        text(person.age)
                                    }
                                }

                            }
                        }
                    }
                }
    }

}


Добавляем css

Kotlinx.html практически не умеет работать с css, с помощью него можно добавить ссылку на уже готовый стиль или вставить свой с помощью unsafe. Все становиться намного лучше если добавить Aza-Kotlin-CSS — DSL добавляющий работу с css

head {
//Добавить стилей bootstrap
    styleLink("https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css")
    styleLink("https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css")
//Добавление своего стиля
    style("text/css") {
        unsafe {// Заходим в unsafe kotlinx.html
            raw(
                    Stylesheet { // и формируем стиль с Aza-Kotlin-CSS
                        table and td and th {
                            color = 0xFC0Fc0
                        }
                    }.render()
            )
        }
    }
    meta {
        charset = "utf-8"
    }

}

Результат

ppx-vheaitzjypmizvjtsjp7rbu.png

Работа с js идет также через unsafe


Резюме

На мой взгляд писать view на DSL удобнее чем на JSP. Мне не нужно сначала лезть в базу, класть результат вычисления в промежуточный объект, который я потом буду вытаскивать в jsp. Я могу сразу наполнять свой jsp из кодовой базы проекта минуя ненужный мне слой абстракции. К сожалению, я использовал jsp только в своих pet-project и вообще не занимаюсь фронтом. Мне было бы интересно почитать мнение профессионалов по этому вопросу.


Полезные ссылки

Пример разработанной в статье розовой таблички
Документация по котлину
Документация подключения spring boot к котлину
Документация по kotlinx.html
Документация по Aza-Kotlin-CSS

© Habrahabr.ru