├── LICENSE ├── README.md ├── kotlin-spring-export-pdf ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ └── KotlinSpringExportPDF │ │ │ ├── KotlinSpringExportPdfApplication.kt │ │ │ ├── controller │ │ │ └── EmployeeController.kt │ │ │ ├── model │ │ │ └── Employee.kt │ │ │ ├── repository │ │ │ └── EmployeeRepository.kt │ │ │ └── util │ │ │ └── PDFGenerator.kt │ └── resources │ │ └── application.properties │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── KotlinSpringExportPDF │ └── KotlinSpringExportPdfApplicationTests.kt ├── kotlin-spring-github-oauth2 ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ └── demo │ │ │ └── kotlinspringgithuboauth2 │ │ │ ├── Kotlinspringgithuboauth2Application.kt │ │ │ └── config │ │ │ ├── SecurityConfig.kt │ │ │ └── WebMvcConfig.kt │ └── resources │ │ ├── application.yaml │ │ └── templates │ │ └── index.html │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── demo │ └── kotlinspringgithuboauth2 │ └── Kotlinspringgithuboauth2ApplicationTests.kt ├── kotlin-spring-h2db-restful-api ├── pom.xml └── src │ └── main │ ├── kotlin │ └── com │ │ └── knf │ │ └── dev │ │ ├── KotlinSpringbH2DBRestfulApiApplication.kt │ │ ├── controller │ │ └── UserController.kt │ │ ├── entity │ │ └── User.kt │ │ └── repository │ │ └── UserRepository.kt │ └── resources │ └── application.properties ├── kotlin-spring-h2db-thymeleaf-crud ├── pom.xml └── src │ └── main │ ├── kotlin │ └── com │ │ └── knf │ │ └── dev │ │ ├── KotlinSpringbH2DBThymeleafApplication.kt │ │ ├── controller │ │ └── UserController.kt │ │ ├── entity │ │ └── User.kt │ │ └── repository │ │ └── UserRepository.kt │ └── resources │ ├── application.properties │ ├── static │ └── bootstrap.min.css │ └── templates │ ├── add-user.html │ ├── edit-user.html │ └── list-users.html ├── kotlin-spring-jpa-freemarker-crud ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ └── demo │ │ │ └── kotlinspringjpafreemarkercrud │ │ │ ├── KotlinspringjpafreemarkercrudApplication.kt │ │ │ ├── controller │ │ │ └── UserController.kt │ │ │ ├── model │ │ │ └── User.kt │ │ │ ├── repository │ │ │ └── UserRepository.kt │ │ │ └── service │ │ │ └── UserService.kt │ └── resources │ │ ├── application.properties │ │ └── templates │ │ ├── create-update.ftlh │ │ └── home.ftlh │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── demo │ └── kotlinspringjpafreemarkercrud │ └── KotlinspringjpafreemarkercrudApplicationTests.kt ├── kotlin-spring-jpa-groovy-crud-example ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ └── demo │ │ │ └── kotlinspringbootcrudexample │ │ │ ├── KotlinspringbootcrudexampleApplication.kt │ │ │ ├── controller │ │ │ └── UserController.kt │ │ │ ├── model │ │ │ └── User.kt │ │ │ ├── repository │ │ │ └── UserRepository.kt │ │ │ └── service │ │ │ └── UserService.kt │ └── resources │ │ ├── application.properties │ │ └── templates │ │ ├── create-update.tpl │ │ └── home.tpl │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── demo │ └── kotlinspringbootcrudexample │ └── KotlinspringbootcrudexampleApplicationTests.kt ├── kotlin-spring-jpa-mustache-crud ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ └── demo │ │ │ └── kotlinspringjpamustachecrud │ │ │ ├── KotlinspringjpamustachecrudApplication.kt │ │ │ ├── controller │ │ │ └── UserController.kt │ │ │ ├── model │ │ │ └── User.kt │ │ │ ├── repository │ │ │ └── UserRepository.kt │ │ │ └── service │ │ │ └── UserService.kt │ └── resources │ │ ├── application.properties │ │ └── templates │ │ ├── create-update.mustache │ │ └── home.mustache │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── demo │ └── kotlinspringjpamustachecrud │ └── KotlinspringjpamustachecrudApplicationTests.kt ├── kotlin-spring-keycloak ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ └── demo │ │ │ └── kotlinspringkeycloakdemo │ │ │ ├── Application.kt │ │ │ ├── Vo │ │ │ └── EmployeeVO.kt │ │ │ ├── config │ │ │ └── SecurityConfig.kt │ │ │ ├── controller │ │ │ └── EmployeeController.kt │ │ │ └── service │ │ │ └── KeycloakService.kt │ └── resources │ │ └── application.properties │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── demo │ └── kotlinspringkeycloakdemo │ └── KotlinspringkeycloakdemoApplicationTests.kt ├── kotlin-spring-oauth2-google ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ └── demo │ │ │ └── kotlinspringOauth2google │ │ │ ├── KotlinspringOauth2googleApplication.kt │ │ │ └── config │ │ │ ├── SecurityConfig.kt │ │ │ └── WebMvcConfig.kt │ └── resources │ │ ├── application.yaml │ │ └── templates │ │ └── index.html │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── demo │ └── kotlinspringOauth2google │ └── KotlinspringOauth2googleApplicationTests.kt ├── kotlin-spring-restful-api ├── pom.xml └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ ├── SpringbootKotlinCrudApplication.kt │ │ │ ├── controller │ │ │ └── EmployeeController.kt │ │ │ ├── model │ │ │ └── Employee.kt │ │ │ └── repository │ │ │ └── EmployeeRepository.kt │ └── resources │ │ └── application.properties │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── SpringbootKotlinCrudApplicationTests.kt ├── kotlin-spring-thymeleaf-login-signup ├── pom.xml └── src │ └── main │ ├── kotlin │ └── com │ │ └── knf │ │ └── dev │ │ └── demo │ │ └── kotlinspringthymeleafloginsignup │ │ ├── KotlinSpringThymeleafLoginSignupApplication.kt │ │ ├── config │ │ └── SecurityConfiguration.kt │ │ ├── controller │ │ ├── HomeController.kt │ │ └── RegistrationController.kt │ │ ├── dto │ │ └── UserRegistrationDto.kt │ │ ├── model │ │ ├── Role.kt │ │ └── User.kt │ │ ├── repository │ │ └── UserRepository.kt │ │ └── service │ │ ├── UserService.kt │ │ └── UserServiceImpl.kt │ └── resources │ ├── application.properties │ └── templates │ ├── index.html │ ├── login.html │ └── registration.html ├── kotlin-spring-webflux-downloadfile ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ └── demo │ │ │ ├── KotlinspringwebfluxdownloadfileApplication.kt │ │ │ └── controller │ │ │ └── DownloadFile.kt │ └── resources │ │ ├── application.properties │ │ └── dummy.txt │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── demo │ └── KotlinspringwebfluxdownloadfileApplicationTests.kt ├── kotlin-spring-webflux-fileupload-download ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ └── demo │ │ │ ├── KotlinspringwebfluxfileuploaddownloadApplication.kt │ │ │ └── controller │ │ │ └── UploadDownloadController.kt │ └── resources │ │ ├── application.properties │ │ └── files │ │ ├── dummy.txt │ │ ├── dummy1.txt │ │ └── dummy3.txt │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── demo │ └── KotlinspringwebfluxfileuploaddownloadApplicationTests.kt ├── kotlin-spring-websocket-example ├── pom.xml └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ ├── KotlinSpringWebsocketExampleApplication.kt │ │ │ ├── config │ │ │ └── SocketConfig.kt │ │ │ └── handler │ │ │ └── TextHandler.kt │ └── resources │ │ ├── application.properties │ │ ├── static │ │ ├── bootstrap.min.css │ │ ├── bootstrap.min.js │ │ ├── jquery.min.js │ │ └── main.js │ │ └── templates │ │ └── index.html │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── KotlinSpringWebsocketExampleApplicationTests.kt ├── kotlin-springboot-apachecommans-exportcsv ├── pom.xml └── src │ └── main │ ├── kotlin │ └── com │ │ └── knf │ │ └── dev │ │ ├── KotlinSpringbootApachecommansExportcsvApplication.kt │ │ ├── controller │ │ └── EmployeeController.kt │ │ ├── entity │ │ └── Employee.kt │ │ ├── helper │ │ └── CSVHelper.kt │ │ ├── repository │ │ └── EmployeeRepository.kt │ │ └── service │ │ └── EmployeeService.kt │ └── resources │ └── application.properties ├── kotlin-springboot-export-csv-demo ├── pom.xml └── src │ └── main │ ├── kotlin │ └── com │ │ └── knf │ │ └── dev │ │ ├── KotlinSpringbootExportCsvDemoApplication.kt │ │ ├── controller │ │ └── EmployeeController.kt │ │ ├── entity │ │ └── Employee.kt │ │ └── repository │ │ └── EmployeeRepository.kt │ └── resources │ └── application.properties ├── kotlin-springboot-mybatis-crud-example ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── knf │ │ │ └── dev │ │ │ └── demo │ │ │ ├── KotlinSpringbootMybatisCrudExampleApplication.kt │ │ │ ├── controller │ │ │ └── UserController.kt │ │ │ ├── exception │ │ │ ├── CustomErrorResponse.kt │ │ │ ├── GlobalExceptionHandler.kt │ │ │ ├── UserIdAlreadyExistException.kt │ │ │ └── UserIdNotFoundException.kt │ │ │ ├── model │ │ │ └── User.kt │ │ │ └── repository │ │ │ └── UserRepository.kt │ └── resources │ │ ├── application.properties │ │ └── schema.sql │ └── test │ └── kotlin │ └── com │ └── knf │ └── dev │ └── demo │ └── KotlinSpringbootMybatisCrudExampleApplicationTests.kt ├── kotlin-springsecurity-jwt ├── pom.xml └── src │ └── main │ ├── kotlin │ └── com │ │ └── knf │ │ └── dev │ │ └── demo │ │ └── kotlinspringsecurityjwt │ │ ├── KotlinSpringsecurityJwtApplication.kt │ │ ├── controller │ │ ├── AuthController.kt │ │ └── EmployeeController.kt │ │ ├── model │ │ ├── ERole.kt │ │ ├── Employee.kt │ │ └── Role.kt │ │ ├── repository │ │ ├── EmployeeRepository.kt │ │ └── RoleRepository.kt │ │ ├── request │ │ ├── LoginRequest.kt │ │ └── SignupRequest.kt │ │ ├── response │ │ ├── JwtResponse.kt │ │ └── MessageResponse.kt │ │ └── security │ │ ├── WebSecurityConfig.kt │ │ ├── jwt │ │ ├── AuthEntryPointJwt.kt │ │ ├── AuthTokenFilter.kt │ │ └── JwtUtils.kt │ │ └── services │ │ ├── EmployeeDetailsImpl.kt │ │ └── EmployeeDetailsServiceImpl.kt │ └── resources │ └── application.yaml └── spring-kotlin-webflux-videostreaming ├── build.gradle.kts ├── settings.gradle.kts └── src ├── main ├── kotlin │ └── com │ │ └── knf │ │ └── springkotlinwebfluxvideostreaming │ │ ├── SpringkotlinwebfluxvideostreamingApplication.kt │ │ ├── config │ │ └── EndPointConfig.kt │ │ ├── controller │ │ └── VideoStreamingController.kt │ │ └── service │ │ └── VideoStreamingService.kt └── resources │ ├── application.properties │ ├── mp4 │ └── sample_960x540.mp4 │ └── static │ └── index.html └── test └── kotlin └── com └── knf └── springkotlinwebfluxvideostreaming └── SpringkotlinwebfluxvideostreamingApplicationTests.kt /README.md: -------------------------------------------------------------------------------- 1 | # Kotlin, Spring Boot examples 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /kotlin-spring-export-pdf/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.5.4" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.5.21" 7 | kotlin("plugin.spring") version "1.5.21" 8 | kotlin("plugin.jpa") version "1.5.21" 9 | } 10 | 11 | group = "com.knf.dev" 12 | version = "0.0.1-SNAPSHOT" 13 | java.sourceCompatibility = JavaVersion.VERSION_11 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 21 | implementation("org.springframework.boot:spring-boot-starter-web") 22 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 23 | implementation("org.jetbrains.kotlin:kotlin-reflect") 24 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 25 | runtimeOnly("com.h2database:h2") 26 | testImplementation("org.springframework.boot:spring-boot-starter-test") 27 | // https://mvnrepository.com/artifact/com.itextpdf/itextpdf 28 | implementation("com.itextpdf:itextpdf:5.0.6") 29 | 30 | } 31 | 32 | tasks.withType { 33 | kotlinOptions { 34 | freeCompilerArgs = listOf("-Xjsr305=strict") 35 | jvmTarget = "11" 36 | } 37 | } 38 | 39 | tasks.withType { 40 | useJUnitPlatform() 41 | } 42 | -------------------------------------------------------------------------------- /kotlin-spring-export-pdf/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowledgefactory4u/kotlin-springboot-app/65c876401a4cb91945ce6768d4d972b98a96c21d/kotlin-spring-export-pdf/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kotlin-spring-export-pdf/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kotlin-spring-export-pdf/src/main/kotlin/com/knf/dev/KotlinSpringExportPDF/KotlinSpringExportPdfApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.KotlinSpringExportPDF 2 | 3 | import com.knf.dev.KotlinSpringExportPDF.model.Employee 4 | import com.knf.dev.KotlinSpringExportPDF.repository.EmployeeRepository 5 | import org.springframework.beans.factory.annotation.Autowired 6 | import org.springframework.boot.CommandLineRunner 7 | import org.springframework.boot.SpringApplication 8 | import org.springframework.boot.autoconfigure.SpringBootApplication 9 | import java.util.* 10 | 11 | 12 | @SpringBootApplication 13 | class KotlinSpringExportPdfApplication : CommandLineRunner { 14 | @Autowired 15 | var repository: EmployeeRepository? = null 16 | 17 | @Throws(Exception::class) 18 | override fun run(vararg args: String) { 19 | if (repository!!.count() == 0L) { 20 | // save a list of Employees 21 | repository!!.saveAll( 22 | Arrays.asList( 23 | Employee("Adam", "John"), 24 | Employee("Sibin", "M"), 25 | Employee("Arun", "Mohan"), 26 | Employee("Scott", "Morrison"), 27 | Employee("Hikaru", "Nakamura"), 28 | Employee("Ishivaka", "Yusuke") 29 | ) 30 | ) 31 | } 32 | } 33 | 34 | companion object { 35 | @JvmStatic 36 | fun main(args: Array) { 37 | SpringApplication.run(KotlinSpringExportPdfApplication::class.java, *args) 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /kotlin-spring-export-pdf/src/main/kotlin/com/knf/dev/KotlinSpringExportPDF/controller/EmployeeController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.KotlinSpringExportPDF.controller 2 | 3 | import com.knf.dev.KotlinSpringExportPDF.model.Employee 4 | import com.knf.dev.KotlinSpringExportPDF.repository.EmployeeRepository 5 | import com.knf.dev.KotlinSpringExportPDF.util.PDFGenerator.employeePDFReport 6 | import org.springframework.beans.factory.annotation.Autowired 7 | import org.springframework.core.io.InputStreamResource 8 | import org.springframework.http.HttpHeaders 9 | import org.springframework.http.MediaType 10 | import org.springframework.http.ResponseEntity 11 | import org.springframework.web.bind.annotation.GetMapping 12 | import org.springframework.web.bind.annotation.RequestMapping 13 | import org.springframework.web.bind.annotation.RestController 14 | import java.io.IOException 15 | 16 | 17 | @RestController 18 | @RequestMapping("/api/pdf") 19 | class EmployeeController { 20 | @Autowired 21 | var employeeRepository: EmployeeRepository? = null 22 | 23 | @GetMapping(value = ["/employees"], produces = [MediaType.APPLICATION_PDF_VALUE]) 24 | @Throws( 25 | IOException::class 26 | ) 27 | fun employeeReport(): ResponseEntity { 28 | val employees = employeeRepository!!.findAll() as List 29 | val bis = employeePDFReport(employees as List) 30 | val headers = HttpHeaders() 31 | headers.add("Content-Disposition", "inline; filename=employees.pdf") 32 | return ResponseEntity.ok().headers(headers).contentType(MediaType.APPLICATION_PDF) 33 | .body(InputStreamResource(bis)) 34 | } 35 | } -------------------------------------------------------------------------------- /kotlin-spring-export-pdf/src/main/kotlin/com/knf/dev/KotlinSpringExportPDF/model/Employee.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.KotlinSpringExportPDF.model 2 | 3 | import javax.persistence.* 4 | 5 | @Entity 6 | @Table(name = "employees") 7 | class Employee { 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.AUTO) 10 | var id: Long = 0 11 | 12 | @Column(name = "firstname") 13 | var firstName: String? = null 14 | 15 | @Column(name = "lastname") 16 | var lastName: String? = null 17 | 18 | protected constructor() {} 19 | constructor(firstName: String?, lastName: String?) { 20 | this.firstName = firstName 21 | this.lastName = lastName 22 | } 23 | } -------------------------------------------------------------------------------- /kotlin-spring-export-pdf/src/main/kotlin/com/knf/dev/KotlinSpringExportPDF/repository/EmployeeRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.KotlinSpringExportPDF.repository 2 | 3 | import com.knf.dev.KotlinSpringExportPDF.model.Employee 4 | import org.springframework.data.repository.CrudRepository 5 | 6 | 7 | interface EmployeeRepository : CrudRepository -------------------------------------------------------------------------------- /kotlin-spring-export-pdf/src/main/kotlin/com/knf/dev/KotlinSpringExportPDF/util/PDFGenerator.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.KotlinSpringExportPDF.util 2 | 3 | import com.itextpdf.text.* 4 | import com.itextpdf.text.pdf.PdfPCell 5 | import com.itextpdf.text.pdf.PdfPTable 6 | import com.itextpdf.text.pdf.PdfWriter 7 | import com.knf.dev.KotlinSpringExportPDF.model.Employee 8 | import org.slf4j.LoggerFactory 9 | import java.io.ByteArrayInputStream 10 | import java.io.ByteArrayOutputStream 11 | import java.util.stream.Stream 12 | 13 | 14 | object PDFGenerator { 15 | private val logger = LoggerFactory.getLogger(PDFGenerator::class.java) 16 | fun employeePDFReport(employees: List): ByteArrayInputStream { 17 | val document = Document() 18 | val out = ByteArrayOutputStream() 19 | try { 20 | PdfWriter.getInstance(document, out) 21 | document.open() 22 | 23 | // Add Text to PDF file -> 24 | val font = FontFactory.getFont( 25 | FontFactory.COURIER, 14f, 26 | BaseColor.BLACK 27 | ) 28 | val para = Paragraph("Employee Table", font) 29 | para.alignment = Element.ALIGN_CENTER 30 | document.add(para) 31 | document.add(Chunk.NEWLINE) 32 | val table = PdfPTable(3) 33 | // Add PDF Table Header -> 34 | Stream.of("ID", "First Name", "Last Name").forEach { headerTitle: String? -> 35 | val header = PdfPCell() 36 | val headFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD) 37 | header.backgroundColor = BaseColor.LIGHT_GRAY 38 | header.horizontalAlignment = Element.ALIGN_CENTER 39 | header.borderWidth = 2f 40 | header.phrase = Phrase(headerTitle, headFont) 41 | table.addCell(header) 42 | } 43 | for (employee in employees) { 44 | val idCell = PdfPCell(Phrase(employee.id.toString())) 45 | idCell.paddingLeft = 4f 46 | idCell.verticalAlignment = Element.ALIGN_MIDDLE 47 | idCell.horizontalAlignment = Element.ALIGN_CENTER 48 | table.addCell(idCell) 49 | val firstNameCell = PdfPCell(Phrase(employee.firstName)) 50 | firstNameCell.paddingLeft = 4f 51 | firstNameCell.verticalAlignment = Element.ALIGN_MIDDLE 52 | firstNameCell.horizontalAlignment = Element.ALIGN_LEFT 53 | table.addCell(firstNameCell) 54 | val lastNameCell = PdfPCell(Phrase(employee.lastName.toString())) 55 | lastNameCell.verticalAlignment = Element.ALIGN_MIDDLE 56 | lastNameCell.horizontalAlignment = Element.ALIGN_RIGHT 57 | lastNameCell.paddingRight = 4f 58 | table.addCell(lastNameCell) 59 | } 60 | document.add(table) 61 | document.close() 62 | } catch (e: DocumentException) { 63 | logger.error(e.toString()) 64 | } 65 | return ByteArrayInputStream(out.toByteArray()) 66 | } 67 | } -------------------------------------------------------------------------------- /kotlin-spring-export-pdf/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-spring-export-pdf/src/test/kotlin/com/knf/dev/KotlinSpringExportPDF/KotlinSpringExportPdfApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.KotlinSpringExportPDF 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KotlinSpringExportPdfApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-spring-github-oauth2/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.5.4" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.5.21" 7 | kotlin("plugin.spring") version "1.5.21" 8 | } 9 | 10 | group = "com.knf.dev.demo" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | repositories { 15 | mavenCentral() 16 | } 17 | 18 | dependencies { 19 | implementation("org.springframework.boot:spring-boot-starter-oauth2-client") 20 | implementation("org.springframework.boot:spring-boot-starter-security") 21 | implementation("org.springframework.boot:spring-boot-starter-thymeleaf") 22 | implementation("org.springframework.boot:spring-boot-starter-web") 23 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 24 | implementation("org.jetbrains.kotlin:kotlin-reflect") 25 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 26 | implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity5") 27 | testImplementation("org.springframework.boot:spring-boot-starter-test") 28 | testImplementation("org.springframework.security:spring-security-test") 29 | } 30 | 31 | tasks.withType { 32 | kotlinOptions { 33 | freeCompilerArgs = listOf("-Xjsr305=strict") 34 | jvmTarget = "11" 35 | } 36 | } 37 | 38 | tasks.withType { 39 | useJUnitPlatform() 40 | } 41 | -------------------------------------------------------------------------------- /kotlin-spring-github-oauth2/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowledgefactory4u/kotlin-springboot-app/65c876401a4cb91945ce6768d4d972b98a96c21d/kotlin-spring-github-oauth2/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kotlin-spring-github-oauth2/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kotlin-spring-github-oauth2/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kotlin-spring-github-oauth2" 2 | -------------------------------------------------------------------------------- /kotlin-spring-github-oauth2/src/main/kotlin/com/knf/dev/demo/kotlinspringgithuboauth2/Kotlinspringgithuboauth2Application.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringgithuboauth2 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class Kotlinspringgithuboauth2Application 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-github-oauth2/src/main/kotlin/com/knf/dev/demo/kotlinspringgithuboauth2/config/SecurityConfig.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringgithuboauth2.config 2 | 3 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity 4 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter 5 | import kotlin.Throws 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity 7 | import java.lang.Exception 8 | 9 | @EnableWebSecurity 10 | class SecurityConfig : WebSecurityConfigurerAdapter() { 11 | @Throws(Exception::class) 12 | public override fun configure(httpSecurity: HttpSecurity) { 13 | httpSecurity.csrf().disable().antMatcher("/**").authorizeRequests() 14 | .antMatchers("/", "/index").authenticated() 15 | .anyRequest().authenticated() 16 | .and() 17 | .oauth2Login().permitAll() 18 | .and() 19 | .logout() 20 | .invalidateHttpSession(true) 21 | .clearAuthentication(true) 22 | .logoutSuccessUrl("/") 23 | } 24 | } -------------------------------------------------------------------------------- /kotlin-spring-github-oauth2/src/main/kotlin/com/knf/dev/demo/kotlinspringgithuboauth2/config/WebMvcConfig.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringgithuboauth2.config 2 | 3 | import org.springframework.context.annotation.Configuration 4 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer 5 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry 6 | 7 | @Configuration 8 | class WebMvcConfig : WebMvcConfigurer { 9 | override fun addViewControllers(registry: ViewControllerRegistry) { 10 | registry.addViewController("/").setViewName("index") 11 | registry.addViewController("/index").setViewName("index") 12 | } 13 | } -------------------------------------------------------------------------------- /kotlin-spring-github-oauth2/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | security: 3 | oauth2: 4 | client: 5 | registration: 6 | github: 7 | clientId: 8 | clientSecret: -------------------------------------------------------------------------------- /kotlin-spring-github-oauth2/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Kotlin + Spring OAuth2 Login with Github - Demo 7 | 8 | 9 | 11 | 13 | 15 | 16 | 17 | 35 | 36 |
37 |
38 |
39 |
40 |
41 |

