SpringMVC的单文件上传,多文件上传和下载文件(十二)下

四. 多文件上传及多文件列表展示, 与对象关联的形式


springmvc 也同样支持多文件上传, 需要把 MultipartFile 单对象改成 数组形式 MultipartFile [] 或者是集合形式 List ,习惯用数组形式来接收。


当然,也用两种用法,一个是方法参数,另外一个就是与对象关联, 这里用对象关联的形式进行讲解,顺便把 文件的展示列表也给讲了。


四.一 重新定义 User.java 类的属性


将image 变成 images, 并设置成集合的形式。 imageFile 变成imageFiles, 并且成为数组的形式。


 //有多个上传图片的路径的属性
    private List<String> images ;
    //定义属性为imageFiles
    private MultipartFile [] imageFiles;


老蝴蝶在这儿省略了 setter和getter方法。


四.二 上传文件的 login.jsp 页面


将单文件变成多文件


<body>
    <h2>两个蝴蝶飞,文件上传使用</h2>
    <form:form commandName="user" action="login.action"  
    enctype="multipart/form-data" type="post">
        <form:label path="name">姓名:</form:label>
        <form:input path="name"/> <br/><br/>
        <!-- 可以使用js来动态设置,这里就指定为3个 -->
        <input type="file" name="imageFiles"> <br/><br/>
        <input type="file" name="imageFiles"> <br/><br/>
        <input type="file" name="imageFiles"> <br/><br/>
        
        <form:button>提交</form:button>
    </form:form>
</body>


四.三 展示文件的 list.jsp页面


要展示多个, 用c:forEach 标签


不要忘记添加 jstl的core标签


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>


页面展示:


<body>
    你好,${message}<br/>
    
    <c:forEach items="${user.images}" var="imgPath">
        <img src="${pageContext.request.contextPath}${imgPath}" width=100 height=100> <br/>
    </c:forEach>
    
</body>


四.四 后端UserAction 的处理


//转到登录的页面
    @RequestMapping(value="toLogin")
    public String toLogin(Model model){
        model.addAttribute("user",new User());
        return "user/login";
    }
    //绑定到user对象。
    @RequestMapping(value="login") 
    public String login(User user,Model model,HttpServletRequest request){
        
        String message="";
        MultipartFile[] files=user.getImageFiles();
        
        if(files!=null&&files.length>0){
            List<String> images=new ArrayList<String>();
            for(MultipartFile file:files){
                //进行单个文件的判断。
                if(file!=null&&!file.isEmpty()){  //不为空,即上传了文件
                    //1. 获取服务器的文件
                    String path=request.getServletContext().getRealPath("/upload");
                    //2. 获取上传的文件的名称
                    String fileName=file.getOriginalFilename();
                    //3. 实例化构建文件。
                    File filePath=new File(path,fileName);
                    //4.判断文件,如果父不存在的话,即upload文件夹不存在的话,就创建父级文件夹。
                    if(!filePath.getParentFile().exists()){
                        filePath.getParentFile().mkdirs(); 
                    }
                    try {
                        file.transferTo(new File(path+File.separator+fileName));
                        //设置图片的路径。
                        String imageName="/upload"+"/"+fileName;
                        images.add(imageName);
                        message="文件上传成功";
                    } catch (IllegalStateException e) {
                        // TODO 自动生成的 catch 块
                        e.printStackTrace();
                        message="文件上传失败";
                    } catch (IOException e) {
                        // TODO 自动生成的 catch 块
                        e.printStackTrace();
                        message="文件上传失败";
                    }
                }
                //for 遍历之后,再设置
                user.setImages(images);
            }
        }else{
            message="没有上传文件";
        }
        model.addAttribute("user",user);
        model.addAttribute("message",message);
        return "user/list";
    }


四.五 springmvc.xml 配置文件,不需要 改变


四.六 运行服务器,进行测试


上传提交:


SpringMVC的单文件上传,多文件上传和下载文件(十二)下


提交后,展示图片


SpringMVC的单文件上传,多文件上传和下载文件(十二)下


Tomcat服务器 路径显示:


SpringMVC的单文件上传,多文件上传和下载文件(十二)下


