Одностраничный сайт на 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 <Application>(*args)
  6. Добавить контроллер HelloWorld, который вернет приветствие миру

Код

pom.xml

<?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>      <groupId>com.example</groupId>     <artifactId>habr-sample</artifactId>     <version>1.0-SNAPSHOT</version>     <repositories>         <repository>             <id>jcenter</id>             <name>jcenter</name>             <url>https://jcenter.bintray.com</url>         </repository>     </repositories>      <build>         <plugins>             <plugin>                 <groupId>org.jetbrains.kotlin</groupId>                 <artifactId>kotlin-maven-plugin</artifactId>                 <version>RELEASE</version>                 <executions>                     <execution>                         <id>compile</id>                         <phase>compile</phase>                         <goals>                             <goal>compile</goal>                         </goals>                     </execution>                 </executions>                 <configuration>                     <jvmTarget>1.8</jvmTarget>                 </configuration>             </plugin>         </plugins>     </build>      <dependencies>         <dependency>             <groupId>org.jetbrains.kotlin</groupId>             <artifactId>kotlin-stdlib</artifactId>             <version>RELEASE</version>         </dependency>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>             <version>RELEASE</version>         </dependency>     </dependencies> </project>

Классы

package example  import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication  @SpringBootApplication open class Application  fun main(args: Array<String>) {     runApplication<Application>(*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 страницу в которой будет табличка с именами людей и их возрастом

Результат

Код

pom.xml

<?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>      <groupId>com.example</groupId>     <artifactId>habr-sample</artifactId>     <version>1.0-SNAPSHOT</version>     <repositories>         <repository>             <id>jcenter</id>             <name>jcenter</name>             <url>https://jcenter.bintray.com</url>         </repository>     </repositories>      <build>         <plugins>             <plugin>                 <groupId>org.jetbrains.kotlin</groupId>                 <artifactId>kotlin-maven-plugin</artifactId>                 <version>RELEASE</version>                 <executions>                     <execution>                         <id>compile</id>                         <phase>compile</phase>                         <goals>                             <goal>compile</goal>                         </goals>                     </execution>                 </executions>                 <configuration>                     <jvmTarget>1.8</jvmTarget>                 </configuration>             </plugin>         </plugins>     </build>      <dependencies>         <dependency>             <groupId>org.jetbrains.kotlin</groupId>             <artifactId>kotlin-stdlib-jdk8</artifactId>             <version>RELEASE</version>         </dependency>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>             <version>RELEASE</version>         </dependency>         <dependency>             <groupId>org.jetbrains.kotlinx</groupId>             <artifactId>kotlinx-html-jvm</artifactId>             <version>RELEASE</version>         </dependency>     </dependencies> </project>

Классы

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<Person> {         val random = Random()         val personList = ArrayList<Person>()         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"     }  }

Результат

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

Резюме

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

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

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

FavoriteLoadingДобавить в избранное
Posted in Без рубрики

Добавить комментарий