Welcome

42 |

You have been successfully logged in

43 |
44 |
45 |
46 | 47 | -------------------------------------------------------------------------------- /kotlin-spring-github-oauth2/src/test/kotlin/com/knf/dev/demo/kotlinspringgithuboauth2/Kotlinspringgithuboauth2ApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringgithuboauth2 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class Kotlinspringgithuboauth2ApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-spring-h2db-restful-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.7.RELEASE 9 | 10 | 11 | com.knf.dev 12 | kotlin-spring-h2db-restful-api 13 | 0.0.1-SNAPSHOT 14 | kotlin-spring-h2db-restful-api 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 1.3.72 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-data-jpa 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | com.fasterxml.jackson.module 33 | jackson-module-kotlin 34 | 35 | 36 | org.jetbrains.kotlin 37 | kotlin-reflect 38 | 39 | 40 | org.jetbrains.kotlin 41 | kotlin-stdlib-jdk8 42 | 43 | 44 | 45 | com.h2database 46 | h2 47 | runtime 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-test 52 | test 53 | 54 | 55 | org.junit.vintage 56 | junit-vintage-engine 57 | 58 | 59 | 60 | 61 | 62 | 63 | ${project.basedir}/src/main/kotlin 64 | ${project.basedir}/src/test/kotlin 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-maven-plugin 69 | 70 | 71 | org.jetbrains.kotlin 72 | kotlin-maven-plugin 73 | 74 | 75 | -Xjsr305=strict 76 | 77 | 78 | spring 79 | jpa 80 | 81 | 82 | 83 | 84 | org.jetbrains.kotlin 85 | kotlin-maven-allopen 86 | ${kotlin.version} 87 | 88 | 89 | org.jetbrains.kotlin 90 | kotlin-maven-noarg 91 | ${kotlin.version} 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /kotlin-spring-h2db-restful-api/src/main/kotlin/com/knf/dev/KotlinSpringbH2DBRestfulApiApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinSpringbH2DBRestfulApiApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-h2db-restful-api/src/main/kotlin/com/knf/dev/controller/UserController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.controller 2 | 3 | import com.knf.dev.entity.User 4 | import com.knf.dev.repository.UserRepository 5 | import org.springframework.http.HttpStatus 6 | import org.springframework.http.ResponseEntity 7 | import org.springframework.web.bind.annotation.* 8 | 9 | @RestController 10 | @RequestMapping("/api/v1/") 11 | class UserController(private val userRepository: UserRepository) { 12 | 13 | @GetMapping("/users") 14 | fun getAllUsers(): List = 15 | userRepository.findAll() 16 | 17 | @PostMapping("/users") 18 | fun createNewUser(@RequestBody user: User): User = 19 | userRepository.save(user) 20 | 21 | @GetMapping("/users/{id}") 22 | fun getUserById(@PathVariable(value = "id") userId: Long): 23 | ResponseEntity { 24 | return userRepository.findById(userId).map { usr -> 25 | ResponseEntity.ok(usr) 26 | }.orElse(ResponseEntity.notFound().build()) 27 | } 28 | 29 | @PutMapping("/users/{id}") 30 | fun updateUserById(@PathVariable(value = "id") userId: Long, 31 | @RequestBody newUser: User): 32 | ResponseEntity { 33 | 34 | return userRepository.findById(userId).map { existingUser -> 35 | val updatedEmployee: User = existingUser 36 | .copy(firstName = newUser.firstName, lastName = 37 | newUser.lastName, emailId = newUser.emailId) 38 | ResponseEntity.ok().body(userRepository.save(updatedEmployee)) 39 | }.orElse(ResponseEntity.notFound().build()) 40 | 41 | } 42 | 43 | @DeleteMapping("/users/{id}") 44 | fun deleteUserById(@PathVariable(value = "id") userId: Long): 45 | ResponseEntity { 46 | return userRepository.findById(userId).map { usr -> 47 | userRepository.delete(usr) 48 | ResponseEntity(HttpStatus.OK) 49 | }.orElse(ResponseEntity.notFound().build()) 50 | 51 | } 52 | } -------------------------------------------------------------------------------- /kotlin-spring-h2db-restful-api/src/main/kotlin/com/knf/dev/entity/User.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.entity 2 | 3 | import javax.persistence.* 4 | 5 | @Entity 6 | @Table(name = "user") 7 | data class User( 8 | 9 | @Id 10 | @GeneratedValue(strategy = GenerationType.AUTO) 11 | var id: Long, 12 | val firstName: String, 13 | val lastName: String, 14 | val emailId: String 15 | ) 16 | -------------------------------------------------------------------------------- /kotlin-spring-h2db-restful-api/src/main/kotlin/com/knf/dev/repository/UserRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.repository 2 | 3 | 4 | import com.knf.dev.entity.User 5 | import org.springframework.data.jpa.repository.JpaRepository 6 | import org.springframework.stereotype.Repository 7 | 8 | @Repository 9 | interface UserRepository : JpaRepository -------------------------------------------------------------------------------- /kotlin-spring-h2db-restful-api/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.h2.console.enabled=true 2 | spring.h2.console.path=/h2_console 3 | spring.datasource.url=jdbc:h2:file:~/h2/testdb 4 | spring.datasource.username=sa 5 | spring.datasource.password= 6 | spring.datasource.driverClassName=org.h2.Driver 7 | spring.jpa.hibernate.ddl-auto = update 8 | spring.jpa.show-sql=true -------------------------------------------------------------------------------- /kotlin-spring-h2db-thymeleaf-crud/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.7.RELEASE 9 | 10 | 11 | com.knf.dev 12 | kotlin-spring-h2db-thymeleaf-crud 13 | 0.0.1-SNAPSHOT 14 | kotlin-spring-h2db-thymeleaf-crud 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 1.3.72 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-data-jpa 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-thymeleaf 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | com.fasterxml.jackson.module 37 | jackson-module-kotlin 38 | 39 | 40 | org.jetbrains.kotlin 41 | kotlin-reflect 42 | 43 | 44 | org.jetbrains.kotlin 45 | kotlin-stdlib-jdk8 46 | 47 | 48 | 49 | com.h2database 50 | h2 51 | runtime 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-starter-test 56 | test 57 | 58 | 59 | org.junit.vintage 60 | junit-vintage-engine 61 | 62 | 63 | 64 | 65 | 66 | 67 | ${project.basedir}/src/main/kotlin 68 | ${project.basedir}/src/test/kotlin 69 | 70 | 71 | org.springframework.boot 72 | spring-boot-maven-plugin 73 | 74 | 75 | org.jetbrains.kotlin 76 | kotlin-maven-plugin 77 | 78 | 79 | -Xjsr305=strict 80 | 81 | 82 | spring 83 | jpa 84 | 85 | 86 | 87 | 88 | org.jetbrains.kotlin 89 | kotlin-maven-allopen 90 | ${kotlin.version} 91 | 92 | 93 | org.jetbrains.kotlin 94 | kotlin-maven-noarg 95 | ${kotlin.version} 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /kotlin-spring-h2db-thymeleaf-crud/src/main/kotlin/com/knf/dev/KotlinSpringbH2DBThymeleafApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinSpringbH2DBThymeleafApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-h2db-thymeleaf-crud/src/main/kotlin/com/knf/dev/controller/UserController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.controller 2 | 3 | import com.knf.dev.entity.User 4 | import com.knf.dev.repository.UserRepository 5 | import org.springframework.http.HttpStatus 6 | import org.springframework.http.MediaType 7 | import org.springframework.http.ResponseEntity 8 | import org.springframework.stereotype.Controller 9 | import org.springframework.web.bind.annotation.* 10 | import org.springframework.ui.Model 11 | 12 | import org.springframework.web.bind.annotation.GetMapping 13 | import java.util.* 14 | import org.springframework.web.bind.annotation.PathVariable 15 | 16 | 17 | @Controller 18 | class UserController(private val userRepository: UserRepository) { 19 | 20 | @GetMapping("/") 21 | fun getAllUsers(model: Model): String? { 22 | val list: List = userRepository.findAll() 23 | model.addAttribute("users", list) 24 | return "list-users" 25 | } 26 | 27 | @PostMapping(path = ["/createUser"]) 28 | fun createNewUser(@ModelAttribute user: User): String { 29 | userRepository.save(user) 30 | return "redirect:/"; 31 | } 32 | 33 | @GetMapping(path = ["/add"]) 34 | fun addUserById(): String? { 35 | return "add-user" 36 | } 37 | 38 | @GetMapping(path = ["/edit/{id}"]) 39 | fun editUserById(model: Model, @PathVariable("id") id: Long): String? { 40 | model.addAttribute("user", userRepository.findById(id)) 41 | return "edit-user" 42 | } 43 | 44 | @PostMapping(path = ["/editUser"]) 45 | fun editUser(@ModelAttribute user: User): String? { 46 | userRepository.save(user) 47 | return "redirect:/" 48 | } 49 | 50 | @GetMapping(path = ["/delete/{id}"]) 51 | fun deleteUserById(@PathVariable("id") id: Long): String? { 52 | userRepository.deleteById(id) 53 | return "redirect:/" 54 | } 55 | 56 | } -------------------------------------------------------------------------------- /kotlin-spring-h2db-thymeleaf-crud/src/main/kotlin/com/knf/dev/entity/User.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.entity 2 | 3 | import javax.persistence.* 4 | 5 | @Entity 6 | @Table(name = "user") 7 | data class User( 8 | 9 | @Id @GeneratedValue(strategy = GenerationType.AUTO) 10 | val id: Long = 0, 11 | val firstName: String, 12 | val lastName: String, 13 | val email: String 14 | ) 15 | -------------------------------------------------------------------------------- /kotlin-spring-h2db-thymeleaf-crud/src/main/kotlin/com/knf/dev/repository/UserRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.repository 2 | 3 | 4 | import com.knf.dev.entity.User 5 | import org.springframework.data.jpa.repository.JpaRepository 6 | import org.springframework.stereotype.Repository 7 | 8 | @Repository 9 | interface UserRepository : JpaRepository -------------------------------------------------------------------------------- /kotlin-spring-h2db-thymeleaf-crud/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-spring-h2db-thymeleaf-crud/src/main/resources/templates/add-user.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Add User 8 | 9 | 11 | 12 | 13 | 14 | 15 |
16 |

Add User

17 |
18 |
19 |
20 |
22 |
23 |
24 | 25 | 28 |
29 |
30 | 31 | 33 |
34 |
35 | 36 | 38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 | 50 | -------------------------------------------------------------------------------- /kotlin-spring-h2db-thymeleaf-crud/src/main/resources/templates/edit-user.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Add User 8 | 9 | 11 | 12 | 13 | 14 | 15 |
16 |

Update User

17 |
18 |
19 |
20 |
22 |
23 |
24 | 25 | 28 |
29 |
30 | 31 | 33 |
34 |
35 | 36 | 38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 | 50 | -------------------------------------------------------------------------------- /kotlin-spring-h2db-thymeleaf-crud/src/main/resources/templates/list-users.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | All Users 8 | 9 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |
19 |

20 | 21 | Add User 22 |

23 |
24 |

No record found !!

