SpringMVC实现文件上传和下载

 SpringMVC+elementUI 实现文件上传(本地上传)

前端vue页面:

上传组件代码块

<el-col :span="12">
            <el-form-item label="用户头像">
              <el-upload
                ref="upload"
                :class="{ disUoloadSty: upload.uploadDisabled }"<!--当上传成功后隐藏上传控件-->
                action="http://localhost:9000/sysuser/upload"
                name="file"<!--后台根据file得到上传的内容-->
                list-type="picture-card"
                :on-preview="handlePreview"
                :on-progress="onProgress"
                :on-remove="handleRemove"
                :on-success="handleSuccess"
                :before-upload="beforeUpload"
                :on-change="handleChange"
                :file-list="upload.fileList"
                accept=".jpeg,.jpg,.gif,.png"
                :limit="upload.limitCountImg"
              >
                <i class="el-icon-plus"></i>
              </el-upload>
              <!--预览图片-->
              <el-dialog
                :modal-append-to-body="false"
                :visible.sync="upload.imgVisible"
                width="30%"
              >
                <img
                  width="100%"
                  :src="upload.dialogImageUrl"
                  alt="图片未找到"
                />
              </el-dialog>
            </el-form-item>
          </el-col>

声明变量

data() {
    return {
        upload: {
        // 是否禁用上传,
        uploadDisabled: false,
        // 是否显示预览图片
        imgVisible: false,
        // 预览图片url
        dialogImageUrl: "",
        // 上传的文件列表(用于在上传组件中回显图片), 例如: [{name: 'xxx.jpg', url: 'https://xxx.com/xxx.jpg'}]
        fileList: [],
        limitCountImg: 1, //上传图片的最大数量
      },
    }
}

事件

methods: {
   //文件上传成功的钩子函数
    handleSuccess(response, file, fileList) {
      this.$message.success("图片上传成功");

      if (response.code == 200) {
        this.upload.imgVisible = true
        this.upload.dialogImageUrl = response.message;
        this.updateForm.uphoto = response.message;//将返回的文件储存路径赋值uphoto字段
      }
    },
    // 上传中
    onProgress(event, file, fileList) {
      this.upload.uploadDisabled = true;
    },
    //删除文件之前的钩子函数
    handleRemove(file, fileList) {
      this.$message.info("已删除原有图片");
      this.upload.uploadDisabled = fileList.length >= this.upload.limitCountImg;
    },
    //处理图片变化时
    handleChange(file, fileList) {
      this.upload.uploadDisabled = fileList.length >= this.upload.limitCountImg;
    },
    //点击列表中已上传的文件事的钩子函数
    handlePreview(file) { },
    //参数是上传的文件,若返回false,或返回Primary且被reject,则停止上传
    beforeUpload(file) {
      const isLt2M = file.size / 1024 / 1024 < 10;
      if (!isLt2M) {
        this.$message.error("上传图片大小不能超过 10MB!");
      }
      return isLt2M;
    },
}

样式控制

 <style>
.uoloadSty .el-upload--picture-card {
  width: 110px;
  height: 110px;
  line-height: 110px;
}
.disUoloadSty .el-upload--picture-card {
  display: none; /* 上传按钮隐藏 */
}
.picture {
  width: 60px;
  height: 60px;
  border: 0px;
}
.disabled .el-upload--picture-card {
  display: none; /* 上传按钮隐藏 */
}
        
  </style>

表格中显示:

 <el-table-column label="图片" width="130">
                <template scope="scope">                   
                    <img :src="scope.row.picture" class="picture" />                   
                </template>
            </el-table-column>

后端:

控制器:

/**
     * 文件上传
     *
     * @param file
     * @param request
     * @return
     */
    @PostMapping("upload")
    public Result upload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {

        //获取文件在服务器的储存位置
        String path = request.getSession().getServletContext().getRealPath("/upload");
        File filePath = new File(path);
        if (!filePath.exists() && !filePath.isDirectory()) {
            filePath.mkdir();
        }

        //获取原始文件名称(包含格式)
        String originalFileName = file.getOriginalFilename();

        //获取文件类型,以最后一个`.`为标识
        String type = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);

        //获取文件名称(不包含格式)
        String name = originalFileName.substring(0, originalFileName.lastIndexOf("."));

        //设置文件新名称: 当前时间+文件名称(不包含格式)
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String date = sdf.format(new Date());
        String fileName = date + name + "." + type;

        //在指定路径下创建一个文件
        File targetFile = new File(path, fileName);
        Result result = new Result();
        //将文件保存到服务器指定位置
        try {
            file.transferTo(targetFile);
            //将文件在服务器的存储路径返回
            result.setCode(200);
            result.setMessages("http://localhost:9000/upload/" + fileName);

        } catch (IOException e) {
            e.printStackTrace();
            result.setCode(500);
            result.setMessages("\"上传失败\"");
        }
        return result;
    }

