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

springMVC文件上传和下载

程序员文章站 2022-06-02 14:39:00
...

首先要加Apache-Commons中的fileupload的jar包(不用自己去写流之类的)

先把前端jsp页面写好

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <%@include file="commons/commons.jsp"%>
    <title>Title</title>
</head>
<body>
    <form method="post" enctype="multipart/form-data" action="upload">
        <p><input type="file" name="myPic"></p>
        <p><input type="submit" value="提交"></p>
    </form>
</body>
</html>

注意,这里引用了commons.jsp,所以在这个jsp里面,我们只要写相对路径即可(action="upload")

此外,所有上传文件的表单都要把在form中的enctype属性设置成  multipart/fore-data(改变编码格式)把表单变成二进制流


然后再在spingMVC.xml上加上文件上传解析器(即装配MultipartResolver,默认情况下,springMVC上下文中没有转配MultipartResolver。如果要使用spring的文件上传功能,需要先进行配置)

	<!--配置文件上传解析器-->
	<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
		<property name="maxUploadSize" value="5242880"/>
	</bean>

注意,这里的id都是用它默认的名字,multipartResolver这个名字是已经规定好的


接着就写FileController了

package com.newer.controller;

@Controller
public class FileController {


    //文件
    @RequestMapping("/upload")
    public String upload(MultipartFile myPic, HttpSession session) throws IOException {  //通过文件解析器拿到MultipartFile(就是上传临时的文件),mypic就是表单中的名字(入参就是文件引用)
        //获取images文件夹在服务器的绝对路径
        String path=session.getServletContext().getRealPath("images");//注意,images不能是空文件夹,因为idea部署的时候不会部署空文件夹
        //拿文件原始名字(上传时的名字)
        String fileName=myPic.getOriginalFilename();
        File file=new File(path,fileName);
        //另存临时文件到指定路径
        myPic.transferTo(file);   //会有异常,抛出去
        session.setAttribute("fileName",fileName); //为了文件下载,所以存session方便等下拿
        return  "suc";
    }



    @RequestMapping("/download") //绕过了视图解释器//ResponseEntity<byte[]>响应的结果是字节流
    public ResponseEntity<byte[]> download(String fileName,HttpSession session) throws IOException {  //响应实体的类型为二进制流(把要下载的文件转成二进制流)
        //获取images文件夹在服务器的绝对路径
        String path=session.getServletContext().getRealPath("images");
        //要下载的文件
        File file=new File(path,fileName);

        //把文件转成响应式流,然后送到响应对象里面去,作为下载的话,响应对象还要在header里规定一些东西
        //比如它是响应式流,到达浏览器后不是直接被解析出来,而是告诉浏览器这是附加,然后浏览器就会弹出另存为下载框等等
        //响应头部数据对象
        HttpHeaders httpHeaders=new HttpHeaders();
        //设置内容类型--定义响应类内容类型为流
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        //告诉浏览器这个流以附件的形式传过来保存(不然就在浏览器中直接打开了)
        httpHeaders.setContentDispositionFormData("attachment",fileName);

        //Commons中的文件工具类FileUtil,直接把file读成二进制数组读给响应的实体
        //字节数组,响应头部,HttpStatus的状态码
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),httpHeaders, HttpStatus.OK);
    }
}


然后controller回跳到suc.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <%@include file="commons/commons.jsp"%>
    <title>Title</title>
</head>
<body>
    <h2>上传成功</h2>   
    <img src="images/${fileName}"><br>  <%--src是相对路径--%>
    <h4><a href="download?fileName=${fileName}">点击下载</a></h4>
</body>
</html>

接下来,我们看下下载,点击suc.jsp中的“点击下载”,然后它就跳到FileController层中的dowload中了,详情请看上面FileController中的注解

注意,下载时,谷歌下载时不会跳出另存为,火狐可以,这和浏览器有关



---------------------------------------------------------------------------------------------------------------------------------

值得注意的是,在上文中的文件上传部分,因为是二进制流上传,所以如果表单有其他数据,怎controller层则无法得到,所以我们才用url重写的方式把其他数据带到后台controller层,见下图

springMVC文件上传和下载



springMVC文件上传和下载