25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 45 | 49 | 50 | 51 |
First NameLast NameEmailEditDelete
44 | 48 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | 59 | 60 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.5.5" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.5.31" 7 | kotlin("plugin.spring") version "1.5.31" 8 | kotlin("plugin.jpa") version "1.5.31" 9 | } 10 | 11 | group = "com.knf.dev.demo" 12 | version = "0.0.1-SNAPSHOT" 13 | java.sourceCompatibility = JavaVersion.VERSION_11 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 21 | implementation("org.springframework.boot:spring-boot-starter-freemarker") 22 | implementation("org.springframework.boot:spring-boot-starter-web") 23 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 24 | implementation("org.jetbrains.kotlin:kotlin-reflect") 25 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 26 | runtimeOnly("com.h2database:h2") 27 | testImplementation("org.springframework.boot:spring-boot-starter-test") 28 | } 29 | 30 | tasks.withType { 31 | kotlinOptions { 32 | freeCompilerArgs = listOf("-Xjsr305=strict") 33 | jvmTarget = "11" 34 | } 35 | } 36 | 37 | tasks.withType { 38 | useJUnitPlatform() 39 | } 40 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowledgefactory4u/kotlin-springboot-app/65c876401a4cb91945ce6768d4d972b98a96c21d/kotlin-spring-jpa-freemarker-crud/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kotlin-spring-jpa-freemarker-crud" 2 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/src/main/kotlin/com/knf/dev/demo/kotlinspringjpafreemarkercrud/KotlinspringjpafreemarkercrudApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpafreemarkercrud 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinspringjpafreemarkercrudApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/src/main/kotlin/com/knf/dev/demo/kotlinspringjpafreemarkercrud/controller/UserController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpafreemarkercrud.controller 2 | 3 | import com.knf.dev.demo.kotlinspringjpafreemarkercrud.model.User 4 | import org.springframework.beans.factory.annotation.Autowired 5 | import com.knf.dev.demo.kotlinspringjpafreemarkercrud.service.UserService 6 | import org.springframework.stereotype.Controller 7 | import org.springframework.ui.Model 8 | import org.springframework.web.bind.annotation.GetMapping 9 | import org.springframework.web.bind.annotation.PostMapping 10 | import org.springframework.web.bind.annotation.ModelAttribute 11 | import org.springframework.web.bind.annotation.PathVariable 12 | import kotlin.Throws 13 | import javax.persistence.EntityNotFoundException 14 | 15 | @Controller 16 | class UserController { 17 | @Autowired 18 | private val userService: UserService? = null 19 | @GetMapping("/") 20 | fun getAllUserView(model: Model): String { 21 | val users = userService!!.allusers 22 | model.addAttribute("users", users) 23 | return "home" 24 | } 25 | 26 | @GetMapping("/create") 27 | fun createUserView(model: Model): String { 28 | val user = User() 29 | model.addAttribute("user", user) 30 | model.addAttribute("isUpdate", false) 31 | return "create-update" 32 | } 33 | 34 | @PostMapping("/update/{id}") 35 | fun createUser( 36 | @ModelAttribute("user") user: User, 37 | @PathVariable("id") id: Long? 38 | ): String { 39 | user.id = id 40 | userService!!.createOrUpdateUser(user) 41 | return "redirect:/" 42 | } 43 | 44 | @GetMapping("/update/{id}") 45 | @Throws(EntityNotFoundException::class) 46 | fun updateUser( 47 | model: Model, 48 | @PathVariable("id") id: Long? 49 | ): String { 50 | val user = userService!!.getUserById(id!!) 51 | model.addAttribute("user", user) 52 | model.addAttribute("isUpdate", true) 53 | return "create-update" 54 | } 55 | 56 | @PostMapping("/create") 57 | fun createUser(@ModelAttribute("user") user: User?): String { 58 | userService!!.createOrUpdateUser(user!!) 59 | return "redirect:/" 60 | } 61 | 62 | @GetMapping("/delete/{id}") 63 | @Throws(EntityNotFoundException::class) 64 | fun deleteUser(@PathVariable("id") id: Long?): String { 65 | userService!!.deleteUserById(id!!) 66 | return "redirect:/" 67 | } 68 | } -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/src/main/kotlin/com/knf/dev/demo/kotlinspringjpafreemarkercrud/model/User.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpafreemarkercrud.model 2 | 3 | import javax.persistence.* 4 | 5 | @Entity 6 | @Table(name = "user") 7 | class User { 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.IDENTITY) 10 | var id: Long? = null 11 | 12 | @Column(name = "first_name") 13 | var firstName: String? = null 14 | 15 | @Column(name = "last_name") 16 | var lastName: String? = null 17 | 18 | @Column(name = "email", nullable = false, length = 200) 19 | var email: String? = null 20 | 21 | constructor() : super() {} 22 | constructor(firstName: String?, lastName: String?, email: String?) : super() { 23 | this.firstName = firstName 24 | this.lastName = lastName 25 | this.email = email 26 | } 27 | 28 | override fun toString(): String { 29 | return ("User [id=" + id + ", firstName=" + firstName + ", lastName=" 30 | + lastName + ", email=" + email + "]") 31 | } 32 | } -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/src/main/kotlin/com/knf/dev/demo/kotlinspringjpafreemarkercrud/repository/UserRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpafreemarkercrud.repository 2 | 3 | import com.knf.dev.demo.kotlinspringjpafreemarkercrud.model.User 4 | import org.springframework.data.repository.CrudRepository 5 | import org.springframework.stereotype.Repository 6 | 7 | @Repository 8 | interface UserRepository : CrudRepository -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/src/main/kotlin/com/knf/dev/demo/kotlinspringjpafreemarkercrud/service/UserService.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpafreemarkercrud.service 2 | 3 | import com.knf.dev.demo.kotlinspringjpafreemarkercrud.model.User 4 | import org.springframework.beans.factory.annotation.Autowired 5 | import com.knf.dev.demo.kotlinspringjpafreemarkercrud.repository.UserRepository 6 | import org.springframework.stereotype.Service 7 | import java.util.ArrayList 8 | import kotlin.Throws 9 | import javax.persistence.EntityNotFoundException 10 | 11 | @Service 12 | class UserService { 13 | @Autowired 14 | var repository: UserRepository? = null 15 | val allusers: List 16 | get() { 17 | val result = repository!!.findAll() as List 18 | return if (result.size > 0) { 19 | result 20 | } else { 21 | ArrayList() 22 | } 23 | } 24 | 25 | @Throws(EntityNotFoundException::class) 26 | fun getUserById(id: Long): User { 27 | val user = repository!!.findById(id) 28 | return if (user.isPresent) { 29 | user.get() 30 | } else { 31 | throw EntityNotFoundException("No user record exist for given id") 32 | } 33 | } 34 | 35 | fun createOrUpdateUser(entity: User): User { 36 | var entity = entity 37 | return if (entity.id == null) { 38 | entity = repository!!.save(entity) 39 | entity 40 | } else { 41 | val user = repository!!.findById( 42 | entity.id!! 43 | ) 44 | if (user.isPresent) { 45 | var newEntity = user.get() 46 | newEntity.email = entity.email 47 | newEntity.firstName = entity.firstName 48 | newEntity.lastName = entity.lastName 49 | newEntity = repository!!.save(newEntity) 50 | newEntity 51 | } else { 52 | entity = repository!!.save(entity) 53 | entity 54 | } 55 | } 56 | } 57 | 58 | @Throws(EntityNotFoundException::class) 59 | fun deleteUserById(id: Long) { 60 | val user = repository!!.findById(id) 61 | if (user.isPresent) { 62 | repository!!.deleteById(id) 63 | } else { 64 | throw EntityNotFoundException("No user record exist for given id") 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/src/main/resources/templates/create-update.ftlh: -------------------------------------------------------------------------------- 1 | 2 | 3 | Freemarker Example 4 | 5 | 6 | 8 | 10 | 12 | 13 | 14 |
15 |

16 | <#if !isUpdate>Create 17 | <#if isUpdate>Update 18 | User 19 |

20 |
21 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | <#if isUpdate> 33 | 34 | 35 | 38 | 39 | 40 | 41 | 42 | 45 | 46 | 47 | 48 | 50 | 51 | 52 | 53 | 55 | 56 | 57 |
FieldValue
ID 36 |
${user.id}
37 |
First Name 44 |
Last Name
Email
58 | 59 |
60 |
61 |
62 | 63 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/src/main/resources/templates/home.ftlh: -------------------------------------------------------------------------------- 1 | 2 | 3 | Freemarker Example 4 | 5 | 6 | 8 | 10 | 12 | 13 | 14 |
15 |

User CRUD operation with Freemarker Template

