Springboot的文件上传与下载
- 文章说明
- 配置路径映射
- 实体类、服务与控制器
- 前端页面
- 前端服务器搭建
 
文章说明
文件上传实现了,文件下载是非常简单的,只需要通过浏览器即可下载成功;于是就没有实现专门的接口
配置路径映射
通过 public void addResourceHandlers(ResourceHandlerRegistry registry) 实现路径映射
PathConfig.java (配置常量类)
package com.boot.config;
import org.springframework.stereotype.Component;
/**
 * @author bbyh
 * @date 2022/10/29 0029 17:04
 * @description
 */
@Component
public class PathConfig {
    public static final String REQUEST_PATH = "/static/img/**";
    public static final String SYSTEM_ERROR_MSG = "暂时不支持Windows、Linux系统外的操作系统";
    public static final String WINDOWS_LOCAL_PATH = "D:/static/img/";
    public static final String LINUX_LOCAL_PATH = "/usr/local/static/img/";
    private static final String LOCAL_BASE_URL = "http://127.0.0.1:";
    private static final String REMOTE_BASE_URL = "http://47.97.170.172:";
    public static final String LOCAL_FILE_IP = LOCAL_BASE_URL + "10001";
    public static final String REMOTE_FILE_IP = REMOTE_BASE_URL + "10001";
    public static final String LOCAL_API_IP = LOCAL_BASE_URL + "8081";
    public static final String REMOTE_API_IP = REMOTE_BASE_URL + "8081";
    public static final String LOCAL_FILE_URL = LOCAL_FILE_IP + "/static/img/";
    public static final String REMOTE_FILE_URL = REMOTE_FILE_IP + "/static/img/";
    public static Boolean judgeWindows() {
        return System.getProperty("os.name").toLowerCase().contains("windows");
    }
    public static Boolean judgeLinux() {
        return System.getProperty("os.name").toLowerCase().contains("linux");
    }
}
WebConfig.java (分系统来配置了路径映射,以及对请求的IP,及请求类型进行了限定)
package com.boot.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.io.File;
import static com.boot.config.PathConfig.*;
/**
 * @author bbyh
 * @date 2022/10/28 0028 19:00
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        File localDir;
        boolean flag = false;
        if (judgeWindows()) {
            localDir = new File(WINDOWS_LOCAL_PATH);
            if (!localDir.exists()) {
                flag = localDir.mkdirs();
            }
            if (flag) {
                System.out.println("已成功创建资源 " + WINDOWS_LOCAL_PATH + " 目录: ");
            }
        } else if (judgeLinux()) {
            localDir = new File(LINUX_LOCAL_PATH);
            if (!localDir.exists()) {
                flag = localDir.mkdirs();
            }
            if (flag) {
                System.out.println("已成功创建资源 " + LINUX_LOCAL_PATH + " 目录: ");
            }
        } else {
            throw new UnsupportedOperationException(SYSTEM_ERROR_MSG);
        }
        registry.addResourceHandler(REQUEST_PATH)
                .addResourceLocations("file:" + localDir.getAbsolutePath() + File.separator);
    }
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        if (judgeWindows()) {
            registry.addMapping("/**")
                    .allowedOrigins(LOCAL_API_IP)
                    .allowedMethods("GET", "POST", "DELETE", "PUT")
                    .maxAge(3600);
        } else if (judgeLinux()) {
            registry.addMapping("/**")
                    .allowedOrigins(REMOTE_API_IP)
                    .allowedMethods("GET", "POST", "DELETE", "PUT")
                    .maxAge(3600);
        } else {
            throw new UnsupportedOperationException(SYSTEM_ERROR_MSG);
        }
    }
}
实体类、服务与控制器
Result.java (用于返回结果)
package com.boot.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @author bbyh
 * @date 2022/10/27 0027 19:17
 * @description
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result {
    public static final String SUCCESS = "200";
    public static final String ERROR = "500";
    private Object data;
    private String msg;
    private String code;
    public static Result success(Object data, String msg) {
        return new Result(data, msg, SUCCESS);
    }
    public static Result error(Object data, String msg) {
        return new Result(data, msg, ERROR);
    }
}
实现服务类
package com.boot.service;
import com.boot.entity.Result;
import org.springframework.web.multipart.MultipartFile;
/**
 * @author bbyh
 * @date 2022/10/4 0004 16:40
 * @description
 */
