Springboot做文件上传和文件下载

10 篇文章 0 订阅

需求:

新建一个web工程
一、springboot完成,它有一个项目名 Project

准备一份upload.html

  1. 上传
    1.1 有一个文件上传表单,点击上传一个文件到服务器中,服务器将它存在一个文件夹中。
    1.2 上传失败,转发回到upload.html
    1.3 上传成功,重定向到download.html,并将需要下载的文件名传送过去

准备一份download.html
2. 下载
点击下载,将前面传送过来的文件又下载下来

注意,下载的文件名不是写死的,和刚才上传的文件名是同名的

一、项目目录截图

在这里插入图片描述

二、准备一个拦截器interceptor
package com.example.demo.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


public class FileInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        Object user = session.getAttribute("user");
        if (user != null){
            return true;//登录
        }
        return false;//游客
    }
}

三、一个mvc配置文件
package com.example.demo.config;

import com.example.demo.interceptor.FileInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

@Configuration/*让它成为配置文件 相当于springmvc.xml*/
public class MvcConfig implements WebMvcConfigurer {
    @Value("${fileupload.pathname}")
    private String path;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {/*注册 相当于<mvc:interceptors>标签*/
        InterceptorRegistration ir = registry.addInterceptor(new FileInterceptor());//相当于<mvc:interceptor bean标签
        ir.addPathPatterns("/**");//增加路径映射 要拦截的 相当于<mvc:mapping>标签
        ir.excludePathPatterns("/js/**","/img/**","/css/**","/login","/upload","/download","/xiazai");//放行的 相当于<mvc:exclude-mapping>标签
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        ResourceHandlerRegistration rhr = registry.addResourceHandler("/upload/**");
        rhr.addResourceLocations("file:" + path + "\\");//必须在前面加file:,保险起见,在后面加个\\
    }
}

四、一个下载工具类 DownloadUtil
package com.example.demo.util;

import sun.misc.BASE64Encoder;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * 下载工具类
 */
public class DownloadUtil {
    /**
     * 获取中文的编码(英文保持不变)
     * @param filename 原生的中文文件名
     * @param agent 来自请求的浏览器信息
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String filenameEncoding(String filename, String agent) throws UnsupportedEncodingException {
        // 根据不同的客户端进行不同的编码
        if (agent.contains("Firefox")) {
            // 火狐浏览器
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
        } else {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }
}

五、web层 FileController

我觉得难点就是如何获取上传的文件名进行下载,我这边用了不太好的一个方法,用了list去存取,声明在全局变量上,老师说可以用RESTFUL风格直接在路径上传文件名,但我没搞出来,先这样吧。

package com.example.demo.web;

import com.example.demo.util.DownloadUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

@Controller
public class FileController {
    private List list = new ArrayList();
    /*模拟登录*/
    @RequestMapping("/login")
    public String login(){
        return "upload";
    }

    @RequestMapping("/xiazai")
    public String xiazai(){
        return "download";
    }

    /*文件上传*/
    @RequestMapping("/upload")
    public String upload(Model model,MultipartFile pic,
                         @Value("${fileupload.pathname}") String path) throws IOException {
        if (!pic.isEmpty()){
            pic.transferTo(new File(path,pic.getOriginalFilename()));
            list.add(pic.getOriginalFilename());
            return "redirect:/xiazai";
        }else {
            model.addAttribute("tip","上传失败,请重新选择文件。");
            return "upload";
        }
    }

    /*文件下载*/
    @RequestMapping("/download")
    public void download( HttpServletResponse resp,
                           @RequestHeader("User-Agent") String userAgent,@Value("${fileupload.pathname}") String path) throws Exception {
        String filename = (String) list.get(list.size()-1);
        String filenameEncoding = DownloadUtil.filenameEncoding(filename, userAgent);
        resp.setHeader("Content-Disposition","attachment;filename="+filenameEncoding);
        InputStream is = new FileInputStream(path + "\\"+ filename);
        OutputStream os = resp.getOutputStream();
        byte[] buf = new byte[1024];
        int len = -1;
        while ((len = is.read(buf)) != -1){
            os.write(buf,0,len);
        }
        os.flush();
        os.close();
        is.close();
    }
}

DemoApplication和pom.xml是框架自动生成的,就不复制过来了。application.properties里加一句话:
fileupload.pathname=d:\upload
然后在D盘下再手动建一个upload的文件夹,用来存放上传的文件。

六、准备两个页面

download.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--文件下载-->
    <p>
        <a th:href="@{/download}">点我下载</a>
    </p>
</body>
</html>

upload.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>文件上传</h2>
    <hr>
    <form th:action="@{/upload}" method="post" enctype="multipart/form-data">
        <p>文件: <input type="file" name="pic"></p>
        <p><input type="submit" value="提交"></p>
    </form>
   <p style="color:red;" th:text="${tip}"></p>
</body>
</html>
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值