对应的Result类

package com.wnxy.wateraffair.util;

import lombok.Data;

import java.util.HashMap;
import java.util.Map;

/**
 * @author :fengSir
 * @date :Created By 2022-08-20 16:45
 * @description :TODO
 */
@Data
public class Result {

    //是否成功
    private Boolean success;

    //返回码
    private Integer code;

    //返回消息
    private String message;

    //返回数据
    private Map<String, Object> data = new HashMap<String, Object>();

    //把构造方法私有
    private Result() {}
    public Result(boolean success, String message) {
        this.success = success;
        this.message = message;
    }

    public boolean isSuccess() {
        return success;
    }

    //成功静态方法
    public static Result ok() {
        Result result = new Result();
        result.setSuccess(true);
        result.setCode(200);
        result.setMessage("成功");
        return result;
    }
    //成功:自己指定消息
    public static Result ok(String msg) {
        Result result = new Result();
        result.setSuccess(true);
        result.setCode(200);
        result.setMessage(msg);
        return result;
    }

    //成功:自己指定消息和返回code
    public static Result ok(Integer code, String msg) {
        Result result = new Result();
        result.setSuccess(true);
        result.setCode(code);
        result.setMessage(msg);
        return result;
    }

    //失败静态方法
    public static Result error() {
        Result result = new Result();
        result.setSuccess(false);
        result.setCode(500);
        result.setMessage("失败");
        return result;
    }
    //失败:自己指定失败消息
    public static Result error(String msg) {
        Result result = new Result();
        result.setSuccess(false);
        result.setCode(500);
        result.setMessage(msg);
        return result;
    }

    //失败:自己指定失败消息和code
    public static Result error(Integer code , String msg) {
        Result result = new Result();
        result.setSuccess(false);
        result.setCode(code);
        result.setMessage(msg);
        return result;
    }
    //给返回消息添加数据
    public Result data(String key, Object value){
        this.data.put(key, value);
        return this;
    }

    //以下四个方法可以不关注,上面的方法已经基本满足需求
    public Result success(Boolean success){
        this.setSuccess(success);
        return this;
    }

    public Result message(String message){
        this.setMessage(message);
        return this;
    }

    public Result code(Integer code){
        this.setCode(code);
        return this;
    }

    public Result data(Map<String, Object> map){
        this.setData(map);
        return this;
    }
}

下载

前端:

表格中调整

 <el-table-column label="图片" width="130">
                <template scope="scope">
                    <el-link @click="down(scope.row.picture)" target="_blank">
                    <img :src="scope.row.picture" class="picture" />
                    </el-link>
                </template>
 </el-table-column>

down方法实现

   down(picture) {
      let pic = picture.substr(picture.lastIndexOf("/") + 1);
      window.location.href ="http://localhost:9000/sysuser/down?filename=" + pic;
    },

后台控制器

 @RequestMapping(value = "/down")
    public ResponseEntity<byte[]> download(HttpServletRequest request,
                                           @RequestParam("filename") String filename,
                                           Model model) throws Exception {
        //下载文件路径
        String path = request.getServletContext().getRealPath("/upload/");
        File file = new File(path + File.separator + filename);
        HttpHeaders headers = new HttpHeaders();
        //下载显示的文件名,解决中文名称乱码问题
        String downloadFielName = new String(filename.getBytes("UTF-8"), "iso-8859-1");
        //通知浏览器以attachment(下载方式)打开图片
        headers.setContentDispositionFormData("attachment", downloadFielName);
        //application/octet-stream : 二进制流数据(最常见的文件下载)。
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
                headers, HttpStatus.CREATED);
    }

导入依赖

 <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>

上传到阿里OSS

在 pom.xml 文件中添加 OSS 的依赖

<!-- 阿里云 OSS -->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>

在 application.yml 文件中添加 OSS 配置项

aliyun:
  oss:
    # oss对外服务的访问域名
    endpoint: oss-cn-hangzhou.aliyuncs.com
    # 访问身份验证中用到用户标识
    accessKeyId: LTAI5t8cnXRkg4yHdTEpKQht
    # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
    accessKeySecret: 8cbMn3hUGNjHmdf6UTqG0jwNXSkt1a
    # oss的存储空间
    bucketName: fengsir
    # 上传文件大小(M)
    maxSize: 3
  

OssUtil工具类

package com.wnxy.wateraffair.util;

/**
 * @author Mrz
 * @date 2022/8/29 13:37
 */


import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

/**
 * 阿里云OSS服务器工具类
 */
@Component
public class OssUtil {

    //---------变量----------
    protected static final Logger log = LoggerFactory.getLogger(OssUtil.class);

    @Value("${aliyun.oss.endpoint}")
    private String endpoint;
    @Value("${aliyun.oss.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.oss.accessKeySecret}")
    private String accessKeySecret;
    @Value("${aliyun.oss.bucketName}")
    private String bucketName;