16 | Create New User 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | <#list users as user> 30 | 31 | 32 | 33 | 34 | 35 | 37 | 39 | 40 | 41 | 42 |
IdFirst NameLast NameEmail
${user.id}${user.firstName}${user.lastName}${user.email} 36 | Update 38 | Delete
43 |
44 | 45 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-freemarker-crud/src/test/kotlin/com/knf/dev/demo/kotlinspringjpafreemarkercrud/KotlinspringjpafreemarkercrudApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpafreemarkercrud 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KotlinspringjpafreemarkercrudApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.5.5" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.5.31" 7 | kotlin("plugin.spring") version "1.5.31" 8 | kotlin("plugin.jpa") version "1.5.31" 9 | } 10 | 11 | group = "com.knf.dev.demo" 12 | version = "0.0.1-SNAPSHOT" 13 | java.sourceCompatibility = JavaVersion.VERSION_11 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 21 | implementation("org.springframework.boot:spring-boot-starter-groovy-templates") 22 | implementation("org.springframework.boot:spring-boot-starter-web") 23 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 24 | implementation("org.jetbrains.kotlin:kotlin-reflect") 25 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 26 | runtimeOnly("com.h2database:h2") 27 | testImplementation("org.springframework.boot:spring-boot-starter-test") 28 | } 29 | 30 | tasks.withType { 31 | kotlinOptions { 32 | freeCompilerArgs = listOf("-Xjsr305=strict") 33 | jvmTarget = "11" 34 | } 35 | } 36 | 37 | tasks.withType { 38 | useJUnitPlatform() 39 | } 40 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowledgefactory4u/kotlin-springboot-app/65c876401a4cb91945ce6768d4d972b98a96c21d/kotlin-spring-jpa-groovy-crud-example/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kotlin-spring-jpa-groovy-crud-example" 2 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/src/main/kotlin/com/knf/dev/demo/kotlinspringbootcrudexample/KotlinspringbootcrudexampleApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringbootcrudexample 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinspringbootcrudexampleApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/src/main/kotlin/com/knf/dev/demo/kotlinspringbootcrudexample/controller/UserController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringbootcrudexample.controller 2 | 3 | import com.knf.dev.demo.kotlinspringbootcrudexample.model.User 4 | import org.springframework.beans.factory.annotation.Autowired 5 | import com.knf.dev.demo.kotlinspringbootcrudexample.service.UserService 6 | import org.springframework.stereotype.Controller 7 | import org.springframework.ui.Model 8 | import org.springframework.web.bind.annotation.GetMapping 9 | import org.springframework.web.bind.annotation.PostMapping 10 | import org.springframework.web.bind.annotation.ModelAttribute 11 | import org.springframework.web.bind.annotation.PathVariable 12 | import kotlin.Throws 13 | import javax.persistence.EntityNotFoundException 14 | 15 | @Controller 16 | class UserController { 17 | @Autowired 18 | private val userService: UserService? = null 19 | @GetMapping("/") 20 | fun getAllUserView(model: Model): String { 21 | val users = userService!!.allusers 22 | model.addAttribute("users", users) 23 | return "home" 24 | } 25 | 26 | @GetMapping("/create") 27 | fun createUserView(model: Model): String { 28 | val user = User() 29 | model.addAttribute("user", user) 30 | model.addAttribute("create", true) 31 | model.addAttribute("actionUrl", "/create") 32 | return "create-update" 33 | } 34 | 35 | @PostMapping("/update/{id}") 36 | fun createUser( 37 | @ModelAttribute("user") user: User, 38 | @PathVariable("id") id: Long? 39 | ): String { 40 | user.id = id 41 | userService!!.createOrUpdateUser(user) 42 | return "redirect:/" 43 | } 44 | 45 | @GetMapping("/update/{id}") 46 | @Throws(EntityNotFoundException::class) 47 | fun updateUser(model: Model, @PathVariable("id") id: Long?): 48 | String { 49 | val user = userService!!.getUserById(id!!) 50 | model.addAttribute("user", user) 51 | model.addAttribute("create", false) 52 | model.addAttribute( 53 | "actionUrl", 54 | "/update/" + if (user == null) 0 else user.id 55 | ) 56 | return "create-update" 57 | } 58 | 59 | @PostMapping("/create") 60 | fun createUser(@ModelAttribute("user") user: User?): String { 61 | userService!!.createOrUpdateUser(user!!) 62 | return "redirect:/" 63 | } 64 | 65 | @GetMapping("/delete/{id}") 66 | @Throws(EntityNotFoundException::class) 67 | fun deleteUser(@PathVariable("id") id: Long?): String { 68 | userService!!.deleteUserById(id!!) 69 | return "redirect:/" 70 | } 71 | } -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/src/main/kotlin/com/knf/dev/demo/kotlinspringbootcrudexample/model/User.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringbootcrudexample.model 2 | 3 | import javax.persistence.* 4 | 5 | @Entity 6 | @Table(name = "user") 7 | class User { 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.IDENTITY) 10 | var id: Long? = null 11 | 12 | @Column(name = "first_name") 13 | var first_name: String? = null 14 | 15 | @Column(name = "last_name") 16 | var last_name: String? = null 17 | 18 | @Column(name = "email", nullable = false, length = 200) 19 | var email: String? = null 20 | } -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/src/main/kotlin/com/knf/dev/demo/kotlinspringbootcrudexample/repository/UserRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringbootcrudexample.repository 2 | 3 | import com.knf.dev.demo.kotlinspringbootcrudexample.model.User 4 | import org.springframework.data.repository.CrudRepository 5 | import org.springframework.stereotype.Repository 6 | 7 | @Repository 8 | interface UserRepository : CrudRepository -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/src/main/kotlin/com/knf/dev/demo/kotlinspringbootcrudexample/service/UserService.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringbootcrudexample.service 2 | 3 | import com.knf.dev.demo.kotlinspringbootcrudexample.model.User 4 | import org.springframework.beans.factory.annotation.Autowired 5 | import com.knf.dev.demo.kotlinspringbootcrudexample.repository.UserRepository 6 | import org.springframework.stereotype.Service 7 | import java.util.ArrayList 8 | import kotlin.Throws 9 | import javax.persistence.EntityNotFoundException 10 | 11 | @Service 12 | class UserService { 13 | @Autowired 14 | var repository: UserRepository? = null 15 | val allusers: List 16 | get() { 17 | val result = repository!!.findAll() as List 18 | return if (result.size > 0) { 19 | result 20 | } else { 21 | ArrayList() 22 | } 23 | } 24 | 25 | @Throws(EntityNotFoundException::class) 26 | fun getUserById(id: Long): User { 27 | val user = repository!!.findById(id) 28 | return if (user.isPresent) { 29 | user.get() 30 | } else { 31 | throw EntityNotFoundException("No user record exist for given id") 32 | } 33 | } 34 | 35 | fun createOrUpdateUser(entity: User): User { 36 | var entity = entity 37 | return if (entity.id == null) { 38 | entity = repository!!.save(entity) 39 | entity 40 | } else { 41 | val user = repository!!.findById( 42 | entity.id!! 43 | ) 44 | if (user.isPresent) { 45 | var newEntity = user.get() 46 | newEntity.email = entity.email 47 | newEntity.first_name = entity.first_name 48 | newEntity.last_name = entity.last_name 49 | newEntity = repository!!.save(newEntity) 50 | newEntity 51 | } else { 52 | entity = repository!!.save(entity) 53 | entity 54 | } 55 | } 56 | } 57 | 58 | @Throws(EntityNotFoundException::class) 59 | fun deleteUserById(id: Long) { 60 | val user = repository!!.findById(id) 61 | if (user.isPresent) { 62 | repository!!.deleteById(id) 63 | } else { 64 | throw EntityNotFoundException("No user record exist for given id") 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/src/main/resources/templates/create-update.tpl: -------------------------------------------------------------------------------- 1 | yieldUnescaped '' 2 | html(lang: 'en') { 3 | head { 4 | meta('http-equiv': '"Content-Type" content="text/html; ' + 5 | 'charset=utf-8"') 6 | title("Groovy example") 7 | link(rel: "stylesheet", type: "text/css", 8 | href: "https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css") 9 | } 10 | body { 11 | div(class: 'container') { 12 | if (create) { 13 | h1("Create a User:") 14 | } else { 15 | h1("Edit User") 16 | } 17 | a(class: 'btn btn-primary', href: "/", "Back to User List") 18 | br() 19 | br() 20 | form(id: "editForm", action: "$actionUrl", method: "POST") { 21 | table(class: 'table') { 22 | if (!create) { 23 | tr { 24 | td("Id") 25 | td(":") 26 | td(user.id ?: '') 27 | } 28 | } 29 | tr { 30 | td("First Name") 31 | td(":") 32 | td { 33 | input(name: 'first_name', type: 'text', 34 | value: user.last_name ?: '') 35 | } 36 | } 37 | tr { 38 | td("Last Name") 39 | td(":") 40 | td { 41 | input(name: 'last_name', type: 'text', 42 | value: user.last_name ?: '') 43 | } 44 | } 45 | tr { 46 | td("Email") 47 | td(":") 48 | td { 49 | input(name: 'email', type: 'text', 50 | value: user.email ?: '') 51 | } 52 | } 53 | } 54 | br() 55 | if (create) { 56 | input(class: 'btn btn-success', type: 'submit', 57 | value: 'Create') 58 | } else { 59 | input(class: 'btn btn-success', type: 'submit', 60 | value: 'Update') 61 | } 62 | } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/src/main/resources/templates/home.tpl: -------------------------------------------------------------------------------- 1 | yieldUnescaped '' 2 | html(lang: 'en') { 3 | head { 4 | meta('http-equiv': '"Content-Type" content="text/html; ' + 5 | 'charset=utf-8"') 6 | title("Groovy example") 7 | link(rel: "stylesheet", type: "text/css", 8 | href: "https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css") 9 | 10 | } 11 | body { 12 | 13 | div(class: 'container') { 14 | h2("User CRUD operation with Groovy Template") 15 | div { 16 | nobr { 17 | a(class: 'btn btn-primary', href: "/create", "Add User") 18 | } 19 | } 20 | br() 21 | br() 22 | div { 23 | table(class: 'table') { 24 | tr { 25 | th("Id") 26 | th("First Name") 27 | th("Last Name") 28 | th("Email") 29 | th("") 30 | th("") 31 | } 32 | users.each { user -> 33 | tr { 34 | td("$user.id") 35 | td("$user.first_name") 36 | td("$user.last_name") 37 | td("$user.email") 38 | td { 39 | a(class: 'btn btn-warning', 40 | href: "/update/$user.id", "Edit") 41 | } 42 | td { 43 | a(class: 'btn btn-danger', 44 | href: "/delete/$user.id", "Delete") 45 | } 46 | } 47 | } 48 | } 49 | } 50 | 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-groovy-crud-example/src/test/kotlin/com/knf/dev/demo/kotlinspringbootcrudexample/KotlinspringbootcrudexampleApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringbootcrudexample 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KotlinspringbootcrudexampleApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.5.5" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.5.31" 7 | kotlin("plugin.spring") version "1.5.31" 8 | kotlin("plugin.jpa") version "1.5.31" 9 | } 10 | 11 | group = "com.knf.dev.demo" 12 | version = "0.0.1-SNAPSHOT" 13 | java.sourceCompatibility = JavaVersion.VERSION_11 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | implementation("org.springframework.boot:spring-boot-starter-data-jpa") 21 | implementation("org.springframework.boot:spring-boot-starter-mustache") 22 | implementation("org.springframework.boot:spring-boot-starter-web") 23 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 24 | implementation("org.jetbrains.kotlin:kotlin-reflect") 25 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 26 | runtimeOnly("com.h2database:h2") 27 | testImplementation("org.springframework.boot:spring-boot-starter-test") 28 | } 29 | 30 | tasks.withType { 31 | kotlinOptions { 32 | freeCompilerArgs = listOf("-Xjsr305=strict") 33 | jvmTarget = "11" 34 | } 35 | } 36 | 37 | tasks.withType { 38 | useJUnitPlatform() 39 | } 40 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowledgefactory4u/kotlin-springboot-app/65c876401a4cb91945ce6768d4d972b98a96c21d/kotlin-spring-jpa-mustache-crud/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kotlin-spring-jpa-mustache-crud" 2 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/src/main/kotlin/com/knf/dev/demo/kotlinspringjpamustachecrud/KotlinspringjpamustachecrudApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpamustachecrud 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinspringjpamustachecrudApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/src/main/kotlin/com/knf/dev/demo/kotlinspringjpamustachecrud/controller/UserController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpamustachecrud.controller 2 | 3 | import com.knf.dev.demo.kotlinspringjpamustachecrud.model.User 4 | import org.springframework.beans.factory.annotation.Autowired 5 | import com.knf.dev.demo.kotlinspringjpamustachecrud.service.UserService 6 | import org.springframework.stereotype.Controller 7 | import org.springframework.ui.Model 8 | import org.springframework.web.bind.annotation.GetMapping 9 | import org.springframework.web.bind.annotation.PostMapping 10 | import org.springframework.web.bind.annotation.ModelAttribute 11 | import org.springframework.web.bind.annotation.PathVariable 12 | import kotlin.Throws 13 | import javax.persistence.EntityNotFoundException 14 | 15 | @Controller 16 | class UserController { 17 | @Autowired 18 | private val userService: UserService? = null 19 | @GetMapping("/") 20 | fun getAllUserView(model: Model): String { 21 | val users = userService!!.allusers 22 | model.addAttribute("users", users) 23 | return "home" 24 | } 25 | 26 | @GetMapping("/create") 27 | fun createUserView(model: Model): String { 28 | val user = User() 29 | model.addAttribute("user", user) 30 | model.addAttribute("isUpdate", false) 31 | return "create-update" 32 | } 33 | 34 | @PostMapping("/update/{id}") 35 | fun createUser( 36 | @ModelAttribute("user") user: User, 37 | @PathVariable("id") id: Long? 38 | ): String { 39 | user.id = id 40 | userService!!.createOrUpdateUser(user) 41 | return "redirect:/" 42 | } 43 | 44 | @GetMapping("/update/{id}") 45 | @Throws(EntityNotFoundException::class) 46 | fun updateUser(model: Model, @PathVariable("id") id: Long?): String { 47 | val user = userService!!.getUserById(id!!) 48 | model.addAttribute("user", user) 49 | model.addAttribute("isUpdate", true) 50 | return "create-update" 51 | } 52 | 53 | @PostMapping("/create") 54 | fun createUser(@ModelAttribute("user") user: User?): String { 55 | userService!!.createOrUpdateUser(user!!) 56 | return "redirect:/" 57 | } 58 | 59 | @GetMapping("/delete/{id}") 60 | @Throws(EntityNotFoundException::class) 61 | fun deleteUser(@PathVariable("id") id: Long?): String { 62 | userService!!.deleteUserById(id!!) 63 | return "redirect:/" 64 | } 65 | } -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/src/main/kotlin/com/knf/dev/demo/kotlinspringjpamustachecrud/model/User.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpamustachecrud.model 2 | 3 | import javax.persistence.* 4 | 5 | @Entity 6 | @Table(name = "user") 7 | class User { 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.IDENTITY) 10 | var id: Long? = null 11 | 12 | @Column(name = "first_name") 13 | var first_name: String? = null 14 | 15 | @Column(name = "last_name") 16 | var last_name: String? = null 17 | 18 | @Column(name = "email", nullable = false, length = 200) 19 | var email: String? = null 20 | } -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/src/main/kotlin/com/knf/dev/demo/kotlinspringjpamustachecrud/repository/UserRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpamustachecrud.repository 2 | 3 | import com.knf.dev.demo.kotlinspringjpamustachecrud.model.User 4 | import org.springframework.data.repository.CrudRepository 5 | import org.springframework.stereotype.Repository 6 | 7 | @Repository 8 | interface UserRepository : CrudRepository -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/src/main/kotlin/com/knf/dev/demo/kotlinspringjpamustachecrud/service/UserService.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpamustachecrud.service 2 | 3 | import com.knf.dev.demo.kotlinspringjpamustachecrud.model.User 4 | import org.springframework.beans.factory.annotation.Autowired 5 | import com.knf.dev.demo.kotlinspringjpamustachecrud.repository.UserRepository 6 | import org.springframework.stereotype.Service 7 | import java.util.ArrayList 8 | import kotlin.Throws 9 | import javax.persistence.EntityNotFoundException 10 | 11 | @Service 12 | class UserService { 13 | @Autowired 14 | var repository: UserRepository? = null 15 | val allusers: List 16 | get() { 17 | val result = repository!!.findAll() as List 18 | return if (result.size > 0) { 19 | result 20 | } else { 21 | ArrayList() 22 | } 23 | } 24 | 25 | @Throws(EntityNotFoundException::class) 26 | fun getUserById(id: Long): User { 27 | val user = repository!!.findById(id) 28 | return if (user.isPresent) { 29 | user.get() 30 | } else { 31 | throw EntityNotFoundException("No user record exist for given id") 32 | } 33 | } 34 | 35 | fun createOrUpdateUser(entity: User): User { 36 | var entity = entity 37 | return if (entity.id == null) { 38 | entity = repository!!.save(entity) 39 | entity 40 | } else { 41 | val user = repository!!.findById( 42 | entity.id!! 43 | ) 44 | if (user.isPresent) { 45 | var newEntity = user.get() 46 | newEntity.email = entity.email 47 | newEntity.first_name = entity.first_name 48 | newEntity.last_name = entity.last_name 49 | newEntity = repository!!.save(newEntity) 50 | newEntity 51 | } else { 52 | entity = repository!!.save(entity) 53 | entity 54 | } 55 | } 56 | } 57 | 58 | @Throws(EntityNotFoundException::class) 59 | fun deleteUserById(id: Long) { 60 | val user = repository!!.findById(id) 61 | if (user.isPresent) { 62 | repository!!.deleteById(id) 63 | } else { 64 | throw EntityNotFoundException("No user record exist for given id") 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/src/main/resources/templates/create-update.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | Mustache Example 4 | 5 | 6 | 8 | 10 | 12 | 13 | 14 |
15 |

{{^isUpdate}}Create{{/isUpdate}} 16 | {{#isUpdate}}Update{{/isUpdate}}User

17 |
18 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{#isUpdate}} 31 | 32 | 33 | 34 | 35 | {{/isUpdate}} 36 | {{#user}} 37 | 38 | 39 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 51 | 52 | {{/user}} 53 | 54 |
FieldValue
ID
{{user.id}}
First Name
Last Name
Email
55 | 56 |
57 |
58 |
59 | 60 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/src/main/resources/templates/home.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | Mustache Example 4 | 5 | 6 | 8 | 10 | 12 | 13 | 14 |
15 |

User CRUD operation with Mustache Template

16 | Create New User 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | {{#users}} 30 | 31 | 32 | 33 | 34 | 35 | 37 | 39 | 40 | {{/users}} 41 | 42 |
IdFirst NameLast NameEmail
{{id}}{{first_name}}{{last_name}}{{email}} 36 | Update 38 | Delete
43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /kotlin-spring-jpa-mustache-crud/src/test/kotlin/com/knf/dev/demo/kotlinspringjpamustachecrud/KotlinspringjpamustachecrudApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringjpamustachecrud 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KotlinspringjpamustachecrudApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-spring-keycloak/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.5.5" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.5.31" 7 | kotlin("plugin.spring") version "1.5.31" 8 | } 9 | 10 | group = "com.knf.dev.demo" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | configurations { 15 | compileOnly { 16 | extendsFrom(configurations.annotationProcessor.get()) 17 | } 18 | } 19 | 20 | repositories { 21 | mavenCentral() 22 | } 23 | 24 | dependencies { 25 | implementation("org.springframework.boot:spring-boot-starter-security") 26 | implementation("org.springframework.boot:spring-boot-starter-web") 27 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 28 | implementation("org.jetbrains.kotlin:kotlin-reflect") 29 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 30 | implementation("org.keycloak:keycloak-spring-boot-starter:15.0.2") 31 | implementation("org.keycloak:keycloak-admin-client:15.0.2") 32 | implementation(platform("org.keycloak.bom:keycloak-adapter-bom:15.0.2")) 33 | testImplementation("org.springframework.boot:spring-boot-starter-test") 34 | testImplementation("org.springframework.security:spring-security-test") 35 | } 36 | 37 | tasks.withType { 38 | kotlinOptions { 39 | freeCompilerArgs = listOf("-Xjsr305=strict") 40 | jvmTarget = "11" 41 | } 42 | } 43 | 44 | tasks.withType { 45 | useJUnitPlatform() 46 | } 47 | -------------------------------------------------------------------------------- /kotlin-spring-keycloak/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowledgefactory4u/kotlin-springboot-app/65c876401a4cb91945ce6768d4d972b98a96c21d/kotlin-spring-keycloak/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kotlin-spring-keycloak/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kotlin-spring-keycloak/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kotlin-spring-keycloak" 2 | -------------------------------------------------------------------------------- /kotlin-spring-keycloak/src/main/kotlin/com/knf/dev/demo/kotlinspringkeycloakdemo/Application.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringkeycloakdemo 2 | 3 | import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver 4 | import org.springframework.boot.SpringApplication 5 | import org.springframework.boot.autoconfigure.SpringBootApplication 6 | import org.springframework.context.annotation.Bean 7 | 8 | @SpringBootApplication 9 | class Application { 10 | @Bean 11 | fun keycloakSpringBootConfigResolver(): KeycloakSpringBootConfigResolver { 12 | return KeycloakSpringBootConfigResolver() 13 | } 14 | 15 | companion object { 16 | @JvmStatic 17 | fun main(args: Array) { 18 | SpringApplication.run(Application::class.java, *args) 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /kotlin-spring-keycloak/src/main/kotlin/com/knf/dev/demo/kotlinspringkeycloakdemo/Vo/EmployeeVO.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringkeycloakdemo.Vo 2 | 3 | class EmployeeVO { 4 | 5 | val email: String? = null 6 | val password: String? = null 7 | val firstname: String? = null 8 | val lastname: String? = null 9 | var statusCode = 0 10 | var status: String? = null 11 | } -------------------------------------------------------------------------------- /kotlin-spring-keycloak/src/main/kotlin/com/knf/dev/demo/kotlinspringkeycloakdemo/config/SecurityConfig.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringkeycloakdemo.config 2 | 3 | import org.keycloak.adapters.KeycloakConfigResolver 4 | import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver 5 | import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter 6 | import org.springframework.beans.factory.annotation.Autowired 7 | import org.springframework.context.annotation.Bean 8 | import org.springframework.context.annotation.Configuration 9 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder 10 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity 11 | import org.springframework.security.config.annotation.web.builders.HttpSecurity 12 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity 13 | import org.springframework.security.config.http.SessionCreationPolicy 14 | import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper 15 | import org.springframework.security.core.session.SessionRegistryImpl 16 | import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy 17 | import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy 18 | 19 | @Configuration 20 | @EnableWebSecurity 21 | @EnableGlobalMethodSecurity(jsr250Enabled = true) 22 | class SecurityConfig : KeycloakWebSecurityConfigurerAdapter() { 23 | @Throws(Exception::class) 24 | override fun configure(http: HttpSecurity) { 25 | super.configure(http) 26 | http.cors().and().csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) 27 | .and().authorizeRequests() 28 | .antMatchers("/employees/unprotected").permitAll() 29 | .antMatchers("/employees/create").permitAll() 30 | .antMatchers("/employees/login").permitAll() 31 | .anyRequest().authenticated() 32 | } 33 | 34 | @Autowired 35 | @Throws(Exception::class) 36 | fun configureGlobal(auth: AuthenticationManagerBuilder) { 37 | val keycloakAuthenticationProvider = keycloakAuthenticationProvider() 38 | keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(SimpleAuthorityMapper()) 39 | auth.authenticationProvider(keycloakAuthenticationProvider) 40 | } 41 | 42 | @Bean 43 | override fun sessionAuthenticationStrategy(): SessionAuthenticationStrategy { 44 | return RegisterSessionAuthenticationStrategy(SessionRegistryImpl()) 45 | } 46 | 47 | @Bean 48 | fun KeycloakConfigResolver(): KeycloakConfigResolver { 49 | return KeycloakSpringBootConfigResolver() 50 | } 51 | } -------------------------------------------------------------------------------- /kotlin-spring-keycloak/src/main/kotlin/com/knf/dev/demo/kotlinspringkeycloakdemo/controller/EmployeeController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringkeycloakdemo.controller 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping 4 | import org.springframework.web.bind.annotation.RestController 5 | import org.springframework.beans.factory.annotation.Autowired 6 | import com.knf.dev.demo.kotlinspringkeycloakdemo.service.KeycloakService 7 | import org.springframework.web.bind.annotation.PostMapping 8 | import org.springframework.web.bind.annotation.RequestBody 9 | import com.knf.dev.demo.kotlinspringkeycloakdemo.Vo.EmployeeVO 10 | import org.springframework.http.ResponseEntity 11 | import org.springframework.web.bind.annotation.GetMapping 12 | 13 | @RequestMapping(value = ["/employees"]) 14 | @RestController 15 | class EmployeeController { 16 | @Autowired 17 | private val keycloakService: KeycloakService? = null 18 | @PostMapping(path = ["/create"]) 19 | fun createEmployee(@RequestBody employeeVo: EmployeeVO?): ResponseEntity<*> { 20 | return ResponseEntity.ok(keycloakService!!.createEmployee(employeeVo!!)) 21 | } 22 | 23 | @PostMapping(path = ["/login"]) 24 | fun login(@RequestBody employeeVo: EmployeeVO?): ResponseEntity<*> { 25 | return ResponseEntity.ok(keycloakService!!.login(employeeVo!!)) 26 | } 27 | 28 | @get:GetMapping(value = ["/unprotected"]) 29 | val unProtectedData: String 30 | get() = "This api is not protected." 31 | 32 | @get:GetMapping(value = ["/protected"]) 33 | val protectedData: String 34 | get() = "This api is protected." 35 | } -------------------------------------------------------------------------------- /kotlin-spring-keycloak/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port = 9080 2 | keycloak.auth-server-url = http://localhost:8080/auth 3 | keycloak.realm = knowledgefactory-realm 4 | keycloak.resource = knowledgefactory-client 5 | keycloak.public-client = true 6 | keycloak.use-resource-role-mappings = true 7 | keycloak.ssl-required = external 8 | server.connection-timeout = 9000 9 | keycloak.credentials.secret = 86996cf7-5030-4a37-948b-99223f8bdabf 10 | -------------------------------------------------------------------------------- /kotlin-spring-keycloak/src/test/kotlin/com/knf/dev/demo/kotlinspringkeycloakdemo/KotlinspringkeycloakdemoApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringkeycloakdemo 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KotlinspringkeycloakdemoApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-spring-oauth2-google/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.5.4" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.5.21" 7 | kotlin("plugin.spring") version "1.5.21" 8 | } 9 | 10 | group = "com.knf.dev.demo" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | repositories { 15 | mavenCentral() 16 | } 17 | 18 | dependencies { 19 | implementation("org.springframework.boot:spring-boot-starter-oauth2-client") 20 | implementation("org.springframework.boot:spring-boot-starter-security") 21 | implementation("org.springframework.boot:spring-boot-starter-thymeleaf") 22 | implementation("org.springframework.boot:spring-boot-starter-web") 23 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 24 | implementation("org.jetbrains.kotlin:kotlin-reflect") 25 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 26 | implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity5") 27 | testImplementation("org.springframework.boot:spring-boot-starter-test") 28 | testImplementation("org.springframework.security:spring-security-test") 29 | } 30 | 31 | tasks.withType { 32 | kotlinOptions { 33 | freeCompilerArgs = listOf("-Xjsr305=strict") 34 | jvmTarget = "11" 35 | } 36 | } 37 | 38 | tasks.withType { 39 | useJUnitPlatform() 40 | } 41 | -------------------------------------------------------------------------------- /kotlin-spring-oauth2-google/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowledgefactory4u/kotlin-springboot-app/65c876401a4cb91945ce6768d4d972b98a96c21d/kotlin-spring-oauth2-google/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kotlin-spring-oauth2-google/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kotlin-spring-oauth2-google/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kotlin-spring-oauth2-google" 2 | -------------------------------------------------------------------------------- /kotlin-spring-oauth2-google/src/main/kotlin/com/knf/dev/demo/kotlinspringOauth2google/KotlinspringOauth2googleApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringOauth2google 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinspringOauth2googleApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-oauth2-google/src/main/kotlin/com/knf/dev/demo/kotlinspringOauth2google/config/SecurityConfig.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringOauth2google.config 2 | 3 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity 4 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter 5 | import kotlin.Throws 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity 7 | import java.lang.Exception 8 | 9 | @EnableWebSecurity 10 | class SecurityConfig : WebSecurityConfigurerAdapter() { 11 | @Throws(Exception::class) 12 | public override fun configure(httpSecurity: HttpSecurity) { 13 | httpSecurity.csrf().disable().antMatcher("/**").authorizeRequests() 14 | .antMatchers("/", "/index").authenticated() 15 | .anyRequest().authenticated() 16 | .and() 17 | .oauth2Login().permitAll() 18 | .and() 19 | .logout() 20 | .invalidateHttpSession(true) 21 | .clearAuthentication(true) 22 | .logoutSuccessUrl("/") 23 | } 24 | } -------------------------------------------------------------------------------- /kotlin-spring-oauth2-google/src/main/kotlin/com/knf/dev/demo/kotlinspringOauth2google/config/WebMvcConfig.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringOauth2google.config 2 | 3 | import org.springframework.context.annotation.Configuration 4 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer 5 | import org.springframework.web.servlet.config.annotation.ViewControllerRegistry 6 | 7 | @Configuration 8 | class WebMvcConfig : WebMvcConfigurer { 9 | override fun addViewControllers(registry: ViewControllerRegistry) { 10 | registry.addViewController("/").setViewName("index") 11 | registry.addViewController("/index").setViewName("index") 12 | } 13 | } -------------------------------------------------------------------------------- /kotlin-spring-oauth2-google/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | security: 3 | oauth2: 4 | client: 5 | registration: 6 | google: 7 | client-id: 8 | client-secret: 9 | -------------------------------------------------------------------------------- /kotlin-spring-oauth2-google/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Kotlin + Spring OAuth2 Login with Google - Demo 7 | 8 | 9 | 11 | 13 | 15 | 16 | 17 | 43 | 44 |
45 |
46 |
47 |
48 |
49 |

Welcome

50 |

You have been successfully logged in

51 |
52 |
53 |
54 | 55 | -------------------------------------------------------------------------------- /kotlin-spring-oauth2-google/src/test/kotlin/com/knf/dev/demo/kotlinspringOauth2google/KotlinspringOauth2googleApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringOauth2google 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KotlinspringOauth2googleApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-spring-restful-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.7.RELEASE 9 | 10 | 11 | com.knf.dev 12 | kotlin-spring-restful-api 13 | 0.0.1-SNAPSHOT 14 | kotlin-spring-restful-api 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 1.3.72 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-data-mongodb 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | com.fasterxml.jackson.module 33 | jackson-module-kotlin 34 | 35 | 36 | org.jetbrains.kotlin 37 | kotlin-reflect 38 | 39 | 40 | org.jetbrains.kotlin 41 | kotlin-stdlib-jdk8 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-test 47 | test 48 | 49 | 50 | org.junit.vintage 51 | junit-vintage-engine 52 | 53 | 54 | 55 | 56 | 57 | 58 | ${project.basedir}/src/main/kotlin 59 | ${project.basedir}/src/test/kotlin 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-maven-plugin 64 | 65 | 66 | org.jetbrains.kotlin 67 | kotlin-maven-plugin 68 | 69 | 70 | -Xjsr305=strict 71 | 72 | 73 | spring 74 | 75 | 76 | 77 | 78 | org.jetbrains.kotlin 79 | kotlin-maven-allopen 80 | ${kotlin.version} 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /kotlin-spring-restful-api/src/main/kotlin/com/knf/dev/SpringbootKotlinCrudApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class SpringbootKotlinCrudApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-restful-api/src/main/kotlin/com/knf/dev/controller/EmployeeController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.controller 2 | 3 | 4 | import com.knf.dev.model.Employee 5 | import com.knf.dev.repository.EmployeeRepository 6 | import org.springframework.http.HttpStatus 7 | import org.springframework.http.ResponseEntity 8 | import org.springframework.web.bind.annotation.* 9 | import java.util.* 10 | 11 | 12 | @RestController 13 | @RequestMapping("/api/v1/") 14 | class EmployeeController(private val employeeRepository: EmployeeRepository) { 15 | 16 | @GetMapping("/employees") 17 | fun getAllEmployees(): List = 18 | employeeRepository.findAll() 19 | 20 | @PostMapping("/employees") 21 | fun createNewEmployee(@RequestBody employee: Employee): Employee = 22 | employeeRepository.save(employee) 23 | 24 | @GetMapping("/employees/{id}") 25 | fun getEmployeeById(@PathVariable(value = "id") employeeId: String): ResponseEntity { 26 | return employeeRepository.findById(employeeId).map { emp -> 27 | ResponseEntity.ok(emp) 28 | }.orElse(ResponseEntity.notFound().build()) 29 | } 30 | 31 | @PutMapping("/employees/{id}") 32 | fun updateEmployeeById(@PathVariable(value = "id") employeeId: String, 33 | @RequestBody newEmployee: Employee): ResponseEntity { 34 | 35 | return employeeRepository.findById(employeeId).map { existingEmployee -> 36 | val updatedEmployee: Employee = existingEmployee 37 | .copy(firstName = newEmployee.firstName, lastName = newEmployee.lastName, emailId = newEmployee.emailId) 38 | ResponseEntity.ok().body(employeeRepository.save(updatedEmployee)) 39 | }.orElse(ResponseEntity.notFound().build()) 40 | 41 | } 42 | 43 | @DeleteMapping("/employees/{id}") 44 | fun deleteEmployeeById(@PathVariable(value = "id") employeeId: String): ResponseEntity { 45 | return employeeRepository.findById(employeeId).map { emp -> 46 | employeeRepository.delete(emp) 47 | ResponseEntity(HttpStatus.OK) 48 | }.orElse(ResponseEntity.notFound().build()) 49 | 50 | } 51 | } -------------------------------------------------------------------------------- /kotlin-spring-restful-api/src/main/kotlin/com/knf/dev/model/Employee.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.model 2 | 3 | import org.bson.types.ObjectId 4 | import org.springframework.data.annotation.Id 5 | import org.springframework.data.mongodb.core.mapping.Document 6 | import org.springframework.web.bind.annotation.CrossOrigin 7 | 8 | @Document(collection = "employees") 9 | data class Employee( 10 | @Id 11 | var id: String? = ObjectId().toHexString(), 12 | val firstName: String, 13 | val lastName: String, 14 | val emailId: String 15 | ) -------------------------------------------------------------------------------- /kotlin-spring-restful-api/src/main/kotlin/com/knf/dev/repository/EmployeeRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.repository 2 | 3 | 4 | import com.knf.dev.model.Employee 5 | import org.springframework.data.mongodb.repository.MongoRepository 6 | import org.springframework.stereotype.Repository 7 | 8 | @Repository 9 | interface EmployeeRepository : MongoRepository -------------------------------------------------------------------------------- /kotlin-spring-restful-api/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-spring-restful-api/src/test/kotlin/com/knf/dev/SpringbootKotlinCrudApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class SpringbootKotlinCrudApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | org.springframework.boot 9 | spring-boot-starter-parent 10 | 2.5.5 11 | 12 | 13 | com.knf.dev.demo 14 | kotlin-spring-thymeleaf-login-signup 15 | 0.0.1-SNAPSHOT 16 | kotlin-spring-thymeleaf-login-signup 17 | Demo project for Spring Boot 18 | 19 | 11 20 | 1.5.31 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-data-jpa 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-security 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-thymeleaf 38 | 39 | 40 | com.fasterxml.jackson.module 41 | jackson-module-kotlin 42 | 43 | 44 | org.jetbrains.kotlin 45 | kotlin-reflect 46 | 47 | 48 | org.jetbrains.kotlin 49 | kotlin-stdlib-jdk8 50 | 51 | 52 | 53 | com.h2database 54 | h2 55 | runtime 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-test 60 | test 61 | 62 | 63 | org.springframework.security 64 | spring-security-test 65 | test 66 | 67 | 68 | 69 | 70 | ${project.basedir}/src/main/kotlin 71 | ${project.basedir}/src/test/kotlin 72 | 73 | 74 | org.springframework.boot 75 | spring-boot-maven-plugin 76 | 77 | 78 | org.jetbrains.kotlin 79 | kotlin-maven-plugin 80 | 81 | 82 | -Xjsr305=strict 83 | 84 | 85 | spring 86 | jpa 87 | 88 | 89 | 90 | 91 | org.jetbrains.kotlin 92 | kotlin-maven-allopen 93 | ${kotlin.version} 94 | 95 | 96 | org.jetbrains.kotlin 97 | kotlin-maven-noarg 98 | ${kotlin.version} 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/kotlin/com/knf/dev/demo/kotlinspringthymeleafloginsignup/KotlinSpringThymeleafLoginSignupApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringthymeleafloginsignup 2 | 3 | import org.springframework.boot.SpringApplication 4 | import org.springframework.boot.autoconfigure.SpringBootApplication 5 | 6 | @SpringBootApplication 7 | class KotlinSpringThymeleafLoginSignupApplication { 8 | companion object { 9 | @JvmStatic 10 | fun main(args: Array) { 11 | SpringApplication.run(KotlinSpringThymeleafLoginSignupApplication::class.java, *args) 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/kotlin/com/knf/dev/demo/kotlinspringthymeleafloginsignup/config/SecurityConfiguration.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringthymeleafloginsignup.config 2 | 3 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity 4 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter 5 | import org.springframework.beans.factory.annotation.Autowired 6 | import com.knf.dev.demo.kotlinspringthymeleafloginsignup.service.UserService 7 | import org.springframework.context.annotation.Bean 8 | import org.springframework.context.annotation.Configuration 9 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder 10 | import org.springframework.security.authentication.dao.DaoAuthenticationProvider 11 | import kotlin.Throws 12 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder 13 | import org.springframework.security.config.annotation.web.builders.HttpSecurity 14 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher 15 | import java.lang.Exception 16 | 17 | @Configuration 18 | @EnableWebSecurity 19 | class SecurityConfiguration : WebSecurityConfigurerAdapter() { 20 | @Autowired 21 | private val userService: UserService? = null 22 | @Bean 23 | fun passwordEncoder(): BCryptPasswordEncoder { 24 | return BCryptPasswordEncoder() 25 | } 26 | 27 | @Bean 28 | fun authenticationProvider(): DaoAuthenticationProvider { 29 | val auth = DaoAuthenticationProvider() 30 | auth.setUserDetailsService(userService) 31 | auth.setPasswordEncoder(passwordEncoder()) 32 | return auth 33 | } 34 | 35 | @Throws(Exception::class) 36 | override fun configure(auth: AuthenticationManagerBuilder) { 37 | auth.authenticationProvider(authenticationProvider()) 38 | } 39 | 40 | @Throws(Exception::class) 41 | override fun configure(http: HttpSecurity) { 42 | http.authorizeRequests().antMatchers( 43 | "/registration**", "/js/**", 44 | "/css/**", "/img/**" 45 | ).permitAll().anyRequest() 46 | .authenticated().and().formLogin().loginPage("/login").permitAll().and().logout() 47 | .invalidateHttpSession(true).clearAuthentication(true) 48 | .logoutRequestMatcher(AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login?logout") 49 | .permitAll() 50 | } 51 | } -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/kotlin/com/knf/dev/demo/kotlinspringthymeleafloginsignup/controller/HomeController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringthymeleafloginsignup.controller 2 | 3 | import org.springframework.stereotype.Controller 4 | import org.springframework.web.bind.annotation.GetMapping 5 | 6 | @Controller 7 | class HomeController { 8 | @GetMapping("/login") 9 | fun login(): String { 10 | return "login" 11 | } 12 | 13 | @GetMapping("/") 14 | fun home(): String { 15 | return "index" 16 | } 17 | } -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/kotlin/com/knf/dev/demo/kotlinspringthymeleafloginsignup/controller/RegistrationController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringthymeleafloginsignup.controller 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping 4 | import com.knf.dev.demo.kotlinspringthymeleafloginsignup.service.UserService 5 | import org.springframework.web.bind.annotation.ModelAttribute 6 | import com.knf.dev.demo.kotlinspringthymeleafloginsignup.dto.UserRegistrationDto 7 | import org.springframework.stereotype.Controller 8 | import org.springframework.web.bind.annotation.GetMapping 9 | import org.springframework.web.bind.annotation.PostMapping 10 | 11 | @Controller 12 | @RequestMapping("/registration") 13 | class RegistrationController(private val userService: UserService) { 14 | @ModelAttribute("user") 15 | fun userRegistrationDto(): UserRegistrationDto { 16 | return UserRegistrationDto() 17 | } 18 | 19 | @GetMapping 20 | fun showRegistrationForm(): String { 21 | return "registration" 22 | } 23 | 24 | @PostMapping 25 | fun registerUserAccount(@ModelAttribute("user") registrationDto: UserRegistrationDto?): String { 26 | userService.save(registrationDto) 27 | return "redirect:/registration?success" 28 | } 29 | } -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/kotlin/com/knf/dev/demo/kotlinspringthymeleafloginsignup/dto/UserRegistrationDto.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringthymeleafloginsignup.dto 2 | 3 | class UserRegistrationDto { 4 | var firstName: String? = null 5 | var lastName: String? = null 6 | var email: String? = null 7 | var password: String? = null 8 | 9 | constructor() {} 10 | constructor( 11 | firstName: String?, 12 | lastName: String?, email: String?, password: String? 13 | ) : super() { 14 | this.firstName = firstName 15 | this.lastName = lastName 16 | this.email = email 17 | this.password = password 18 | } 19 | } -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/kotlin/com/knf/dev/demo/kotlinspringthymeleafloginsignup/model/Role.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringthymeleafloginsignup.model 2 | 3 | import javax.persistence.* 4 | 5 | @Entity 6 | @Table(name = "role") 7 | class Role { 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.IDENTITY) 10 | var id: Long? = null 11 | var name: String? = null 12 | 13 | constructor() {} 14 | constructor(name: String?) : super() { 15 | this.name = name 16 | } 17 | } -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/kotlin/com/knf/dev/demo/kotlinspringthymeleafloginsignup/model/User.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringthymeleafloginsignup.model 2 | 3 | import javax.persistence.* 4 | 5 | @Entity 6 | @Table(name = "user", uniqueConstraints = [UniqueConstraint(columnNames = ["email"])]) 7 | class User { 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.IDENTITY) 10 | var id: Long? = null 11 | 12 | @Column(name = "first_name") 13 | var firstName: String? = null 14 | 15 | @Column(name = "last_name") 16 | var lastName: String? = null 17 | var email: String? = null 18 | var password: String? = null 19 | 20 | @ManyToMany(fetch = FetchType.EAGER, cascade = [CascadeType.ALL]) 21 | @JoinTable( 22 | name = "users_roles", 23 | joinColumns = [JoinColumn(name = "user_id", referencedColumnName = "id")], 24 | inverseJoinColumns = [JoinColumn(name = "role_id", referencedColumnName = "id")] 25 | ) 26 | var roles: Collection? = null 27 | 28 | constructor() {} 29 | constructor( 30 | firstName: String?, lastName: String?, email: String?, 31 | password: String?, roles: Collection? 32 | ) : super() { 33 | this.firstName = firstName 34 | this.lastName = lastName 35 | this.email = email 36 | this.password = password 37 | this.roles = roles 38 | } 39 | } -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/kotlin/com/knf/dev/demo/kotlinspringthymeleafloginsignup/repository/UserRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringthymeleafloginsignup.repository 2 | 3 | import com.knf.dev.demo.kotlinspringthymeleafloginsignup.model.User 4 | import org.springframework.data.jpa.repository.JpaRepository 5 | import org.springframework.stereotype.Repository 6 | 7 | @Repository 8 | interface UserRepository : JpaRepository { 9 | fun findByEmail(email: String?): User? 10 | } -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/kotlin/com/knf/dev/demo/kotlinspringthymeleafloginsignup/service/UserService.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringthymeleafloginsignup.service 2 | 3 | import org.springframework.security.core.userdetails.UserDetailsService 4 | import com.knf.dev.demo.kotlinspringthymeleafloginsignup.dto.UserRegistrationDto 5 | import com.knf.dev.demo.kotlinspringthymeleafloginsignup.model.User 6 | 7 | interface UserService : UserDetailsService { 8 | fun save(registrationDto: UserRegistrationDto?): User? 9 | val all: List? 10 | } -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/kotlin/com/knf/dev/demo/kotlinspringthymeleafloginsignup/service/UserServiceImpl.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringthymeleafloginsignup.service 2 | 3 | import com.knf.dev.demo.kotlinspringthymeleafloginsignup.dto.UserRegistrationDto 4 | import com.knf.dev.demo.kotlinspringthymeleafloginsignup.model.Role 5 | import com.knf.dev.demo.kotlinspringthymeleafloginsignup.model.User 6 | import com.knf.dev.demo.kotlinspringthymeleafloginsignup.repository.UserRepository 7 | import org.springframework.beans.factory.annotation.Autowired 8 | import org.springframework.security.core.GrantedAuthority 9 | import org.springframework.security.core.authority.SimpleGrantedAuthority 10 | import org.springframework.security.core.userdetails.UserDetails 11 | import org.springframework.security.core.userdetails.UsernameNotFoundException 12 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder 13 | import org.springframework.stereotype.Service 14 | import java.util.* 15 | import java.util.function.Function 16 | import java.util.stream.Collectors 17 | 18 | 19 | @Service 20 | class UserServiceImpl(private val userRepository: UserRepository) : UserService { 21 | @Autowired 22 | private val passwordEncoder: BCryptPasswordEncoder? = null 23 | override fun save(registrationDto: UserRegistrationDto?): User? { 24 | val user = User( 25 | registrationDto!!.firstName, 26 | registrationDto.lastName, registrationDto.email, 27 | passwordEncoder!!.encode(registrationDto.password), 28 | Arrays.asList(Role("ROLE_USER")) 29 | ) 30 | return userRepository.save(user) 31 | } 32 | 33 | @Throws(UsernameNotFoundException::class) 34 | override fun loadUserByUsername(username: String): UserDetails { 35 | val user = userRepository.findByEmail(username) 36 | ?: throw UsernameNotFoundException("Invalid username or password.") 37 | return org.springframework.security.core.userdetails.User( 38 | user.email, user.password, 39 | mapRolesToAuthorities(user.roles!!) 40 | ) 41 | } 42 | 43 | private fun mapRolesToAuthorities(roles: Collection): Collection { 44 | return roles.stream().map(Function { role: Role -> 45 | SimpleGrantedAuthority( 46 | role.name 47 | ) 48 | }).collect(Collectors.toList()) 49 | } 50 | 51 | override val all: List? 52 | get() = userRepository.findAll() 53 | 54 | } -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | Spring Security Demo 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 | 42 | 43 |



44 |
45 |
46 | Success! Login Successful. 47 |
48 |
49 | 50 | 51 | -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Spring Security Demo 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 35 | 36 |






37 |
38 |
39 |
40 | 41 |

User Login Page

42 |
43 | 44 | 45 |
46 |
Invalid username or 47 | password.
48 |
49 | 50 | 51 |
52 |
53 | You have been logged out.
54 |
55 | 56 |
57 | : 58 | 61 |
62 | 63 |
64 | : 65 | 67 |
68 | 69 |
70 |
71 |
72 | 76 |
77 |
78 |
79 |
80 |
81 | New user? 82 | Register 83 | here 84 |
85 |
86 |
87 |
88 | 89 | -------------------------------------------------------------------------------- /kotlin-spring-thymeleaf-login-signup/src/main/resources/templates/registration.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Spring Security Demo 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 35 | 36 |






37 | 38 |
39 |
40 |
41 | 42 | 43 |
44 |
You've successfully registered 45 | to our awesome app!
46 |
47 | 48 |

Registration

49 | 50 |
52 |
53 | 55 | 58 |
59 | 60 |
61 | 65 |
66 | 67 |
68 | 72 |
73 | 74 |
75 | 80 |
81 | 82 |
83 | 85 | Already registered? Login 87 | here 88 |
89 |
90 |
91 |
92 |
93 | 94 | 95 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-downloadfile/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.5.4" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.5.21" 7 | kotlin("plugin.spring") version "1.5.21" 8 | } 9 | 10 | group = "com.knf.dev.demo" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | repositories { 15 | mavenCentral() 16 | } 17 | 18 | dependencies { 19 | implementation("org.springframework.boot:spring-boot-starter-webflux") 20 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 21 | implementation("io.projectreactor.kotlin:reactor-kotlin-extensions") 22 | implementation("org.jetbrains.kotlin:kotlin-reflect") 23 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 24 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") 25 | testImplementation("org.springframework.boot:spring-boot-starter-test") 26 | testImplementation("io.projectreactor:reactor-test") 27 | } 28 | 29 | tasks.withType { 30 | kotlinOptions { 31 | freeCompilerArgs = listOf("-Xjsr305=strict") 32 | jvmTarget = "11" 33 | } 34 | } 35 | 36 | tasks.withType { 37 | useJUnitPlatform() 38 | } 39 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-downloadfile/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowledgefactory4u/kotlin-springboot-app/65c876401a4cb91945ce6768d4d972b98a96c21d/kotlin-spring-webflux-downloadfile/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kotlin-spring-webflux-downloadfile/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-downloadfile/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kotlin-spring-webflux-downloadfile" 2 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-downloadfile/src/main/kotlin/com/knf/dev/demo/KotlinspringwebfluxdownloadfileApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinspringwebfluxdownloadfileApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-downloadfile/src/main/kotlin/com/knf/dev/demo/controller/DownloadFile.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.controller 2 | 3 | import org.springframework.web.bind.annotation.RestController 4 | import org.springframework.web.bind.annotation.GetMapping 5 | import kotlin.Throws 6 | import java.io.IOException 7 | import org.springframework.web.bind.annotation.PathVariable 8 | import reactor.core.publisher.Mono 9 | import java.lang.Void 10 | import org.springframework.http.ZeroCopyHttpOutputMessage 11 | import org.springframework.core.io.ClassPathResource 12 | import org.springframework.http.HttpHeaders 13 | import org.springframework.http.MediaType 14 | import org.springframework.http.server.reactive.ServerHttpResponse 15 | 16 | @RestController 17 | class DownloadFile { 18 | @GetMapping("/download/{fileName}") 19 | @Throws(IOException::class) 20 | fun downloadFile( 21 | @PathVariable fileName: String, 22 | response: ServerHttpResponse 23 | ): Mono { 24 | val zeroCopyResponse = response as ZeroCopyHttpOutputMessage 25 | response.getHeaders()[HttpHeaders.CONTENT_DISPOSITION] = 26 | "attachment; filename=$fileName" 27 | response.getHeaders().contentType = MediaType.APPLICATION_OCTET_STREAM 28 | val resource = ClassPathResource(fileName) 29 | val file = resource.file 30 | return zeroCopyResponse.writeWith( 31 | file, 0, 32 | file.length() 33 | ) 34 | } 35 | } -------------------------------------------------------------------------------- /kotlin-spring-webflux-downloadfile/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-downloadfile/src/main/resources/dummy.txt: -------------------------------------------------------------------------------- 1 | Dummy text......Dummy text......Dummy text...... -------------------------------------------------------------------------------- /kotlin-spring-webflux-downloadfile/src/test/kotlin/com/knf/dev/demo/KotlinspringwebfluxdownloadfileApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KotlinspringwebfluxdownloadfileApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-fileupload-download/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.5.4" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.5.21" 7 | kotlin("plugin.spring") version "1.5.21" 8 | } 9 | 10 | group = "com.knf.dev.demo" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | repositories { 15 | mavenCentral() 16 | } 17 | 18 | dependencies { 19 | implementation("org.springframework.boot:spring-boot-starter-webflux") 20 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 21 | implementation("io.projectreactor.kotlin:reactor-kotlin-extensions") 22 | implementation("org.jetbrains.kotlin:kotlin-reflect") 23 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 24 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") 25 | testImplementation("org.springframework.boot:spring-boot-starter-test") 26 | testImplementation("io.projectreactor:reactor-test") 27 | } 28 | 29 | tasks.withType { 30 | kotlinOptions { 31 | freeCompilerArgs = listOf("-Xjsr305=strict") 32 | jvmTarget = "11" 33 | } 34 | } 35 | 36 | tasks.withType { 37 | useJUnitPlatform() 38 | } 39 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-fileupload-download/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowledgefactory4u/kotlin-springboot-app/65c876401a4cb91945ce6768d4d972b98a96c21d/kotlin-spring-webflux-fileupload-download/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kotlin-spring-webflux-fileupload-download/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-fileupload-download/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kotlin-spring-webflux-fileupload-download" 2 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-fileupload-download/src/main/kotlin/com/knf/dev/demo/KotlinspringwebfluxfileuploaddownloadApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinspringwebfluxfileuploaddownloadApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-fileupload-download/src/main/kotlin/com/knf/dev/demo/controller/UploadDownloadController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.controller 2 | 3 | import org.springframework.web.bind.annotation.RestController 4 | import org.springframework.web.bind.annotation.RequestMapping 5 | import org.springframework.web.bind.annotation.PostMapping 6 | import org.springframework.web.bind.annotation.RequestPart 7 | import reactor.core.publisher.Mono 8 | import org.springframework.http.codec.multipart.FilePart 9 | import java.lang.Void 10 | import reactor.core.publisher.Flux 11 | import java.nio.file.Paths 12 | 13 | @RestController 14 | @RequestMapping("api/v1") 15 | class UploadDownloadController { 16 | private val basePath = Paths. 17 | get("./src/main/resources/files/") 18 | 19 | //single file upload 20 | @PostMapping("single/upload") 21 | fun uploadFile(@RequestPart("file") filePartMono: 22 | Mono): Mono { 23 | return filePartMono 24 | .doOnNext { fp: FilePart -> 25 | println("Received File : " + fp.filename()) } 26 | .flatMap { fp: FilePart -> fp. 27 | transferTo(basePath.resolve(fp.filename())) } 28 | .then() 29 | } 30 | 31 | //multiple file upload 32 | @PostMapping("multi/upload") 33 | fun uploadMultipleFiles(@RequestPart("files") partFlux: 34 | Flux): Mono { 35 | return partFlux 36 | .doOnNext { fp: FilePart -> 37 | println(fp.filename()) } 38 | .flatMap { fp: FilePart -> fp. 39 | transferTo(basePath.resolve(fp.filename())) } 40 | .then() 41 | } 42 | } -------------------------------------------------------------------------------- /kotlin-spring-webflux-fileupload-download/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-fileupload-download/src/main/resources/files/dummy.txt: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ### Reference Documentation 4 | For further reference, please consider the following sections: 5 | 6 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) 7 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.5.4/maven-plugin/reference/html/) 8 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.5.4/maven-plugin/reference/html/#build-image) 9 | 10 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-fileupload-download/src/main/resources/files/dummy1.txt: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ### Reference Documentation 4 | For further reference, please consider the following sections: 5 | 6 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) 7 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.5.4/maven-plugin/reference/html/) 8 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.5.4/maven-plugin/reference/html/#build-image) 9 | 10 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-fileupload-download/src/main/resources/files/dummy3.txt: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ### Reference Documentation 4 | For further reference, please consider the following sections: 5 | 6 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) 7 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.5.4/maven-plugin/reference/html/) 8 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.5.4/maven-plugin/reference/html/#build-image) 9 | 10 | -------------------------------------------------------------------------------- /kotlin-spring-webflux-fileupload-download/src/test/kotlin/com/knf/dev/demo/KotlinspringwebfluxfileuploaddownloadApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KotlinspringwebfluxfileuploaddownloadApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-spring-websocket-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.3.7.RELEASE 9 | 10 | 11 | com.knf.dev 12 | kotlin-spring-websocket-example 13 | 0.0.1-SNAPSHOT 14 | kotlin-spring-websocket-example 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 1.3.72 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-thymeleaf 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-websocket 34 | 35 | 36 | com.fasterxml.jackson.module 37 | jackson-module-kotlin 38 | 39 | 40 | org.jetbrains.kotlin 41 | kotlin-reflect 42 | 43 | 44 | org.jetbrains.kotlin 45 | kotlin-stdlib-jdk8 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-test 51 | test 52 | 53 | 54 | org.junit.vintage 55 | junit-vintage-engine 56 | 57 | 58 | 59 | 60 | com.vaadin.external.google 61 | android-json 62 | 0.0.20131108.vaadin1 63 | compile 64 | 65 | 66 | 67 | 68 | ${project.basedir}/src/main/kotlin 69 | ${project.basedir}/src/test/kotlin 70 | 71 | 72 | org.springframework.boot 73 | spring-boot-maven-plugin 74 | 75 | 76 | org.jetbrains.kotlin 77 | kotlin-maven-plugin 78 | 79 | 80 | -Xjsr305=strict 81 | 82 | 83 | spring 84 | 85 | 86 | 87 | 88 | org.jetbrains.kotlin 89 | kotlin-maven-allopen 90 | ${kotlin.version} 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /kotlin-spring-websocket-example/src/main/kotlin/com/knf/dev/KotlinSpringWebsocketExampleApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinSpringWebsocketExampleApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-websocket-example/src/main/kotlin/com/knf/dev/config/SocketConfig.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.config 2 | 3 | import com.knf.dev.handler.TextHandler 4 | import org.springframework.context.annotation.Configuration 5 | import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry 6 | import org.springframework.web.socket.config.annotation.WebSocketConfigurer 7 | import org.springframework.web.socket.config.annotation.EnableWebSocket 8 | 9 | @Configuration 10 | @EnableWebSocket 11 | class SocketConfig : WebSocketConfigurer { 12 | override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) { 13 | registry.addHandler(TextHandler(), "/getMessage") 14 | } 15 | } -------------------------------------------------------------------------------- /kotlin-spring-websocket-example/src/main/kotlin/com/knf/dev/handler/TextHandler.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.handler 2 | 3 | import org.springframework.web.socket.TextMessage 4 | import org.json.JSONException 5 | import org.json.JSONObject 6 | import org.springframework.stereotype.Component 7 | import java.io.IOException 8 | import org.springframework.web.socket.WebSocketSession 9 | import org.springframework.web.socket.handler.TextWebSocketHandler 10 | 11 | @Component 12 | class TextHandler : TextWebSocketHandler() { 13 | @Throws(InterruptedException::class, IOException::class, JSONException::class) 14 | public override fun handleTextMessage(session: WebSocketSession, message: TextMessage) { 15 | val payload = message.payload 16 | val jsonObject = JSONObject(payload) 17 | session.sendMessage(TextMessage("Your message:" + jsonObject.get("user"))) 18 | } 19 | } -------------------------------------------------------------------------------- /kotlin-spring-websocket-example/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-spring-websocket-example/src/main/resources/static/main.js: -------------------------------------------------------------------------------- 1 | var ws; 2 | function setConnected(connected) { 3 | $("#connect").prop("disabled", connected); 4 | $("#disconnect").prop("disabled", !connected); 5 | } 6 | 7 | function connect() { 8 | ws = new WebSocket('ws://localhost:8080/getMessage'); 9 | ws.onmessage = function(data) { 10 | helloWorld(data.data); 11 | } 12 | setConnected(true); 13 | } 14 | function disconnect() { 15 | if (ws != null) { 16 | ws.close(); 17 | } 18 | setConnected(false); 19 | console.log("Websocket is in disconnected state"); 20 | } 21 | function sendData() { 22 | var data = JSON.stringify({ 23 | 'user' : $("#user").val() 24 | }) 25 | ws.send(data); 26 | } 27 | 28 | function helloWorld(message) { 29 | $("#helloworldmessage").append("\n " + message + ""); 30 | } 31 | 32 | $(function() { 33 | $("form").on('submit', function(e) { 34 | e.preventDefault(); 35 | }); 36 | $("#connect").click(function() { 37 | connect(); 38 | }); 39 | $("#disconnect").click(function() { 40 | disconnect(); 41 | }); 42 | $("#send").click(function() { 43 | sendData(); 44 | }); 45 | }); -------------------------------------------------------------------------------- /kotlin-spring-websocket-example/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebSocket Chat Application 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |


15 |
16 |
17 |
18 |
19 |
20 | 22 | 24 | 25 |
26 |
27 |
28 |
29 |
30 |


31 |
32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 |
Welcome,Please enter your message
40 |
41 |
42 |
43 |
44 |
45 | 47 |
48 | 49 |
50 |
51 |
52 |

53 |
54 |
55 |
56 | 57 | 58 | 59 | 60 | 61 | 62 |
Your Message
63 |
64 |
65 |
66 |
67 |
68 | 70 |
71 |
72 |
73 |
74 |
75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /kotlin-spring-websocket-example/src/test/kotlin/com/knf/dev/KotlinSpringWebsocketExampleApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KotlinSpringWebsocketExampleApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-springboot-apachecommans-exportcsv/src/main/kotlin/com/knf/dev/KotlinSpringbootApachecommansExportcsvApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinSpringbootApachecommansExportcsvApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-springboot-apachecommans-exportcsv/src/main/kotlin/com/knf/dev/controller/EmployeeController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.controller 2 | 3 | import org.springframework.http.HttpHeaders 4 | 5 | import org.springframework.http.ResponseEntity 6 | 7 | import org.springframework.core.io.InputStreamResource 8 | 9 | import javax.servlet.http.HttpServletResponse 10 | 11 | import org.springframework.web.bind.annotation.GetMapping 12 | 13 | import com.knf.dev.service.EmployeeService 14 | 15 | import org.springframework.beans.factory.annotation.Autowired 16 | import org.springframework.http.MediaType 17 | import org.springframework.stereotype.Controller 18 | 19 | 20 | @Controller 21 | class EmployeeController { 22 | @Autowired 23 | var employeeService: EmployeeService? = null 24 | @GetMapping("/export-employees") 25 | @Throws(Exception::class) 26 | fun exportCSV(response: HttpServletResponse?): ResponseEntity { 27 | val filename = "employees.csv" 28 | val file = InputStreamResource(employeeService!!.load()) 29 | return ResponseEntity.ok().header( 30 | HttpHeaders.CONTENT_DISPOSITION, 31 | "attachment; filename=$filename" 32 | ) 33 | .contentType(MediaType.parseMediaType("application/csv")).body(file) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /kotlin-springboot-apachecommans-exportcsv/src/main/kotlin/com/knf/dev/entity/Employee.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.entity 2 | 3 | 4 | import javax.persistence.* 5 | 6 | 7 | @Entity 8 | @Table(name = "employee") 9 | class Employee { 10 | @Id 11 | @GeneratedValue(strategy = GenerationType.AUTO) 12 | var id: Long = 0 13 | var name: String? = null 14 | var email: String? = null 15 | var country: String? = null 16 | var age = 0 17 | var role: String? = null 18 | 19 | constructor() : super() {} 20 | constructor( 21 | name: String?, email: String?, country: String?, 22 | age: Int, role: String? 23 | ) : super() { 24 | this.name = name 25 | this.email = email 26 | this.country = country 27 | this.age = age 28 | this.role = role 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /kotlin-springboot-apachecommans-exportcsv/src/main/kotlin/com/knf/dev/helper/CSVHelper.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.helper 2 | 3 | import java.io.IOException 4 | 5 | import java.io.ByteArrayInputStream 6 | 7 | import com.knf.dev.entity.Employee 8 | 9 | import java.io.PrintWriter 10 | 11 | import org.apache.commons.csv.CSVPrinter 12 | 13 | import org.apache.commons.csv.CSVFormat 14 | import java.io.ByteArrayOutputStream 15 | import java.util.* 16 | 17 | 18 | object CSVHelper { 19 | fun employeesToCSV(employees: List): ByteArrayInputStream { 20 | val format = CSVFormat.DEFAULT.withHeader("ID", "Name", "Email", "Age", "Country", "Role") 21 | try { 22 | ByteArrayOutputStream().use({ out -> 23 | CSVPrinter( 24 | PrintWriter(out), 25 | format 26 | ).use { csvPrinter -> 27 | for (emp in employees) { 28 | val data: List = Arrays.asList( 29 | emp.id.toString(), 30 | emp.name, emp.email, 31 | java.lang.String.valueOf(emp.age), emp.country, 32 | emp.role 33 | ) 34 | csvPrinter.printRecord(data) 35 | } 36 | csvPrinter.flush() 37 | return ByteArrayInputStream(out.toByteArray()) 38 | } 39 | }) 40 | } catch (e: IOException) { 41 | throw RuntimeException( 42 | "fail to import data to CSV file: " 43 | + e.message 44 | ) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /kotlin-springboot-apachecommans-exportcsv/src/main/kotlin/com/knf/dev/repository/EmployeeRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.repository 2 | 3 | import com.knf.dev.entity.Employee 4 | import org.springframework.data.jpa.repository.JpaRepository 5 | import org.springframework.stereotype.Repository 6 | 7 | @Repository 8 | interface EmployeeRepository : JpaRepository -------------------------------------------------------------------------------- /kotlin-springboot-apachecommans-exportcsv/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-springboot-export-csv-demo/src/main/kotlin/com/knf/dev/KotlinSpringbootExportCsvDemoApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinSpringbH2DBThymeleafApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-springboot-export-csv-demo/src/main/kotlin/com/knf/dev/entity/Employee.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.entity 2 | 3 | import javax.persistence.* 4 | 5 | 6 | @Entity 7 | @Table(name = "employee") 8 | class Employee { 9 | @Id 10 | @GeneratedValue(strategy = GenerationType.AUTO) 11 | var id: Long = 0 12 | var name: String? = null 13 | var email: String? = null 14 | var country: String? = null 15 | var age = 0 16 | var role: String? = null 17 | 18 | constructor() : super() {} 19 | constructor( 20 | name: String?, email: String?, country: String?, 21 | age: Int, role: String? 22 | ) : super() { 23 | this.name = name 24 | this.email = email 25 | this.country = country 26 | this.age = age 27 | this.role = role 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /kotlin-springboot-export-csv-demo/src/main/kotlin/com/knf/dev/repository/EmployeeRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.repository 2 | 3 | 4 | import com.knf.dev.entity.Employee 5 | import org.springframework.data.jpa.repository.JpaRepository 6 | import org.springframework.stereotype.Repository 7 | 8 | @Repository 9 | interface EmployeeRepository : JpaRepository -------------------------------------------------------------------------------- /kotlin-springboot-export-csv-demo/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.h2.console.enabled=true 2 | spring.h2.console.path=/h2_console 3 | spring.datasource.url=jdbc:h2:file:~/h2/knf-demo 4 | spring.datasource.username=sa 5 | spring.datasource.password= 6 | spring.datasource.driverClassName=org.h2.Driver 7 | spring.jpa.hibernate.ddl-auto = update 8 | spring.jpa.show-sql=true -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.5.4" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.5.21" 7 | kotlin("plugin.spring") version "1.5.21" 8 | } 9 | 10 | group = "com.knf.dev.demo" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | repositories { 15 | mavenCentral() 16 | } 17 | 18 | dependencies { 19 | implementation("org.springframework.boot:spring-boot-starter-web") 20 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 21 | implementation("org.jetbrains.kotlin:kotlin-reflect") 22 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 23 | implementation("org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0") 24 | runtimeOnly("com.h2database:h2") 25 | testImplementation("org.springframework.boot:spring-boot-starter-test") 26 | } 27 | 28 | tasks.withType { 29 | kotlinOptions { 30 | freeCompilerArgs = listOf("-Xjsr305=strict") 31 | jvmTarget = "11" 32 | } 33 | } 34 | 35 | tasks.withType { 36 | useJUnitPlatform() 37 | } 38 | -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowledgefactory4u/kotlin-springboot-app/65c876401a4cb91945ce6768d4d972b98a96c21d/kotlin-springboot-mybatis-crud-example/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/src/main/kotlin/com/knf/dev/demo/KotlinSpringbootMybatisCrudExampleApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinSpringbootMybatisCrudExampleApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/src/main/kotlin/com/knf/dev/demo/controller/UserController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.controller 2 | 3 | import org.springframework.web.bind.annotation.RestController 4 | import org.springframework.web.bind.annotation.RequestMapping 5 | import org.springframework.beans.factory.annotation.Autowired 6 | import com.knf.dev.demo.repository.UserRepository 7 | import org.springframework.web.bind.annotation.GetMapping 8 | import org.springframework.web.bind.annotation.PostMapping 9 | import org.springframework.web.bind.annotation.RequestBody 10 | import com.knf.dev.demo.exception.UserIdAlreadyExistException 11 | import org.springframework.web.bind.annotation.PathVariable 12 | import org.springframework.http.ResponseEntity 13 | import com.knf.dev.demo.exception.UserIdNotFoundException 14 | import com.knf.dev.demo.model.User 15 | import org.springframework.web.bind.annotation.PutMapping 16 | import org.springframework.web.bind.annotation.DeleteMapping 17 | import java.util.HashMap 18 | 19 | @RestController 20 | @RequestMapping("/api/v1") 21 | class UserController { 22 | @Autowired 23 | private val userRepository: UserRepository? = null 24 | 25 | // get all users 26 | @get:GetMapping("/users") 27 | val allUsers: List? 28 | get() = userRepository!!.findAll() 29 | 30 | // create user rest API 31 | @PostMapping("/users") 32 | fun createUser(@RequestBody user: User): User? { 33 | return if (userRepository!!.findById(user.id) == null) { 34 | val id = userRepository.insert(user) 35 | userRepository.findById(user.id) 36 | } else { 37 | throw UserIdAlreadyExistException() 38 | } 39 | } 40 | 41 | // get user by id rest api 42 | @GetMapping("/users/{id}") 43 | fun getUserById(@PathVariable id: Long?): ResponseEntity { 44 | val user = userRepository!!.findById(id!!) ?: throw UserIdNotFoundException() 45 | return ResponseEntity.ok(user) 46 | } 47 | 48 | // update user rest api 49 | @PutMapping("/users/{id}") 50 | fun updateUser( 51 | @PathVariable id: Long?, 52 | @RequestBody userDetails: User 53 | ): ResponseEntity { 54 | if (userRepository!!.update( 55 | User( 56 | id!!, userDetails.firstName, 57 | userDetails.lastName, userDetails.emailId 58 | ) 59 | ) == 0 60 | ) { 61 | throw UserIdNotFoundException() 62 | } 63 | return ResponseEntity.ok(userRepository.findById(id)) 64 | } 65 | 66 | // delete user rest api 67 | @DeleteMapping("/users/{id}") 68 | fun deleteUser(@PathVariable id: Long?): ResponseEntity> { 69 | userRepository!!.deleteById(id!!) 70 | val response: MutableMap = HashMap() 71 | response["deleted"] = java.lang.Boolean.TRUE 72 | return ResponseEntity.ok(response) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/src/main/kotlin/com/knf/dev/demo/exception/CustomErrorResponse.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.exception 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat 4 | import java.time.LocalDateTime 5 | 6 | class CustomErrorResponse { 7 | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss") 8 | var timestamp: LocalDateTime? = null 9 | var status = 0 10 | var error: String? = null 11 | } -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/src/main/kotlin/com/knf/dev/demo/exception/GlobalExceptionHandler.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.exception 2 | 3 | import org.springframework.web.bind.annotation.ControllerAdvice 4 | import com.knf.dev.demo.exception.UserIdNotFoundException 5 | import org.springframework.web.context.request.WebRequest 6 | import org.springframework.http.ResponseEntity 7 | import java.time.LocalDateTime 8 | import org.springframework.http.HttpStatus 9 | import com.knf.dev.demo.exception.UserIdAlreadyExistException 10 | import org.springframework.web.bind.annotation.ExceptionHandler 11 | import java.lang.Exception 12 | 13 | @ControllerAdvice 14 | class GlobalExceptionHandler { 15 | @ExceptionHandler(UserIdNotFoundException::class) 16 | fun globalExceptionHandler(ex: Exception, request: WebRequest?): 17 | ResponseEntity { 18 | val errors = CustomErrorResponse() 19 | errors.timestamp = LocalDateTime.now() 20 | errors.error = ex.message 21 | errors.status = HttpStatus.NOT_FOUND.value() 22 | return ResponseEntity(errors, HttpStatus.NOT_FOUND) 23 | } 24 | 25 | @ExceptionHandler(UserIdAlreadyExistException::class) 26 | fun globalExceptionHandler2(ex: Exception, request: WebRequest?): 27 | ResponseEntity { 28 | val errors = CustomErrorResponse() 29 | errors.timestamp = LocalDateTime.now() 30 | errors.error = ex.message 31 | errors.status = HttpStatus.INTERNAL_SERVER_ERROR.value() 32 | return ResponseEntity(errors, 33 | HttpStatus.INTERNAL_SERVER_ERROR) 34 | } 35 | } -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/src/main/kotlin/com/knf/dev/demo/exception/UserIdAlreadyExistException.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.exception 2 | 3 | import java.lang.RuntimeException 4 | 5 | class UserIdAlreadyExistException : RuntimeException("User Id Already Exist") -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/src/main/kotlin/com/knf/dev/demo/exception/UserIdNotFoundException.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.exception 2 | 3 | import java.lang.RuntimeException 4 | 5 | class UserIdNotFoundException : RuntimeException("User Id Not Found") -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/src/main/kotlin/com/knf/dev/demo/model/User.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.model 2 | 3 | class User { 4 | var id: Long = 0 5 | var firstName: String? = null 6 | var lastName: String? = null 7 | var emailId: String? = null 8 | 9 | constructor() {} 10 | constructor(id: Long, firstName: String?, lastName: String?, emailId: String?) : super() { 11 | this.id = id 12 | this.firstName = firstName 13 | this.lastName = lastName 14 | this.emailId = emailId 15 | } 16 | } -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/src/main/kotlin/com/knf/dev/demo/repository/UserRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.repository 2 | 3 | import com.knf.dev.demo.model.User 4 | import org.apache.ibatis.annotations.* 5 | 6 | @Mapper 7 | interface UserRepository { 8 | @Select("select * from users") 9 | fun findAll(): List? 10 | 11 | @Select("SELECT * FROM users WHERE id = #{id}") 12 | fun findById(id: Long): User? 13 | 14 | @Delete("DELETE FROM users WHERE id = #{id}") 15 | fun deleteById(id: Long): Int 16 | 17 | @Insert( 18 | "INSERT INTO users(id, firstName, lastName,emailId) " + 19 | " VALUES (#{id}, #{firstName}, #{lastName}, #{emailId})" 20 | ) 21 | fun insert(user: User?): Int 22 | 23 | @Update( 24 | "Update users set firstName=#{firstName}, " + 25 | " lastName=#{lastName}, emailId=#{emailId} where id=#{id}" 26 | ) 27 | fun update(user: User?): Int 28 | } -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | create table users 2 | ( 3 | id integer not null, 4 | firstName varchar(255) not null, 5 | lastName varchar(255) not null, 6 | emailId varchar(255) not null, 7 | primary key(id) 8 | ); -------------------------------------------------------------------------------- /kotlin-springboot-mybatis-crud-example/src/test/kotlin/com/knf/dev/demo/KotlinSpringbootMybatisCrudExampleApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KotlinSpringbootMybatisCrudExampleApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | org.springframework.boot 9 | spring-boot-starter-parent 10 | 2.5.5 11 | 12 | 13 | com.knf.dev.demo 14 | kotlin-springsecurity-jwt 15 | 0.0.1-SNAPSHOT 16 | kotlin-springsecurity-jwt 17 | Demo project for Spring Boot 18 | 19 | 11 20 | 1.5.31 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-data-mongodb 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-security 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | com.fasterxml.jackson.module 37 | jackson-module-kotlin 38 | 39 | 40 | org.jetbrains.kotlin 41 | kotlin-reflect 42 | 43 | 44 | org.jetbrains.kotlin 45 | kotlin-stdlib-jdk8 46 | 47 | 48 | io.jsonwebtoken 49 | jjwt 50 | 0.9.1 51 | 52 | 53 | 54 | javax.xml.bind 55 | jaxb-api 56 | 2.1 57 | 58 | 59 | org.springframework.boot 60 | spring-boot-starter-validation 61 | 62 | 63 | org.springframework.boot 64 | spring-boot-starter-test 65 | test 66 | 67 | 68 | org.springframework.security 69 | spring-security-test 70 | test 71 | 72 | 73 | 74 | 75 | ${project.basedir}/src/main/kotlin 76 | 77 | 78 | org.springframework.boot 79 | spring-boot-maven-plugin 80 | 81 | 82 | org.jetbrains.kotlin 83 | kotlin-maven-plugin 84 | 85 | 86 | -Xjsr305=strict 87 | 88 | 89 | spring 90 | 91 | 92 | 93 | 94 | org.jetbrains.kotlin 95 | kotlin-maven-allopen 96 | ${kotlin.version} 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/KotlinSpringsecurityJwtApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt 2 | 3 | import com.knf.dev.demo.kotlinspringsecurityjwt.model.ERole 4 | import com.knf.dev.demo.kotlinspringsecurityjwt.model.Role 5 | import com.knf.dev.demo.kotlinspringsecurityjwt.repository.RoleRepository 6 | import org.springframework.beans.factory.annotation.Autowired 7 | import org.springframework.boot.CommandLineRunner 8 | import org.springframework.boot.SpringApplication 9 | import org.springframework.boot.autoconfigure.SpringBootApplication 10 | 11 | 12 | @SpringBootApplication 13 | class KotlinSpringsecurityJwtApplication : CommandLineRunner { 14 | @Autowired 15 | var roleRepository: RoleRepository? = null 16 | 17 | //Add some rows into roles collection before 18 | // assigning any role to Employee. 19 | @Throws(Exception::class) 20 | override fun run(vararg args: String) { 21 | try { 22 | val role = Role() 23 | role.name=ERole.ROLE_EMPLOYEE 24 | roleRepository!!.save(role) 25 | val role2 = Role() 26 | role2.name=ERole.ROLE_ADMIN 27 | roleRepository!!.save(role2) 28 | } catch (e: Exception) { 29 | } 30 | } 31 | 32 | companion object { 33 | @JvmStatic 34 | fun main(args: Array) { 35 | SpringApplication.run(KotlinSpringsecurityJwtApplication::class.java, *args) 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/controller/EmployeeController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.controller 2 | 3 | import org.springframework.web.bind.annotation.CrossOrigin 4 | import org.springframework.web.bind.annotation.RestController 5 | import org.springframework.web.bind.annotation.RequestMapping 6 | import org.springframework.web.bind.annotation.GetMapping 7 | import com.knf.dev.demo.kotlinspringsecurityjwt.response.MessageResponse 8 | import org.springframework.security.access.prepost.PreAuthorize 9 | 10 | @CrossOrigin(origins = ["*"], maxAge = 4800) 11 | @RestController 12 | @RequestMapping("/api/test") 13 | class EmployeeController { 14 | @GetMapping("/all") 15 | fun allAccess(): MessageResponse { 16 | return MessageResponse("Public ") 17 | } 18 | 19 | @GetMapping("/employee") 20 | @PreAuthorize("hasRole('EMPLOYEE') ") 21 | fun employeeAccess(): MessageResponse { 22 | return MessageResponse("Employee zone") 23 | } 24 | 25 | @GetMapping("/admin") 26 | @PreAuthorize("hasRole('ADMIN')") 27 | fun adminAccess(): MessageResponse { 28 | return MessageResponse("Admin zone") 29 | } 30 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/model/ERole.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.model 2 | 3 | enum class ERole { 4 | ROLE_EMPLOYEE, ROLE_ADMIN 5 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/model/Employee.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.model 2 | 3 | import org.springframework.data.annotation.Id 4 | import org.springframework.data.mongodb.core.mapping.DBRef 5 | import org.springframework.data.mongodb.core.mapping.Document 6 | import java.util.HashSet 7 | import javax.validation.constraints.Email 8 | import javax.validation.constraints.NotBlank 9 | import javax.validation.constraints.Size 10 | 11 | @Document(collection = "employees") 12 | class Employee { 13 | @Id 14 | var id: String? = null 15 | var employeename: @NotBlank @Size(max = 20) String? = null 16 | var email: @NotBlank @Size(max = 50) @Email String? = null 17 | var password: @NotBlank @Size(max = 120) String? = null 18 | 19 | @DBRef 20 | var roles: Set = HashSet() 21 | 22 | constructor() {} 23 | constructor(employeename: String?, email: String?, password: String?) : super() { 24 | this.employeename = employeename 25 | this.email = email 26 | this.password = password 27 | } 28 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/model/Role.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.model 2 | 3 | import org.springframework.data.annotation.Id 4 | import org.springframework.data.mongodb.core.index.Indexed 5 | import org.springframework.data.mongodb.core.mapping.Document 6 | 7 | @Document(collection = "roles") 8 | class Role { 9 | @Id 10 | var id: String? = null 11 | 12 | @Indexed(unique = true) 13 | var name: ERole? = null 14 | 15 | constructor() {} 16 | constructor(name: ERole?) { 17 | this.name = name 18 | } 19 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/repository/EmployeeRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.repository 2 | 3 | import com.knf.dev.demo.kotlinspringsecurityjwt.model.Employee 4 | import org.springframework.data.mongodb.repository.MongoRepository 5 | import java.util.* 6 | 7 | 8 | interface EmployeeRepository : MongoRepository { 9 | fun findByEmployeename(employeename: String?): Optional? 10 | fun existsByEmployeename(employeename: String?): Boolean? 11 | fun existsByEmail(email: String?): Boolean? 12 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/repository/RoleRepository.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.repository 2 | 3 | import org.springframework.data.mongodb.repository.MongoRepository 4 | import com.knf.dev.demo.kotlinspringsecurityjwt.model.ERole 5 | import com.knf.dev.demo.kotlinspringsecurityjwt.model.Role 6 | import java.util.* 7 | 8 | interface RoleRepository : MongoRepository { 9 | fun findByName(name: ERole?): Optional? 10 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/request/LoginRequest.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.request 2 | 3 | import javax.validation.constraints.NotBlank 4 | 5 | class LoginRequest { 6 | var employeename: @NotBlank String? = null 7 | var password: @NotBlank String? = null 8 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/request/SignupRequest.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.request 2 | 3 | import javax.validation.constraints.Email 4 | import javax.validation.constraints.NotBlank 5 | import javax.validation.constraints.Size 6 | 7 | class SignupRequest { 8 | var employeename: @NotBlank @Size(min = 3, max = 20) String? = null 9 | var email: @NotBlank @Size(max = 50) @Email String? = null 10 | var roles: Set? = null 11 | private set 12 | var password: @NotBlank @Size(min = 6, max = 40) String? = null 13 | fun setRole(roles: Set?) { 14 | this.roles = roles 15 | } 16 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/response/JwtResponse.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.response 2 | 3 | class JwtResponse( 4 | var accessToken: String, var id: String, 5 | var employeename: String, var email: String, val roles: List 6 | ) { 7 | var tokenType = "Bearer" 8 | 9 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/response/MessageResponse.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.response 2 | 3 | class MessageResponse(var message: String) -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/security/WebSecurityConfig.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.security 2 | 3 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity 4 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity 5 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter 6 | import org.springframework.beans.factory.annotation.Autowired 7 | import com.knf.dev.demo.kotlinspringsecurityjwt.security.jwt.AuthEntryPointJwt 8 | import com.knf.dev.demo.kotlinspringsecurityjwt.security.services.EmployeeDetailsServiceImpl 9 | import kotlin.Throws 10 | import org.springframework.security.config.annotation.web.builders.HttpSecurity 11 | import org.springframework.security.config.http.SessionCreationPolicy 12 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter 13 | import org.springframework.security.crypto.password.PasswordEncoder 14 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder 15 | import com.knf.dev.demo.kotlinspringsecurityjwt.security.jwt.AuthTokenFilter 16 | import org.springframework.context.annotation.Bean 17 | import org.springframework.context.annotation.Configuration 18 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder 19 | import org.springframework.security.authentication.AuthenticationManager 20 | import java.lang.Exception 21 | 22 | @Configuration 23 | @EnableWebSecurity 24 | @EnableGlobalMethodSecurity(prePostEnabled = true) 25 | class WebSecurityConfig : WebSecurityConfigurerAdapter() { 26 | @Autowired 27 | private val unauthorizedHandler: AuthEntryPointJwt? = null 28 | 29 | @Autowired 30 | var employeeDetailsService: EmployeeDetailsServiceImpl? = null 31 | @Throws(Exception::class) 32 | override fun configure(http: HttpSecurity) { 33 | http.cors().and().csrf().disable().exceptionHandling(). 34 | authenticationEntryPoint(unauthorizedHandler).and() 35 | .sessionManagement(). 36 | sessionCreationPolicy(SessionCreationPolicy.STATELESS). 37 | and().authorizeRequests() 38 | .antMatchers("/api/auth/**").permitAll(). 39 | antMatchers("/api/test/**").permitAll().anyRequest() 40 | .authenticated() 41 | http.addFilterBefore( 42 | authenticationJwtTokenFilter(), 43 | UsernamePasswordAuthenticationFilter::class.java 44 | ) 45 | } 46 | 47 | @Bean 48 | fun passwordEncoder(): PasswordEncoder { 49 | return BCryptPasswordEncoder() 50 | } 51 | 52 | @Bean 53 | fun authenticationJwtTokenFilter(): AuthTokenFilter { 54 | return AuthTokenFilter() 55 | } 56 | 57 | @Throws(Exception::class) 58 | public override fun configure 59 | (authenticationManagerBuilder: AuthenticationManagerBuilder) { 60 | authenticationManagerBuilder.userDetailsService(employeeDetailsService). 61 | passwordEncoder(passwordEncoder()) 62 | } 63 | 64 | @Bean 65 | @Throws(Exception::class) 66 | override fun authenticationManagerBean(): AuthenticationManager { 67 | return super.authenticationManagerBean() 68 | } 69 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/security/jwt/AuthEntryPointJwt.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.security.jwt 2 | 3 | import org.springframework.security.web.AuthenticationEntryPoint 4 | import kotlin.Throws 5 | import java.io.IOException 6 | import javax.servlet.ServletException 7 | import javax.servlet.http.HttpServletRequest 8 | import javax.servlet.http.HttpServletResponse 9 | import com.knf.dev.demo.kotlinspringsecurityjwt.security.jwt.AuthEntryPointJwt 10 | import org.slf4j.LoggerFactory 11 | import org.springframework.security.core.AuthenticationException 12 | import org.springframework.stereotype.Component 13 | 14 | @Component 15 | class AuthEntryPointJwt : AuthenticationEntryPoint { 16 | @Throws(IOException::class, ServletException::class) 17 | override fun commence( 18 | request: HttpServletRequest, response: HttpServletResponse, 19 | authException: AuthenticationException 20 | ) { 21 | logger.error("Unauthorized error: {}", authException.message) 22 | response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error: Unauthorized") 23 | } 24 | 25 | companion object { 26 | private val logger = LoggerFactory.getLogger(AuthEntryPointJwt::class.java) 27 | } 28 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/security/jwt/AuthTokenFilter.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.security.jwt 2 | 3 | import org.springframework.web.filter.OncePerRequestFilter 4 | import org.springframework.beans.factory.annotation.Autowired 5 | import com.knf.dev.demo.kotlinspringsecurityjwt.security.services.EmployeeDetailsServiceImpl 6 | import kotlin.Throws 7 | import javax.servlet.ServletException 8 | import java.io.IOException 9 | import javax.servlet.http.HttpServletRequest 10 | import javax.servlet.http.HttpServletResponse 11 | import javax.servlet.FilterChain 12 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken 13 | import org.springframework.security.web.authentication.WebAuthenticationDetailsSource 14 | import org.springframework.security.core.context.SecurityContextHolder 15 | import org.slf4j.LoggerFactory 16 | import org.springframework.util.StringUtils 17 | import java.lang.Exception 18 | 19 | class AuthTokenFilter : OncePerRequestFilter() { 20 | @Autowired 21 | private val jwtUtils: JwtUtils? = null 22 | 23 | @Autowired 24 | private val employeeDetailsService: EmployeeDetailsServiceImpl? = null 25 | @Throws(ServletException::class, IOException::class) 26 | override fun doFilterInternal( 27 | request: HttpServletRequest, 28 | response: HttpServletResponse, filterChain: FilterChain 29 | ) { 30 | try { 31 | val jwt = parseJwt(request) 32 | if (jwt != null && jwtUtils!!.validateJwtToken(jwt)) { 33 | val employeename = jwtUtils.getEmployeeNameFromJwtToken(jwt) 34 | val employeeDetails = employeeDetailsService!!.loadUserByUsername(employeename) 35 | val authentication = UsernamePasswordAuthenticationToken( 36 | employeeDetails, null, employeeDetails.authorities 37 | ) 38 | authentication.details = WebAuthenticationDetailsSource().buildDetails(request) 39 | SecurityContextHolder.getContext().authentication = authentication 40 | } 41 | } catch (e: Exception) { 42 | Companion.logger.error("Cannot set employee authentication: {}", e) 43 | } 44 | filterChain.doFilter(request, response) 45 | } 46 | 47 | private fun parseJwt(request: HttpServletRequest): String? { 48 | val headerAuth = request.getHeader("Authorization") 49 | return if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer")) { 50 | headerAuth.substring(7, headerAuth.length) 51 | } else null 52 | } 53 | 54 | companion object { 55 | private val logger = LoggerFactory.getLogger(AuthTokenFilter::class.java) 56 | } 57 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/security/jwt/JwtUtils.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.security.jwt 2 | 3 | import java.lang.IllegalArgumentException 4 | import com.knf.dev.demo.kotlinspringsecurityjwt.security.services.EmployeeDetailsImpl 5 | import io.jsonwebtoken.* 6 | import org.slf4j.LoggerFactory 7 | import org.springframework.beans.factory.annotation.Value 8 | import org.springframework.security.core.Authentication 9 | import org.springframework.stereotype.Component 10 | import java.util.* 11 | 12 | @Component 13 | class JwtUtils { 14 | @Value("\${knf.app.jwtExpirationMs}") 15 | private val jwtExpirationMs = 0 16 | 17 | @Value("\${knf.app.jwtSecret}") 18 | private val jwtSecret: String? = null 19 | fun validateJwtToken(authToken: String?): Boolean { 20 | try { 21 | Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken) 22 | return true 23 | } catch (e: SignatureException) { 24 | logger.error("Invalid JWT signature: {}", e.message) 25 | } catch (e: MalformedJwtException) { 26 | logger.error("Invalid JWT token: {}", e.message) 27 | } catch (e: ExpiredJwtException) { 28 | logger.error("JWT token is expired: {}", e.message) 29 | } catch (e: UnsupportedJwtException) { 30 | logger.error("JWT token is unsupported: {}", e.message) 31 | } catch (e: IllegalArgumentException) { 32 | logger.error("JWT claims string is empty: {}", e.message) 33 | } 34 | return false 35 | } 36 | 37 | fun generateJwtToken(authentication: Authentication): String { 38 | val employeePrincipal = authentication.principal as EmployeeDetailsImpl 39 | return Jwts.builder().setSubject(employeePrincipal.username).setIssuedAt(Date()) 40 | .setExpiration( 41 | Date( 42 | Date().time + 43 | jwtExpirationMs 44 | ) 45 | ) 46 | .signWith(SignatureAlgorithm.HS512, jwtSecret).compact() 47 | } 48 | 49 | fun getEmployeeNameFromJwtToken(token: String?): String { 50 | return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).body.subject 51 | } 52 | 53 | companion object { 54 | private val logger = LoggerFactory.getLogger(JwtUtils::class.java) 55 | } 56 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/security/services/EmployeeDetailsImpl.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.security.services 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore 4 | import org.springframework.security.core.GrantedAuthority 5 | import org.springframework.security.core.userdetails.UserDetails 6 | import com.knf.dev.demo.kotlinspringsecurityjwt.model.Employee 7 | import com.knf.dev.demo.kotlinspringsecurityjwt.model.Role 8 | import org.springframework.security.core.authority.SimpleGrantedAuthority 9 | import java.util.stream.Collectors 10 | 11 | class EmployeeDetailsImpl( 12 | val id: String?, private val username: String, val email: String?, 13 | @field:JsonIgnore private val password: String, 14 | private val authorities: Collection 15 | ) : UserDetails { 16 | 17 | override fun getAuthorities(): Collection { 18 | return authorities 19 | } 20 | 21 | override fun getPassword(): String { 22 | return password 23 | } 24 | 25 | override fun getUsername(): String { 26 | return username 27 | } 28 | 29 | override fun isAccountNonExpired(): Boolean { 30 | return true 31 | } 32 | 33 | override fun isAccountNonLocked(): Boolean { 34 | return true 35 | } 36 | 37 | override fun isCredentialsNonExpired(): Boolean { 38 | return true 39 | } 40 | 41 | override fun isEnabled(): Boolean { 42 | return true 43 | } 44 | 45 | override fun equals(o: Any?): Boolean { 46 | if (this === o) return true 47 | if (o == null || javaClass != o.javaClass) return false 48 | val user = o as EmployeeDetailsImpl 49 | return id == user.id 50 | } 51 | 52 | companion object { 53 | private const val serialVersionUID = 1L 54 | fun build(user: Employee): EmployeeDetailsImpl { 55 | val authorities = user.roles.stream() 56 | .map { role: Role -> 57 | SimpleGrantedAuthority( 58 | role.name!!.name 59 | ) 60 | }.collect(Collectors.toList()) 61 | return EmployeeDetailsImpl( 62 | user.id, user.employeename!!, 63 | user.email, user.password!!, 64 | authorities 65 | ) 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/kotlin/com/knf/dev/demo/kotlinspringsecurityjwt/security/services/EmployeeDetailsServiceImpl.kt: -------------------------------------------------------------------------------- 1 | package com.knf.dev.demo.kotlinspringsecurityjwt.security.services 2 | 3 | import com.knf.dev.demo.kotlinspringsecurityjwt.model.Employee 4 | import org.springframework.security.core.userdetails.UserDetailsService 5 | import org.springframework.beans.factory.annotation.Autowired 6 | import org.springframework.transaction.annotation.Transactional 7 | import kotlin.Throws 8 | import org.springframework.security.core.userdetails.UsernameNotFoundException 9 | import org.springframework.security.core.userdetails.UserDetails 10 | import org.springframework.stereotype.Service 11 | import com.knf.dev.demo.kotlinspringsecurityjwt.repository.EmployeeRepository 12 | 13 | @Service 14 | class EmployeeDetailsServiceImpl : UserDetailsService { 15 | @Autowired 16 | var employeeRepository: EmployeeRepository? = null 17 | @Transactional 18 | @Throws(UsernameNotFoundException::class) 19 | override fun loadUserByUsername(employeename: String): UserDetails { 20 | val employee: Employee = employeeRepository!!.findByEmployeename(employeename) 21 | ?.orElseThrow { UsernameNotFoundException("Employee Not Found with username: " + 22 | "$employeename") }!! 23 | return EmployeeDetailsImpl.build(employee) 24 | } 25 | } -------------------------------------------------------------------------------- /kotlin-springsecurity-jwt/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | knf: 2 | app: 3 | jwtExpirationMs: 76300000 4 | jwtSecret: knowledgeFactory 5 | spring: 6 | data: 7 | mongodb: 8 | database: demo_db 9 | host: localhost 10 | port: 27017 -------------------------------------------------------------------------------- /spring-kotlin-webflux-videostreaming/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.5.4" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.5.21" 7 | kotlin("plugin.spring") version "1.5.21" 8 | } 9 | 10 | group = "com.knf" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_11 13 | 14 | repositories { 15 | mavenCentral() 16 | } 17 | 18 | dependencies { 19 | implementation("org.springframework.boot:spring-boot-starter-webflux") 20 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 21 | implementation("io.projectreactor.kotlin:reactor-kotlin-extensions") 22 | implementation("org.jetbrains.kotlin:kotlin-reflect") 23 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 24 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") 25 | testImplementation("org.springframework.boot:spring-boot-starter-test") 26 | testImplementation("io.projectreactor:reactor-test") 27 | } 28 | 29 | tasks.withType { 30 | kotlinOptions { 31 | freeCompilerArgs = listOf("-Xjsr305=strict") 32 | jvmTarget = "11" 33 | } 34 | } 35 | 36 | tasks.withType { 37 | useJUnitPlatform() 38 | } 39 | -------------------------------------------------------------------------------- /spring-kotlin-webflux-videostreaming/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "spring-kotlin-webflux-videostreaming" 2 | -------------------------------------------------------------------------------- /spring-kotlin-webflux-videostreaming/src/main/kotlin/com/knf/springkotlinwebfluxvideostreaming/SpringkotlinwebfluxvideostreamingApplication.kt: -------------------------------------------------------------------------------- 1 | package com.knf.springkotlinwebfluxvideostreaming 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class SpringkotlinwebfluxvideostreamingApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /spring-kotlin-webflux-videostreaming/src/main/kotlin/com/knf/springkotlinwebfluxvideostreaming/config/EndPointConfig.kt: -------------------------------------------------------------------------------- 1 | package com.knf.springkotlinwebfluxvideostreaming.config 2 | 3 | 4 | import com.knf.springkotlinwebfluxvideostreaming.service.VideoStreamingService 5 | import org.springframework.beans.factory.annotation.Autowired 6 | import org.springframework.context.annotation.Bean 7 | import org.springframework.context.annotation.Configuration 8 | import org.springframework.core.io.Resource 9 | import org.springframework.http.MediaType 10 | import org.springframework.web.reactive.function.server.* 11 | import reactor.core.publisher.Mono 12 | 13 | @Configuration 14 | class EndPointConfig { 15 | @Autowired 16 | private val service: VideoStreamingService? = null 17 | @Bean 18 | fun router(): RouterFunction { 19 | return RouterFunctions.route() 20 | .GET( 21 | "video/{name}", 22 | HandlerFunction { serverRequest: ServerRequest -> videoHandler(serverRequest) }) 23 | .build() 24 | } 25 | 26 | private fun videoHandler(serverRequest: ServerRequest): Mono { 27 | val title: String = serverRequest.pathVariable("name") 28 | return ServerResponse.ok() 29 | .contentType(MediaType.valueOf("video/mp4")) 30 | .body(service!!.getVideo(title), Resource::class.java) 31 | } 32 | } -------------------------------------------------------------------------------- /spring-kotlin-webflux-videostreaming/src/main/kotlin/com/knf/springkotlinwebfluxvideostreaming/controller/VideoStreamingController.kt: -------------------------------------------------------------------------------- 1 | package com.knf.springkotlinwebfluxvideostreaming.controller 2 | 3 | 4 | import com.knf.springkotlinwebfluxvideostreaming.service.VideoStreamingService 5 | import org.springframework.beans.factory.annotation.Autowired 6 | import org.springframework.core.io.Resource 7 | import org.springframework.web.bind.annotation.GetMapping 8 | import org.springframework.web.bind.annotation.PathVariable 9 | import org.springframework.web.bind.annotation.RequestHeader 10 | import org.springframework.web.bind.annotation.RestController 11 | import reactor.core.publisher.Mono 12 | 13 | @RestController 14 | class VideoStreamingController { 15 | @Autowired 16 | private val service: VideoStreamingService? = null 17 | @GetMapping(value = ["video/{name}"], produces = ["video/mp4"]) 18 | fun getVideo( 19 | @PathVariable title: String?, 20 | @RequestHeader("Range") range: String? 21 | ): Mono { 22 | return service!!.getVideo(title) 23 | } 24 | } -------------------------------------------------------------------------------- /spring-kotlin-webflux-videostreaming/src/main/kotlin/com/knf/springkotlinwebfluxvideostreaming/service/VideoStreamingService.kt: -------------------------------------------------------------------------------- 1 | package com.knf.springkotlinwebfluxvideostreaming.service 2 | 3 | import org.springframework.beans.factory.annotation.Autowired 4 | import org.springframework.core.io.ResourceLoader 5 | import reactor.core.publisher.Mono 6 | import com.knf.springkotlinwebfluxvideostreaming.service.VideoStreamingService 7 | import org.springframework.core.io.Resource 8 | import org.springframework.stereotype.Service 9 | 10 | @Service 11 | class VideoStreamingService { 12 | @Autowired 13 | private val resourceLoader: ResourceLoader? = null 14 | fun getVideo(title: String?): Mono { 15 | return Mono.fromSupplier { resourceLoader!!.getResource(String.format(FORMAT, title)) } 16 | } 17 | 18 | companion object { 19 | private const val FORMAT = "classpath:mp4/%s.mp4" 20 | } 21 | } -------------------------------------------------------------------------------- /spring-kotlin-webflux-videostreaming/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /spring-kotlin-webflux-videostreaming/src/main/resources/mp4/sample_960x540.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/knowledgefactory4u/kotlin-springboot-app/65c876401a4cb91945ce6768d4d972b98a96c21d/spring-kotlin-webflux-videostreaming/src/main/resources/mp4/sample_960x540.mp4 -------------------------------------------------------------------------------- /spring-kotlin-webflux-videostreaming/src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Kotlin Spring WebFlux Video Streaming 9 | 10 | 11 | 12 |
13 |

Kotlin Spring WebFlux Video Streaming Example

14 | 17 |
18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /spring-kotlin-webflux-videostreaming/src/test/kotlin/com/knf/springkotlinwebfluxvideostreaming/SpringkotlinwebfluxvideostreamingApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package com.knf.springkotlinwebfluxvideostreaming 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class SpringkotlinwebfluxvideostreamingApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | --------------------------------------------------------------------------------