Ajax请求+上传下载Demo
1.流程解析:
- 前端用<input tye="file">标签读取本地的文件对象;
- 前端用FormData()对象封装文件对象和其他信息,异步请求改成false,async=false;
- 后端通过Multipart对象接收文件对象;
- 后端创建存储文件夹——创建空文件对象——用transferTo把文件内容写入空文件对象中——获取文件路径写入数据库——上传完成——返回结果到前端
- 下载实现的原理主要是修改请求头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>