Docker 容器中的 Spring Boot 资源

Posted

技术标签:

【中文标题】Docker 容器中的 Spring Boot 资源【英文标题】:Spring Boot Resources in Docker container 【发布时间】:2018-10-31 06:17:55 【问题描述】:

我正在将 Docker 用于 Spring Boot 应用程序,到目前为止一切正常。

我在src/main/resources/db/data/dummydata.csv有一个资源文件

在引导类中,此文件用于将虚拟数据导入数据库。

私人乐趣 getDummyData(): List var fileReader: BufferedReader? = 空

val dummyData = ArrayList<DummyDataEntity>()

try 
    var line: String?

    val res = ResourceUtils.getFile("classpath:db/data/dummydata.csv")
    fileReader = BufferedReader(FileReader(res.path))

    // Read CSV header
    fileReader.readLine()

   ... Processing the data ...

 catch (e: Exception) 
    e.printStackTrace()
 finally 
    try 
        fileReader!!.close()
     catch (e: Exception) 
        e.printStackTrace()
    

    return dummyData

当我在 IntelliJ 中运行应用程序时,一切正常,但是当我在 Docker 中运行它时,却找不到。

Jar 和 Docker 镜像是使用 Kotlin DSL Gradle 创建的。

import com.palantir.gradle.docker.DockerExtension
import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension
import org.gradle.tooling.model.GradleTask
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.springframework.boot.gradle.tasks.bundling.BootJar

buildscript 
    repositories 
        mavenCentral()
    

    dependencies 
        classpath(Libs.springBootGradlePlugin)
        classpath(Libs.kotlinGradlePlugin)
        classpath(Libs.kotlinAllOpen)
        classpath(Libs.gradleDocker)
    


plugins 
    // Apply the java-library plugin to add support for Java Library
    `java-library`


apply 
    plugin("kotlin")
    plugin("kotlin-spring")
    plugin("org.springframework.boot")
    plugin("io.spring.dependency-management")
    plugin("com.palantir.docker")


repositories 
    mavenCentral()


dependencies 
    compile(Libs.kotlinReflect)

    // Spring Boot
    compile(Libs.springBootStarterDataJpa)


configure<DependencyManagementExtension> 
    imports 
        mavenBom(Libs.vaadinBom)
    


val bootJar: BootJar by tasks
bootJar.baseName = "reporting-app-site"
bootJar.version = "0.0.1"

configure<DockerExtension> 
    name = "brabantia/$bootJar.baseName"
    files(bootJar.archivePath)
    buildArgs(mapOf("JAR_FILE" to bootJar.archiveName))
    dependsOn(tasks["build"])


val compileKotlin: KotlinCompile by tasks
compileKotlin.kotlinOptions.jvmTarget = "1.8"

Jar 确实包含 BOOT-INF/classes/db/data/dummyData.csv 但是当应用程序运行时抛出的错误是

java.io.FileNotFoundException: class path resource [db/data/dummydata.csv] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app.jar!/BOOT-INF/classes!/db/data/dummydata.csv

我在这里错过了什么?

【问题讨论】:

我认为这是 getFile 工作方式的问题,请查看this answer 【参考方案1】:

以下对我有用..,您需要使用 InputStream 而不是文件。

...

@Autowired
private ResourceLoader resourceLoader;

...

  Resource resource= resourceLoader.getResource("classpath:/account_info.html");

    InputStream inputStream= resource.getInputStream();

    Assert.notNull(inputStream,"Could not load template resource!");

    String email = null;

    try 
        byte[] bdata = FileCopyUtils.copyToByteArray(inputStream);
        email = new String(bdata, StandardCharsets.UTF_8);
     catch (IOException e) 
        logger.warn("IOException", e);
    finally 
        if ( inputStream != null) 
            IOUtils.closeQuietly(inputStream);
        
    

【讨论】:

以上是关于Docker 容器中的 Spring Boot 资源的主要内容,如果未能解决你的问题,请参考以下文章

无法将docker Spring-Boot应用程序与docker-compose中的mysql容器和flyway连接起来

将 Spring Boot 应用程序连接到 Docker 容器中的 Oracle 数据库 12.2.0.1

如何将 application.properties 传递给 Docker 容器中的 Spring Boot 应用程序?

Angular 应用程序和部署在 Docker 容器中的 Spring Boot API 之间的通信问题

spring boot项目生成docker镜像并完成容器部署

Docker 中的 Consul 和 Spring Boot 服务 - 不取消注册