    //文件存储目录
    private String filedir = "my_file/";

    /**
     * 1、单个文件上传
     * @param file
     * @return 返回完整URL地址
     */
    public String uploadFile(MultipartFile file) {
        String fileUrl = uploadImg2Oss(file);
        String str = getFileUrl(fileUrl);
        return str.trim();
    }

    /**
     * 1、单个文件上传(指定文件名(带后缀))
     * @param file
     * @return 返回完整URL地址
     */
    public String uploadFile(MultipartFile file,String fileName) {
        try {
            InputStream inputStream = file.getInputStream();
            this.uploadFile2OSS(inputStream, fileName);
            return fileName;
        }
        catch (Exception e) {
            return "上传失败";
        }
    }

    /**
     * 2、多文件上传
     * @param fileList
     * @return 返回完整URL,逗号分隔
     */
    public String uploadFile(List<MultipartFile> fileList) {
        String fileUrl = "";
        String str = "";
        String photoUrl = "";
        for(int i = 0;i< fileList.size();i++){
            fileUrl = uploadImg2Oss(fileList.get(i));
            str = getFileUrl(fileUrl);
            if(i == 0){
                photoUrl = str;
            }else {
                photoUrl += "," + str;
            }
        }
        return photoUrl.trim();
    }

    /**
     * 3、通过文件名获取文完整件路径
     * @param fileUrl
     * @return 完整URL路径
     */
    public String getFileUrl(String fileUrl) {
        if (fileUrl !=null && fileUrl.length()>0) {
            String[] split = fileUrl.split("/");
            String url = this.getUrl(this.filedir + split[split.length - 1]);
            return url;
        }
        return null;
    }

    //获取去掉参数的完整路径
    private String getShortUrl(String url) {
        String[] imgUrls = url.split("\\?");
        return imgUrls[0].trim();
    }

    // 获得url链接
    private String getUrl(String key) {
        // 设置URL过期时间为20年 3600l* 1000*24*365*20
        Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 20);
        // 生成URL
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
        if (url != null) {
            return getShortUrl(url.toString());
        }
        return null;
    }

    // 上传文件
    private String uploadImg2Oss(MultipartFile file) {
        //1、限制最大文件为20M
        if (file.getSize() > 1024 * 1024 *20) {
            return "图片太大";
        }

        String fileName = file.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf(".")).toLowerCase(); //文件后缀
        String uuid = UUID.randomUUID().toString();
        String name = uuid + suffix;

        try {
            InputStream inputStream = file.getInputStream();
            this.uploadFile2OSS(inputStream, name);
            return name;
        }
        catch (Exception e) {
            return "上传失败";
        }
    }


    // 上传文件(指定文件名)
    private String uploadFile2OSS(InputStream instream, String fileName) {
        String ret = "";
        try {
            //创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(instream.available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
            objectMetadata.setContentDisposition("inline;filename=" + fileName);
            //上传文件

            OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
            PutObjectResult putResult = ossClient.putObject(bucketName, filedir + fileName, instream, objectMetadata);
            ret = putResult.getETag();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } finally {
            try {
                if (instream != null) {
                    instream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    private static String getcontentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpeg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        //PDF
        if (FilenameExtension.equalsIgnoreCase(".pdf")) {
            return "application/pdf";
        }
        return "image/jpeg";
    }
}

控制器类:

 @Autowired
    private OssUtil ossUtil;//引入工具类
    @PostMapping("uploadoss")
    public Result fileUpload(@RequestParam("file") MultipartFile file) {
        try {
            String url = ossUtil.uploadFile(file); //调用OSS工具类
            System.out.println(url);
            return Result.ok(url);
        } catch (Exception e) {
            return  Result.error("上传失败");
        }
    }

上传控件路径修改

<el-col :span="12">
            <el-form-item label="用户头像">
              <el-upload
                ref="upload"
               
                :class="{disabled:uploadDisabled}"
                action="http://localhost:9000/sysuser/uploadoss"
                name="file"
                list-type="picture-card"
                :on-preview="handlePreview"
                :on-progress="onProgress"
                :on-remove="handleRemove"
                :on-success="handleSuccess"
                :before-upload="beforeUpload"
                :on-change="handleChange"
                :file-list="upload.fileList"
                accept=".jpeg,.jpg,.gif,.png"
                :limit="upload.limitCountImg"
              >
                <i class="el-icon-plus"></i>
              </el-upload>
              <!--预览图片-->
              <el-dialog
                :modal-append-to-body="false"
                :visible.sync="upload.imgVisible"
                width="30%"
              >
                <img
                  width="100%"
                  :src="upload.dialogImageUrl"
                  alt="图片未找到"
                />
              </el-dialog>
            </el-form-item>
          </el-col>
        </el-row>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值