`


前言

前后端涉及到文件的传输,都是以二进制流的形式进行交互的。


一、前端上传文件,Springboot接受并保存在某个路径

springboot内部封装了MultipartFile接口,用于接收和处理前端发送过来的文件。

1.引入库

代码如下(示例):

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

2.前端核心代码(发送文件)

代码如下(示例):

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="multipartfile" accept="image/png" value="请选择文件">
    <input type="submit" value="上传">
</form>

action属性指定了upload接口。由于get请求是将传输数据封装在URL里的,所以get请求无法传输二进制流的数据。故文件的请求方式method必须是post,因为需要http请求报文的数据体来封装文件数据。

编码方式enctype必须是“multipart/form-data”,指表单数据中由多部分构成,既有文本数据,又有文件等二进制数据。默认情况下,enctype的值是“application/x-www-form-urlencoded”,不能用于文件上传,只有使用了“multipart/form-data”,才能完整的传递文件数据。“application/x-www-form-urlencoded”不是不能上传文件,是只能上传文本格式的文件,multipart/form-data是将文件以二进制的形式上传,这样可以实现多种类型的文件上传。accept属性是用来指定文件类型的,属性值"image/png"表示只能上传.png图片的文件。


3.Controller类

代码如下(示例):

@RestController
public class uploadcontroller {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
    @PostMapping("/upload")
    public String upload(MultipartFile multipartfile, HttpServletRequest request){
        String realPath = request.getSession().getServletContext().getRealPath("/update/");
        String format=sdf.format(new Date());
        File folder=new File(realPath+format);
        if(!folder.isDirectory()){
            folder.mkdirs();
        }
        String oldname = multipartfile.getOriginalFilename();
        String newname = UUID.randomUUID().toString()+oldname.substring(oldname.lastIndexOf("."),oldname.length());
        try {
            multipartfile.transferTo(new File(folder, newname));
            System.out.println(new File(folder, newname).getAbsolutePath());//输出(上传文件)保存的绝对路径
            String filePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/update/"+format+newname;
            return filePath+"上传成功";
        }
        catch (IOException e){
            e.printStackTrace();
        }
        return "上传失败!";
    }
}

multipartfile封装了接受到的文件,multipartfile.getOriginalFilename()获取上传文件的完整名称,包括文件名和文件扩展名(如.png,.txt等指定文件类型的后缀);multipartfile.transferTo(new File(folder, newname))将接受文件下载到new File(folder, newname)对象指定的路径下。
request封装了http请求对象。request.getSession()获取一个http请求的session(会话);getServletContext()获取一个http请求对应的web应用上下文;getRealPath(“/update/”)获取一个相对(web应用上下文)地址为“/update/”的绝对地址。


4.注意事项

处理前端post请求的接口必须要用 @PostMapping注解,否则post请求无法访问成功!!!!


二、Springboot发送文件,前端接收并下载。

示例:MIME(Multipurpose Internet Mail Extensions)是一种多用途互联网邮件扩展。但不局限于邮件,适用于所有的浏览器能接受的文件。服务器会将它们发送的多媒体数据的类型告诉浏览器,而通知手段就是说明该多媒体数据的MIME类型,从而让浏览器知道接收到的信息哪些是MP3文件,哪些是Shockwave文件等等。服务器将MIME标志符放入传送的数据中来告诉浏览器使用哪种插件读取相关文件。
Springboot可通过(HttpServletResponse对象)response.setContentType(contenttype)设置发送到浏览器(前端)的响应内容的类型。
给浏览器(前端)的文件必须是以二进制流的形式发送的(在Java中要用io流对发送文件进行处理,以字节数组(byte[])的形式发送),因为只有以二进制的形式,才能处理文件中多类型的数据。

1.引入库

代码如下(示例):

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.io.IOException;

2.前端核心代码(发送文件)

代码如下(示例):

<a href="/load" download="file">下载文件</a>

href属性设置请求接口为"/load",download表明这是一个请求下载的链接,且下载到的文件会被自动改名为"file"。这种请求方式是get形式


3.Controller类

代码如下(示例):

@RestController
public class loadcontroller {
    @GetMapping("/load")
    public void fileload( HttpServletResponse response) throws IOException {
        File f = new File("C:\\Users\\Java\\Desktop\\新建 文本文档.txt");
        FileInputStream ips = new FileInputStream(f);
        OutputStream ops = response.getOutputStream();
        response.setContentType("application/octet-stream; charset=UTF-8");
        byte[] a = new byte[1000];
        ips.read(a);
        ops.write(a);
    }
}
//本代码在执行结束后并没有手动关闭对应的io流,读者可自行解决

通过response.getOutputStream()得到ServletOutputStream接口,ServletOutputStream是OutputStream的子接口。(HttpServletResponse)response的输出流对应的是http响应内容,通过response输出流的write方法就可以给http响应报文的数据体内写内容了,从而发送给对应的浏览器。
response.setContentType(“application/octet-stream;
charset=UTF-8”)设置响应内容的类型为二进制流(application/octet-stream),字符编码方式为UTF-8。


4.注意事项

凡是以一个UIR链接进行后端接口访问的请求方式都是get方式,对应的接口必须用 @GetMapping进行注解,表明该接口可以接受get请求。
凡是返回数据的Controller类都应该用@RestController标注,@Controller标注的Controller类是返回视图的。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