Spring Boot 与 Kotlin 上传文件的示例代码
程序员文章站
2023-12-13 21:43:10
如果我们做一个小型的web站,而且刚好选择的kotlin 和spring boot技术栈,那么上传文件的必不可少了,当然,如果你做一个中大型的web站,那建议你使用云存储,...
如果我们做一个小型的web站,而且刚好选择的kotlin 和spring boot技术栈,那么上传文件的必不可少了,当然,如果你做一个中大型的web站,那建议你使用云存储,能省不少事情。
这篇文章就介绍怎么使用kotlin 和spring boot上传文件
构建工程
如果对于构建工程还不是很熟悉的可以参考《我的第一个kotlin应用》
完整 build.gradle 文件
group 'name.quanke.kotlin' version '1.0-snapshot' buildscript { ext.kotlin_version = '1.2.10' ext.spring_boot_version = '1.5.4.release' repositories { mavencentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath("org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version") // kotlin整合springboot的默认无参构造函数,默认把所有的类设置open类插件 classpath("org.jetbrains.kotlin:kotlin-noarg:$kotlin_version") classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlin_version") } } apply plugin: 'kotlin' apply plugin: "kotlin-spring" // see https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin apply plugin: 'org.springframework.boot' jar { basename = 'chapter11-5-6-service' version = '0.1.0' } repositories { mavencentral() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" compile "org.springframework.boot:spring-boot-starter-web:$spring_boot_version" compile "org.springframework.boot:spring-boot-starter-thymeleaf:$spring_boot_version" testcompile "org.springframework.boot:spring-boot-starter-test:$spring_boot_version" testcompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" } compilekotlin { kotlinoptions.jvmtarget = "1.8" } compiletestkotlin { kotlinoptions.jvmtarget = "1.8" }
创建文件上传controller
import name.quanke.kotlin.chaper11_5_6.storage.storagefilenotfoundexception import name.quanke.kotlin.chaper11_5_6.storage.storageservice import org.springframework.beans.factory.annotation.autowired import org.springframework.core.io.resource import org.springframework.http.httpheaders import org.springframework.http.responseentity import org.springframework.stereotype.controller import org.springframework.ui.model import org.springframework.web.bind.annotation.* import org.springframework.web.multipart.multipartfile import org.springframework.web.servlet.mvc.method.annotation.mvcuricomponentsbuilder import org.springframework.web.servlet.mvc.support.redirectattributes import java.io.ioexception import java.util.stream.collectors /** * 文件上传控制器 * created by http://quanke.name on 2018/1/12. */ @controller class fileuploadcontroller @autowired constructor(private val storageservice: storageservice) { @getmapping("/") @throws(ioexception::class) fun listuploadedfiles(model: model): string { model.addattribute("files", storageservice .loadall() .map { path -> mvcuricomponentsbuilder .frommethodname(fileuploadcontroller::class.java, "servefile", path.filename.tostring()) .build().tostring() } .collect(collectors.tolist())) return "uploadform" } @getmapping("/files/{filename:.+}") @responsebody fun servefile(@pathvariable filename: string): responseentity<resource> { val file = storageservice.loadasresource(filename) return responseentity .ok() .header(httpheaders.content_disposition, "attachment; filename=\"" + file.filename + "\"") .body(file) } @postmapping("/") fun handlefileupload(@requestparam("file") file: multipartfile, redirectattributes: redirectattributes): string { storageservice.store(file) redirectattributes.addflashattribute("message", "you successfully uploaded " + file.originalfilename + "!") return "redirect:/" } @exceptionhandler(storagefilenotfoundexception::class) fun handlestoragefilenotfound(exc: storagefilenotfoundexception): responseentity<*> { return responseentity.notfound().build<any>() } }
上传文件服务的接口
import org.springframework.core.io.resource import org.springframework.web.multipart.multipartfile import java.nio.file.path import java.util.stream.stream interface storageservice { fun init() fun store(file: multipartfile) fun loadall(): stream<path> fun load(filename: string): path fun loadasresource(filename: string): resource fun deleteall() }
上传文件服务
import org.springframework.beans.factory.annotation.autowired import org.springframework.core.io.resource import org.springframework.core.io.urlresource import org.springframework.stereotype.service import org.springframework.util.filesystemutils import org.springframework.util.stringutils import org.springframework.web.multipart.multipartfile import java.io.ioexception import java.net.malformedurlexception import java.nio.file.files import java.nio.file.path import java.nio.file.paths import java.nio.file.standardcopyoption import java.util.stream.stream @service class filesystemstorageservice @autowired constructor(properties: storageproperties) : storageservice { private val rootlocation: path init { this.rootlocation = paths.get(properties.location) } override fun store(file: multipartfile) { val filename = stringutils.cleanpath(file.originalfilename) try { if (file.isempty) { throw storageexception("failed to store empty file " + filename) } if (filename.contains("..")) { // this is a security check throw storageexception( "cannot store file with relative path outside current directory " + filename) } files.copy(file.inputstream, this.rootlocation.resolve(filename), standardcopyoption.replace_existing) } catch (e: ioexception) { throw storageexception("failed to store file " + filename, e) } } override fun loadall(): stream<path> { try { return files.walk(this.rootlocation, 1) .filter { path -> path != this.rootlocation } .map { path -> this.rootlocation.relativize(path) } } catch (e: ioexception) { throw storageexception("failed to read stored files", e) } } override fun load(filename: string): path { return rootlocation.resolve(filename) } override fun loadasresource(filename: string): resource { try { val file = load(filename) val resource = urlresource(file.touri()) return if (resource.exists() || resource.isreadable) { resource } else { throw storagefilenotfoundexception( "could not read file: " + filename) } } catch (e: malformedurlexception) { throw storagefilenotfoundexception("could not read file: " + filename, e) } } override fun deleteall() { filesystemutils.deleterecursively(rootlocation.tofile()) } override fun init() { try { files.createdirectories(rootlocation) } catch (e: ioexception) { throw storageexception("could not initialize storage", e) } } }
自定义异常
open class storageexception : runtimeexception { constructor(message: string) : super(message) constructor(message: string, cause: throwable) : super(message, cause) } class storagefilenotfoundexception : storageexception { constructor(message: string) : super(message) constructor(message: string, cause: throwable) : super(message, cause) }
配置文件上传目录
import org.springframework.boot.context.properties.configurationproperties @configurationproperties("storage") class storageproperties { /** * folder location for storing files */ var location = "upload-dir" }
启动spring boot
/** * created by http://quanke.name on 2018/1/9. */ @springbootapplication @enableconfigurationproperties(storageproperties::class) class application { @bean internal fun init(storageservice: storageservice) = commandlinerunner { storageservice.deleteall() storageservice.init() } companion object { @throws(exception::class) @jvmstatic fun main(args: array<string>) { springapplication.run(application::class.java, *args) } } }
创建一个简单的 html模板 src/main/resources/templates/uploadform.html
<html xmlns:th="http://www.thymeleaf.org"> <body> <div th:if="${message}"> <h2 th:text="${message}"/> </div> <div> <form method="post" enctype="multipart/form-data" action="/"> <table> <tr> <td>file to upload:</td> <td><input type="file" name="file"/></td> </tr> <tr> <td></td> <td><input type="submit" value="upload"/></td> </tr> </table> </form> </div> <div> <ul> <li th:each="file : ${files}"> <a th:href="${file}" rel="external nofollow" th:text="${file}"/> </li> </ul> </div> </body> </html>
配置文件 application.yml
spring: http: multipart: max-file-size: 128kb max-request-size: 128kb
更多spring boot 和 kotlin相关内容,欢迎关注 《spring boot 与 kotlin 实战》
源码:
参考:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
Spring Boot 与 Kotlin 使用JdbcTemplate连接MySQL数据库的方法
-
Spring Boot与Kotlin处理Web表单提交的方法
-
Spring Boot 与 Kotlin 上传文件的示例代码
-
Spring Boot 与 Kotlin 使用Redis数据库的配置方法
-
使用Spring Cloud Feign上传文件的示例
-
Spring Boot中使用RabbitMQ的示例代码
-
Spring Boot 与 kotlin 使用Thymeleaf模板引擎渲染web视图的方法
-
spring boot整合Shiro实现单点登录的示例代码
-
spring boot 与kafka集成的示例代码
-
spring boot封装HttpClient的示例代码