【问题标题】:Serving files using Spring-Boot and Spring-MVC from any location in the file system使用 Spring-Boot 和 Spring-MVC 从文件系统中的任何位置提供文件
【发布时间】:2016-01-14 04:45:27
【问题描述】:

我正在尝试制作一个网络应用程序,您可以在其中上传保存在我的文件系统中的图像,然后在某个地址(有点像 imgur)提供给用户。

图片上传并保存到我的系统后,我在提供图片时遇到了问题。有人向我指出,问题可能是我将图像存储为源树的一部分,而我应该将它们存储在我的项目目标文件夹中。现在,我首先将图像存储在 project/src/main/resources/static/images 中的原因是因为我无法从其他任何地方在我的网站上提供静态内容。

这几天我一直在搜索和阅读这方面的内容,但没有找到任何适用的解决方案。这类问题的答案通常涉及我的项目没有的文件(如 application-servlet.xml 或 web.xml)并且我以前从未使用过(我对 Spring、Spring-Boot 和Java Web 开发一般)。

我的项目的基础是由 github 上的导师制作的,然后我克隆了它,包括 Application.java,所以我看到的使用 Spring Configuration 的解决方案也不适合。

这是我项目的(希望是相关的)部分:

这是我的 Application.java 文件。我什么都没做,它与我克隆的原始 github 中的文件完全相同。

package project;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;

/**
 * The main class of the project.
 * By running the main class of {@link Application} then you start the Spring Boot system
 */
@SpringBootApplication
public class Application extends SpringBootServletInitializer{

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder applicationBuilder){
        return applicationBuilder.sources(Application.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }

}

这是我的 application.properties。这里我只是添加了数据库的东西:

spring.view.prefix=/WEB-INF/jsp/
spring.view.suffix=.jsp
multipart.maxFileSize=-1
debug=true

spring.datasource.url=jdbc:postgresql://localhost:5432/finaltest
spring.datasource.username=myusername
spring.datasource.password=mypassword

这是我的 pom.xml(我项目中唯一的 xml 文件)。这里我只是添加了数据库依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>HBV501G</groupId>
    <artifactId>Spring_Web_MVC</artifactId>
    <version>0.1</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.5.RELEASE</version>
    </parent>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.4-1200-jdbc41</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

我自己制作的项目的其余部分,从我的 UploadController 开始。它只是从 post 请求中获取文件、标签和类型,以随机生成的名称将当前文件写入文件系统中的某个位置,并将有关文件的信息(类型、标签、名称及其在文件系统中的位置)存储在一个数据库:

package project.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Random;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import project.service.MediaFile;
import project.service.MediaFileRepository;

@Controller
public class UploadController {
    private final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private Random rnd = new Random();
    private int randomLength = 8;

    @Autowired
    private MediaFileRepository repository;

    @RequestMapping(value = "/uploadmedia", method = RequestMethod.GET)
    public String uploadForm() {
        return "upload";
    }

    @RequestMapping(value = "/uploadmedia", method = RequestMethod.POST)
    public String uploadSubmit(@RequestParam(value="files[]") MultipartFile[] files,
                               @RequestParam("tags[]") String[] tags, @RequestParam("types[]") String[] types)
    {
        String[] tagsArray;
        MultipartFile file;
        String name;
        String tag;
        String path;
        String type;

        for (int i = 0; i < files.length; i++) {
            file = files[i];
            tagsArray = tags[i].split("\\s+");
            type = types[i];

            name = randomString(randomLength);
            List<MediaFile> nameExists = repository.findByName(name);
            while (nameExists.size() > 0) {
                name = randomString(randomLength);
                nameExists = repository.findByName(name);
            }

            path = "/Users/.../src/main/resources/static/img/" + name + type;
            if (!file.isEmpty()) {
                try {
                    byte[] bytes = file.getBytes();
                    BufferedOutputStream stream =
                            new BufferedOutputStream(new FileOutputStream(new File(path)));
                    stream.write(bytes);
                    stream.close();
                    for (int j = 0; j < tagsArray.length; j++) {
                        tag = tagsArray[j].toLowerCase();
                        repository.save(new MediaFile(name, tag, path, type));
                    }
                    System.out.println("Success!");
                } catch (Exception e) {
                    System.out.println("Failure... " + e.getMessage());
                }
            } else {
                System.out.println("file is empty");
            }
        }
        return "upload";
    }

    private String randomString( int len ){
        StringBuilder sb = new StringBuilder( len );
        for( int i = 0; i < len; i++ )
            sb.append( AB.charAt( rnd.nextInt(AB.length()) ) );
        return sb.toString();
    }
}

...接下来,这是我的 MediaController(上传的文件是某种媒体)。它只是检查一个 url 在数据库中是否有一个具有相应名称的文件,如果有,则将文件的路径发送到 media.jsp。

package project.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import project.service.MediaFile;
import project.service.MediaFileRepository;

import java.util.List;

/**
 * Created by johannesthorkell on 13.10.2015.
 */

@Controller
@RequestMapping("/media")
public class MediaController {

    @Autowired
    private MediaFileRepository repository;

    @RequestMapping("/{media}")
    public String newMedia(@PathVariable String media, Model model) {
        List<MediaFile> nameExists = repository.findByName(media);
        if (nameExists.size() > 0) {
            MediaFile mediaFile = nameExists.get(0);
            String name = mediaFile.getName();
            String type = mediaFile.getType();
            model.addAttribute("image", "/img/" + name + type);
            return "media";
        }
        return "error";
    }
}

...最后,这是我的 media.jsp 文件。它只是从我的 MediaController 中获取文件位置并将其作为 img 元素的 src 属性(我用来测试的文件是图像文件)。

<!DOCTYPE html>

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Home</title>
    </head>
        <h1>Media Upload</h1>
        <img src="${image}">
        <div id="links">
            <a href="/uploadmedia">upload media</a>
            <a href="/searchmedia">search media</a>
        </div>
    </body>
</html>

【问题讨论】:

标签: java spring jsp spring-mvc spring-boot


【解决方案1】:

你可以创建一个@Configuration bean,比如

@Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        super.addResourceHandlers(registry);
        registry.addResourceHandler("/**").addResourceLocations("file:///D:/your_image_location/");
    }
}

请务必将 bean 放在您的 Application 所在的同一包中,或者放在它下面的某个位置,以便自动扫描它

【讨论】:

  • 这正是我想要的!
猜你喜欢
  • 1970-01-01
  • 2019-02-21
  • 2019-02-22
  • 2018-08-12
  • 1970-01-01
  • 2021-09-11
  • 2013-01-01
  • 2021-12-26
  • 1970-01-01
相关资源
最近更新 更多