public interface FileService {
    /**
     * 处理上传的文件
     *
     * @param file    所上传文件
     * @param isLocal 是否是本地环境
     * @return 返回上传文件放到目录后的路径,最终将URL返回到前端页面,随着文章保存到数据库中
     */
    Result upload(MultipartFile file, Boolean isLocal);
}
package com.boot.service.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONObject;
import com.boot.entity.Result;
import com.boot.service.FileService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import static com.boot.config.PathConfig.*;
/**
 * @author bbyh
 * @date 2022/10/4 0004 16:41
 * @description
 */
@Service
public class FileServiceImpl implements FileService {
    @Override
    public Result upload(MultipartFile file, Boolean isLocal) {
        String fileName = System.currentTimeMillis() + "__" + file.getOriginalFilename();
        JSONObject jsonObject = new JSONObject();
        if (isLocal) {
            try {
                FileUtil.writeBytes(file.getBytes(), WINDOWS_LOCAL_PATH + fileName);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            jsonObject.putOpt("url", LOCAL_FILE_URL + fileName);
        } else {
            try {
                FileUtil.writeBytes(file.getBytes(), LINUX_LOCAL_PATH + fileName);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            jsonObject.putOpt("url", REMOTE_FILE_URL + fileName);
        }
        jsonObject.putOpt("fileName", fileName);
        return Result.success(jsonObject, "图片上传成功");
    }
}
控制器
package com.boot.controller;
import com.boot.entity.Result;
import com.boot.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import static com.boot.config.PathConfig.*;
/**
 * @author bbyh
 * @date 2022/10/29 0029 13:53
 * @description
 */
@RestController
@RequestMapping("/file")
public class FileController {
    @Autowired
    FileService fileService;
    @PostMapping("/upload")
    public Result upload(@RequestParam MultipartFile file) {
        if (judgeWindows()) {
            return fileService.upload(file, true);
        } else if (judgeLinux()) {
            return fileService.upload(file, false);
        } else {
            throw new UnsupportedOperationException(SYSTEM_ERROR_MSG);
        }
    }
}
前端页面
采用Vue编写,结合Element-ui-plus的上传组件实现
App.vue
<template>
    <div id="app">
        <el-upload
            class="upload"
            action="#"
            :auto-upload="false"
            :on-change="handleChange"
            :limit="20"
            :show-file-list="false"
        >
            <el-image
                id="download"
                :src="avatarUrl"
                style="width: 100%; height: 100%"
            ></el-image>
        </el-upload>
    </div>
</template>
<script>
import { ref } from "@vue/reactivity";
import { postFileRequest } from "./utils/api";
export default {
    name: "App",
    components: {},
    setup() {
        let avatarUrl = ref("http://127.0.0.1:10001/static/img/10.jpg");
        function handleChange(file) {
            let formData = new FormData();
            formData.append("file", file.raw);
            postFileRequest("/file/upload", formData).then((response) => {
                avatarUrl.value = response.data.data.url;
            });
        }
        return {
            avatarUrl,
            handleChange,
        };
    },
};
</script>
<style>
* {
    padding: 0;
    margin: 0;
}
.upload {
    background-color: rgb(182, 214, 215);
    width: 30%;
    height: 30%;
}
</style>
api.js
import axios from "axios";
import { ElMessage } from 'element-plus';
const localPath = 'http://127.0.0.1:9000'
const localFilePath = 'http://127.0.0.1:10001'
const remoteFilePath = 'http://47.97.170.172:10001'
export function message(msg, type) {
    ElMessage({
        message: msg,
        showClose: true,
        type: type,
        center: true
    })
}
export const getRequest = (url, params) => {
    return axios({
        method: 'get',
        url: localPath + url,
        params: params
    })
}
export const postRequest = (url, params) => {
    return axios({
        method: 'post',
        url: localPath + url,
        data: params
    })
}
export const postFileRequest = (url, params) => {
    return axios({
        method: 'post',
        url: localFilePath + url,
        data: params
    })
}
export const putRequest = (url, params) => {
    return axios({
        method: 'put',
        url: localPath + url,
        data: params
    })
}
export const deleteRequest = (url, params) => {
    return axios({
        method: 'delete',
        url: localPath + url,
        data: params
    })
}
前端服务器搭建
server.js ,其余静态文件放在static文件夹下即可
const express = require('express');
const app = express();
app.use(express.static(__dirname + '/static'))
app.listen(8081, ()=>{
    console.log("服务器端8080端口已打开!")
});




















