欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot 2.x (3):文件上传

程序员文章站 2022-04-09 17:37:33
文件上传有两个要点 一是如何高效地上传:使用MultipartFile替代FileOutputSteam 二是上传文件的路径问题的解决:使用路径映射 文件路径通常不在classpath,而是本地的一个固定路径或者是一个文件服务器路径 SpringBoot的路径: src/main/java:存放代码 ......

文件上传有两个要点

一是如何高效地上传:使用multipartfile替代fileoutputsteam

二是上传文件的路径问题的解决:使用路径映射

文件路径通常不在classpath,而是本地的一个固定路径或者是一个文件服务器路径

 

springboot的路径:

src/main/java:存放代码

src/main/resources:存放资源

  static: 存放静态文件:css、js、image (访问方式 http://localhost:8080/js/main.js)

  templates:存放静态页面:html,jsp

  application.properties:配置文件

但是要注意:

比如我在static下新建index.html,那么就可以访问localhost:8080/index.html看到页面

如果在templates下新建index.html,那么访问会显示错误,除非在controller中进行跳转

如果想对默认静态资源路径进行修改,则在application.properties中配置:

spring.resources.static-locations = classpath:/meta-inf/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ 

这里默认的顺序是先从/meta-inf/resources中进行寻找,最后找到/public,可以在后边自行添加

 

文件上传不是老问题,这里就当是巩固学习了

方式:multipartfile file,源自springmvc

首先需要一个文件上传的页面

在static目录下新建一个html页面:

<!doctype html>
<html>
<head>
<title>文件上传</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
    <form enctype="multipart/form-data" method="post" action="/upload">
        文件:<input type="file" name="head_img" /> 姓名:<input type="text"
            name="name" /> <input type="submit" value="上传" />
    </form>
</body>
</html>

 

文件上传成功否需要返回的应该是一个封装的对象:

package org.dreamtech.springboot.domain;

import java.io.serializable;

public class filedata implements serializable {
    private static final long serialversionuid = 8573440386723294606l;
    // 返回状态码:0失败、1成功
    private int code;
    // 返回数据
    private object data;
    // 错误信息
    private string errmsg;

    public int getcode() {
        return code;
    }

    public void setcode(int code) {
        this.code = code;
    }

    public object getdata() {
        return data;
    }

    public void setdata(object data) {
        this.data = data;
    }

    public string geterrmsg() {
        return errmsg;
    }

    public void seterrmsg(string errmsg) {
        this.errmsg = errmsg;
    }

    public filedata(int code, object data) {
        super();
        this.code = code;
        this.data = data;
    }

    public filedata(int code, object data, string errmsg) {
        super();
        this.code = code;
        this.data = data;
        this.errmsg = errmsg;
    }

}

 

处理文件上传的controller:

package org.dreamtech.springboot.controller;

import java.io.file;
import java.util.uuid;

import javax.servlet.http.httpservletrequest;

import org.dreamtech.springboot.domain.filedata;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestparam;
import org.springframework.web.bind.annotation.restcontroller;
import org.springframework.web.multipart.multipartfile;

@restcontroller
public class filecontroller {
    private static final string file_path = "d:\\temp\\images\\";
    static {
        file file = new file(file_path);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    @requestmapping("/upload")
    private filedata upload(@requestparam("head_img") multipartfile file, httpservletrequest request) {
        if (file.isempty()) {
            return new filedata(0, null, "文件不能为空");
        }
        string name = request.getparameter("name");
        system.out.println("用户名:" + name);
        string filename = file.getoriginalfilename();
        system.out.println("文件名:" + filename);
        string suffixname = filename.substring(filename.lastindexof("."));
        system.out.println("后缀名:" + suffixname);
        filename = uuid.randomuuid() + suffixname;
        string path = file_path + filename;
        file dest = new file(path);
        system.out.println("文件路径:" + path);
        try {
            // transferto文件保存方法效率很高
            file.transferto(dest);
            system.out.println("文件上传成功");
            return new filedata(1, filename);
        } catch (exception e) {
            e.printstacktrace();
            return new filedata(0, filename, e.tostring());
        }
    }
}

 

还有问题要处理,保存图片的路径不是项目路径,而是本地的一个固定路径,那么要如何通过url访问到图片呢?

对路径进行映射:比如我图片保存在d:\temp\image,那么我们希望访问localhost:8080/image/xxx.png得到图片

可以修改tomcat的配置文件,也可以按照下面的配置:

package org.dreamtech.springboot.config;

import org.springframework.context.annotation.configuration;
import org.springframework.web.servlet.config.annotation.resourcehandlerregistry;
import org.springframework.web.servlet.config.annotation.webmvcconfigurer;

@configuration
public class mywebappconfigurer implements webmvcconfigurer {
    @override
    public void addresourcehandlers(resourcehandlerregistry registry) {
        registry.addresourcehandler("/image/**").addresourcelocations("file:d:/temp/images/");
    }
}

 

还有一些细节问题不得忽略:对文件大小进行限制

package org.dreamtech.springboot.config;

import javax.servlet.multipartconfigelement;

import org.springframework.boot.web.servlet.multipartconfigfactory;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.util.unit.datasize;

@configuration
public class filesizeconfigurer {
    @bean
    public multipartconfigelement multipartconfigelement() {
        multipartconfigfactory factory = new multipartconfigfactory();
        // 单个文件最大10mb
        factory.setmaxfilesize(datasize.ofmegabytes(10l));
        /// 设置总上传数据总大小10gb
        factory.setmaxrequestsize(datasize.ofgigabytes(10l));
        return factory.createmultipartconfig();
    }
}

 

打包后的项目如何处理文件上传呢?

顺便记录springboot打包的坑,mvn clean package运行没有问题,但是不太方便

于是eclipse中run as maven install,但是会报错,根本原因是没有配置jdk,配置的是jre:

解决:https://blog.csdn.net/lslk9898/article/details/73836745

 

图片量不大的时候,我们可以用自己的服务器自行处理,

如果图片量很多,可以采用图片服务器,自己用nginx搭建或者阿里oss等等