使用Spring-Boot和Spring-MVC从文件系统中的任何位置提供文件

时间:2015-10-15 16:06:44

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

我正在尝试创建一个网络应用,您可以上传保存在我的文件系统中的图像,然后在某个地址(有点像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>

1 个答案:

答案 0 :(得分:5)

您可以创建@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所在的同一个包中,或放在其下的某个位置,以便自动扫描