SpringBoot的文件上传相对比较简单,文件信息都包含在MultipartFile对象中,只要从中获取文件信息即可
不煽情,直接上代码吧,这个部分出门右拐“百度一下”一大堆
/** * 单文件上传 * * @param name 携带的其他文本表单(可以省略) * @param file 文件内容 * @return */
@RequestMapping(value = "/upload_single", method = RequestMethod.POST)
public @ResponseBody String handleFileUpload(@RequestParam("name") String name,
@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
BufferedOutputStream out = null;
try {
byte[] bytes = file.getBytes();
out = new BufferedOutputStream(
new FileOutputStream(new File(BASE_PATH + "\\" + name + "-" + file.getOriginalFilename())));
out.write(bytes);
return "You successfully uploaded " + name + " into " + name + "-uploaded !";
} catch (Exception e) {
return "You failed to upload " + name + " => " + e.getMessage();
} finally {
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else {
return "You failed to upload " + name + " because the file was empty.";
}
}
测试:
单文件上传
多文件上传需要接收解析出MultipartHttpServletRequest对象中包含的文件信息
/** * 多文件上传,主要是使用了MultipartHttpServletRequest和MultipartFile * * @param name 携带的其他文本表单(可以省略) * @param request * @return */
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody String handleFileUpload(HttpServletRequest request,@RequestParam("name") String name) {
List files = ((MultipartHttpServletRequest) request).getFiles("file");
System.out.println("name==>"+name);
MultipartFile file = null;
BufferedOutputStream out = null;
for (int i = 0; i < files.size(); ++i) {
file = files.get(i);
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
out = new BufferedOutputStream(new FileOutputStream(new File(BASE_PATH + "\\" + file.getOriginalFilename())));
out.write(bytes);
} catch (Exception e) {
return "failed to upload " + i + " => " + e.getMessage();
} finally {
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
out = null;
}
}
} else {
return "failed to upload " + i + " because the file was empty.";
}
}
return "upload successful";
}
测试:
<p>多文件上传p>
<form method="POST" enctype="multipart/form-data" action="/upload">
Name: <input type="text" name="name"/>
<p>文件1:<input type="file" name="file" />p>
<p>文件2:<input type="file" name="file" />p>
<p><input type="submit" value="多文件上传" />p>
form>
相对于上传在文件下载的处理上,需要自己处理HttpServletResponse中流的返回,这里直接上一个有断点续传的代码:
@RequestMapping(value = "/download", method = RequestMethod.GET)
public void getDownload(String name, HttpServletRequest request, HttpServletResponse response) {
// Get your file stream from wherever.
String fullPath = "D:\\upload_test\\" + name;
File downloadFile = new File(fullPath);
ServletContext context = request.getServletContext();
// get MIME type of the file
String mimeType = context.getMimeType(fullPath);
if (mimeType == null) {
// set to binary type if MIME mapping not found
mimeType = "application/octet-stream";
}
// set content attributes for the response
response.setContentType(mimeType);
// response.setContentLength((int) downloadFile.length());
// set headers for the response
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
response.setHeader(headerKey, headerValue);
// 解析断点续传相关信息
response.setHeader("Accept-Ranges", "bytes");
long downloadSize = downloadFile.length();
long fromPos = 0, toPos = 0;
if (request.getHeader("Range") == null) {
response.setHeader("Content-Length", downloadSize + "");
} else {
// 若客户端传来Range,说明之前下载了一部分,设置206状态(SC_PARTIAL_CONTENT)
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
String range = request.getHeader("Range");
String bytes = range.replaceAll("bytes=", "");
String[] ary = bytes.split("-");
fromPos = Long.parseLong(ary[0]);
if (ary.length == 2) {
toPos = Long.parseLong(ary[1]);
}
int size;
if (toPos > fromPos) {
size = (int) (toPos - fromPos);
} else {
size = (int) (downloadSize - fromPos);
}
response.setHeader("Content-Length", size + "");
downloadSize = size;
}
// Copy the stream to the response's output stream.
RandomAccessFile in = null;
OutputStream out = null;
try {
in = new RandomAccessFile(downloadFile, "rw");
// 设置下载起始位置
if (fromPos > 0) {
in.seek(fromPos);
}
// 缓冲区大小
int bufLen = (int) (downloadSize < 2048 ? downloadSize : 2048);
byte[] buffer = new byte[bufLen];
int num;
int count = 0; // 当前写到客户端的大小
out = response.getOutputStream();
while ((num = in.read(buffer)) != -1) {
out.write(buffer, 0, num);
count += num;
//处理最后一段,计算不满缓冲区的大小
if (downloadSize - count < bufLen) {
bufLen = (int) (downloadSize-count);
if(bufLen==0){
break;
}
buffer = new byte[bufLen];
}
}
response.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
该部分本人直接在Android客户端上测试:
下载代码:
public static boolean downLoadFile(String url, int from, int to,String savePath) {
try {
URL link = new URL(url);
HttpURLConnection conn = (HttpURLConnection) link.openConnection();
// 设置断点续传的开始位置
if (to != 0) {
conn.setRequestProperty("Range", "bytes=" + from + "-" + to);
}else{
conn.setRequestProperty("Range", "bytes=" + from + "-");
}
Log.e("m_tag", "code:" + conn.getResponseCode());
if (conn.getResponseCode() == 206) {
RandomAccessFile file = new RandomAccessFile(savePath, "rw");
file.seek(from);
InputStream in = conn.getInputStream();
byte[] buffer = new byte[1024];
int num;
while ((num = in.read(buffer)) > 0) {
file.write(buffer, 0, num);
}
file.close();
in.close();
return true;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
Activity中运用:
class MyTask extends AsyncTask
以上的上传文件可以保存到服务器端的D:\upload_test但是对于这个路径,客户端如果想要使用一个相对路径来访问的话,需要做以下配置:
1、在application.properties中声明一个变量描述该地址
#图片上传存储路径
imagesPath=file:/D:/upload_test/
2、定义一个配置文件可以将该绝对路径映射到一个/images的相对路径上
package com.example.demo.config;
import org.apache.log4j.spi.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class FileConfig extends WebMvcConfigurerAdapter {
@Value("${imagesPath}")
private String mImagesPath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (mImagesPath.equals("") || mImagesPath.equals("${imagesPath}")) {
String imagesPath = FileConfig.class.getClassLoader().getResource("").getPath();
if (imagesPath.indexOf(".jar") > 0) {
imagesPath = imagesPath.substring(0, imagesPath.indexOf(".jar"));
} else if (imagesPath.indexOf("classes") > 0) {
imagesPath = "file:" + imagesPath.substring(0, imagesPath.indexOf("classes"));
}
imagesPath = imagesPath.substring(0, imagesPath.lastIndexOf("/")) + "/images/";
mImagesPath = imagesPath;
}
System.out.println("imagesPath=" + mImagesPath);
registry.addResourceHandler("/images/**").addResourceLocations(mImagesPath);
super.addResourceHandlers(registry);
}
}
这样之后对于服务器上D:\upload_test\1.jpg这个图片可以在客户端直接使用http://127.0.0.1:8080/images/1.jpg这个路径就可以访问了