Ajax请求+上传下载Demo

1.流程解析:

  1. 前端用<input tye="file">标签读取本地的文件对象;
  2. 前端用FormData()对象封装文件对象和其他信息,异步请求改成false,async=false;
  3. 后端通过Multipart对象接收文件对象;
  4. 后端创建存储文件夹——创建空文件对象——用transferTo把文件内容写入空文件对象中——获取文件路径写入数据库——上传完成——返回结果到前端
  5. 下载实现的原理主要是修改请求头setHeader使浏览器弹出下载框,实现下载功能。

2.前端(html+jquery):

<!DOCTYPE html>
<html>
  <head>
    <title>post.html</title>
    
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html; charset=UTF-8">
    <script type="text/javascript" src="jquery.min.js"></script>
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
    <form action="/ssm/study/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file" id = "file" required="required"><br>
        user:<input type="text" name="user" id = "user" value = "liguochao"><br>
        <input type="button" value="send" onclick = "send()"><br>
    </form>
    <div id="lists">
        
    </div>
  </body>
  <script type="text/javascript">
 /* 上传 */
      function send(){    
          var file = $("#file")[0].files[0];//获取文件
          console.log("file:"+file);
          var user = $("#user");//获取user信息
        var formData = new FormData();
        formData.append("file", file);
        formData.append("user",user);
         $.ajax({
                type:"post",
                async: false,                                    
                processData : false, // 使数据不做处理
                contentType : false, // 不要设置Content-Type请求头
                url: "/ssm/study/upload",
                data:formData,
                dataType:"json",
                success: function(result){
                    var files = result;
                       document.getElementById("lists").innerHTML = null;
                       for (var i = 0; i < files.length; i++) {
                        var name = files[i].name;//文件名
                        var path = files[i].path;//文件路径
                           var html = "<p>"+(i+1)+"-<a href='#' onclick='downloadFile(\""+path+"\")'>"+name+"</a></p>";
                           $("#lists").append(html);
                    }
               }
            });
           }
  
/* 下载 */
    function downloadFile(path){
        path = path.replace("#", "%23");
        name = name.replace("#", "%23");
        var uri = "/ssm/study/download?path=" + encodeURIComponent(path) + "&name=" + encodeURIComponent(name);
        var w = window.open("", "_self");
        w.location.href = uri;
    }
  </script>
</html>

3.后端(springMVC)

package com.study.controller;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