多文件上传成功。


五. 下载文件


众所皆知, 链接到正确的位置,可以进行下载。 下面,用a 链接看看。


五.一 a 链接显示


将多文件列表那个 list.jsp 的显示图片 <img> ,改成 <a> 链接的话,看看效果怎么样。


<body>
    你好,${message}<br/>
    <ul style="list-style: none;">
    <c:forEach items="${user.images}" var="imgPath">
        <%-- <img src="${pageContext.request.contextPath}${imgPath}" width=100 height=100> <br/> --%>
        <li>
            <a href="${pageContext.request.contextPath}${imgPath}">${imgPath}</a>
        </li>
    </c:forEach>
    </ul>
</body>


刷新后展示为:


SpringMVC的单文件上传,多文件上传和下载文件(十二)下


点击链接,发现会进行查看,并不会下载。


SpringMVC的单文件上传,多文件上传和下载文件(十二)下


用JS 强行下载呢?


五.二 JS 强制 a链接下载


将上面 的 list.jsp 继续优化,改成,用js事件来进行下载。


<body>
    你好,${message}<br/>
    <ul style="list-style: none;">
    <c:forEach items="${user.images}" var="imgPath">
        <%-- <img src="${pageContext.request.contextPath}${imgPath}" width=100 height=100> <br/> --%>
        <li>
            <a href="javascript:void(0);" onclick="openDownloadDialog('${pageContext.request.contextPath}${imgPath}')">${imgPath}</a>
        </li>
    </c:forEach>
    </ul>
    
<script>
function openDownloadDialog(url){
    var first = "" , last = "" , name = "" , houZhui = "";
    first = url.lastIndexOf("/");//最后一个/的位置
    last = url.lastIndexOf(".");//最后一个.的位置
    name = url.substr(first+1,last-first-1);//照片名称
    houZhui = url.substr(url.lastIndexOf("."));//后缀
    var aLink = document.createElement('a');//创建一个虚拟的a标签
    aLink.href = url;//这只a标签的url
    aLink.download = name + houZhui; // 指定保存文件名,可以不要后缀
    var event;
    event = document.createEvent('MouseEvents');//创建一个新的MouseEvent对象
    event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    aLink.dispatchEvent(event);
}
</script>
</body>


刷新页面,当点击链接之后,会弹出下载对话框,可以进行下载。


SpringMVC的单文件上传,多文件上传和下载文件(十二)下


当这上面,只是js的前端下载, 还需要学习后端的下载。


五.三 服务器后端下载


在UserAction 中添加一个download() 下载的方法,传入的是文件的路径 (也可以传入文件的名称),进行操作


    @RequestMapping(value="download")
    public ResponseEntity<byte[]> download(HttpServletRequest request,
            @RequestParam(value="filePath") String fileName) throws UnsupportedEncodingException,
    IOException{
        //1 获取项目路径
        String contextPath=request.getServletContext().getRealPath("/");
        System.out.println("输出name:"+fileName);
        // 2 拼接下载的文件的路径 
        File file=new File(contextPath+fileName);
        System.out.println("输出文件路径:"+file.toString());
        //3 将下载的名称,进行格式转换
        String downFileName=new String(fileName.getBytes("utf-8"),"ISO-8859-1");    
        //4 设置浏览器头部信息,可以下载的设置,设置中文编码,避免出现中文不能下载的情况。
        HttpHeaders headers=new HttpHeaders();
        headers.setContentDispositionFormData("attachment", downFileName);
        //常见的格式,application/oct_stream
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
                    headers,HttpStatus.CREATED);
    }


在前端 重写 list.jsp, a链接的href提交到后端。


<ul style="list-style: none;">
    <c:forEach items="${user.images}" var="imgPath">
        <li>
            <a href="download.action?filePath=${imgPath}">${imgPath}</a>
        </li>
    </c:forEach>
    </ul>


重启服务器,进行验证。


SpringMVC的单文件上传,多文件上传和下载文件(十二)下


谢谢!!!


上一篇:SpringMVC的单文件上传,多文件上传和下载文件(十二)上


下一篇:【李宏毅2020 ML/DL】P79 Generative Adversarial Network | Tips for improving GAN