@Controller
@RequestMapping("study")
public class UploadController {
    /**上传
     * @param file 文件对象
     * @param user 用户名
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("upload")
    public List<Map<String,Object>> upload(@RequestParam("file") MultipartFile file,@RequestParam("user") String user) throws IOException,FileNotFoundException {
        System.out.println("上传文件,user:"+user+"getContentType"+file.getContentType()+"getName:"+file.getName()+"getOriginalFilename:"+file.getOriginalFilename());
        System.out.println("getSize:"+file.getSize()+"getBytes:"+file.getBytes()+"getInputStream:"+file.getInputStream()+"isEmpty:"+file.isEmpty());
        Integer result = 0;
        if (file.isEmpty()) {return null;}
        /* 创建父文件夹 */
        String folder = "D:/files";
        File parent = new File(folder);
        if (!parent.exists()) {
            parent.mkdirs();
        }
        /* 创建文件 */
        File tempFile = new File(parent,user+"-"+new Date().getTime()+"-"+file.getOriginalFilename());
        System.out.println(tempFile.getAbsolutePath());
        tempFile.createNewFile();
        file.transferTo(tempFile.getAbsoluteFile());
        /* 查找文件夹列表 */
        List<Map<String, Object>> files = new ArrayList<Map<String, Object>>();
        Map<String, Object> map;
        String[] fileNames = parent.list();
        for (int i = 0; i < fileNames.length; i++) {
            String name = fileNames[i].substring(fileNames[i].indexOf("-")+1); 
            map = new HashMap<String, Object>();
            map.put("name",name);
            map.put("path","D:/files"+"/"+fileNames[i]);
            files.add(map);
        }
        return files;
    }
    
    /**下载
     * @param request
     * @param response
     * @throws IOException 
     */
    @RequestMapping("download")
    public void download(HttpServletRequest request,HttpServletResponse response) throws IOException {
        String path = java.net.URLDecoder.decode(request.getParameter("path"),"utf-8");
        String name = java.net.URLDecoder.decode(request.getParameter("name"),"utf-8");
        System.out.println("path:"+path);System.out.println("name:"+name);
        /* 过滤文件格式 */
        String tname = path;
        System.out.println("tname:"+tname);
        String name_hz = tname.substring(tname.lastIndexOf("."));
        if (name_hz.equals(".xls") || !name_hz.equals(".xls")) {}
        /* 查找服务器文件路径,创建对象 */
        File serverfile = new File(path);
        /* 判断是否为能供下载的文件夹路径下的文件 */
        /* 该步是最关键的一步,使用setHeader()方法弹出"是否要保存"的对话框,打引号的部分都是固定的值,不要改变 */
        response.setHeader ("Content-disposition", "attachment;filename=" + new String (tname.getBytes ("gb2312"), "ISO8859-1"));
        /* 设置返回的文件格式,可有可无 */
//        if(path.endsWith("xls")||path.endsWith("xlsx"))response.setContentType ("application/vnd.ms-excel");
//        else if(path.endsWith("ppt")||path.endsWith("pptx"))response.setContentType ("application/vnd.ms-powerpoint");
//        else response.setContentType ("application/msword");
        /* 定义下载文件的长度 /字节 */
        long fileLength = serverfile.length ();
        String length = String.valueOf (fileLength);
        /* 设置文件长度(如果是Post请求,则这步不可少) */
        response.setHeader ("content_Length", length);
        /* 获得一个 ServletOutputStream(向客户端发送二进制数据的输出流)对象 */
        OutputStream servletOutPutStream = response.getOutputStream ();
        /* 获得一个从服务器上的文件myFile中获得输入字节的输入流对象 */
        FileInputStream fileInputStream = new FileInputStream (serverfile);
        /* 设置缓冲区为1024个字节,即1KB */
        byte bytes[] = new byte[1024];
        int len = 0;
        /* 读取数据。返回值为读入缓冲区的字节总数,如果到达文件末尾,则返回-1 */
        while ((len = fileInputStream.read (bytes)) != -1) {
            // 将指定 byte数组中从下标 0 开始的 len个字节写入此文件输出流,(即读了多少就写入多少)
            servletOutPutStream.write (bytes, 0, len);
        }
        /* 关闭输出流,输入流 */
        servletOutPutStream.close ();
        fileInputStream.close ();
    }
}

4.xml配置(配置上传文件的大小限制)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
    <context:annotation-config/>

    <context:component-scan base-package="com.how2java.controller">
          <context:include-filter type="annotation" 
          expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <mvc:annotation-driven >
       <mvc:message-converters register-defaults="true">
          <bean class="org.springframework.http.converter.StringHttpMessageConverter">
             <property name="supportedMediaTypes" value="text/plain;charset=UTF-8" />
          </bean>
       </mvc:message-converters>    
    </mvc:annotation-driven>
    
    <mvc:default-servlet-handler />


    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
       <!--  <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" /> -->
    </bean>
    
        <!-- 定义文件上传解析器 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设定默认编码 -->
        <property name="defaultEncoding" value="UTF-8"></property>
        <!-- 设定文件上传的最大值5MB,50*1024*1024 -->
        <property name="maxUploadSize" value="52428800"></property>
    </bean>
</beans>

 

posted @ 2019-11-04 09:53  情怀诗意  阅读(737)  评论(0编辑  收藏  举报