Spring 文件上传
获取文件流的方法,已经在专题的“(二)Spring- RestController 请求参数详解” 中说过了,大家可以去找之前的获取方式。 本篇主要讲的是文件上传的处理和保存。中间件使用的是tomcat。
1. 文件上传配置
文件上传需要增加一个依赖包
<!--flieupload-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3</version>
</dependency>
在spring 的配置文件中,配置图片处理的bin文件
<!-- 上传文件拦截,设置最大上传文件大小 10M=10*1024*1024(B)=10485760 bytes -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760" />
</bean>
2. 文件上传处理的方法
现在共有2个方法,大家还可以根据自己需求,把生成文件名的方法和生成缩略图大小的方法抽离出来,这里是示例,就不写那么复杂了。
- 1单文件上传
- 2单文件上传并自动生成缩略图
public class FilesService {
//文件相对Tomcat路径,相对tomcat设置,暂时弃用
//public static final String FILE_PATH = "../user_res/upload/plantAssistant/";
//文件相对网站路径
public static final String FILE_PATH = "WEB-INF/upload";
//单文件上传
public static FilesResp uploadFile(MultipartFile file, HttpServletRequest request) throws IOException {
//获取上传的路径
String realpath = request.getSession().getServletContext().getRealPath(FILE_PATH);
//获取文件名
String fileName = file.getOriginalFilename();
//上传文件
File tempFile = new File(realpath, new Date().getTime() + "_" + String.valueOf(fileName));
if (!tempFile.getParentFile().exists()) {
tempFile.getParentFile().mkdir();
}
if (!tempFile.exists()) {
tempFile.createNewFile();
}
file.transferTo(tempFile);
//处理返回值
FilesResp fileResp = new FilesResp(tempFile.getName(),getDomain(request));
return fileResp;
}
//单文件上传,并生成缩略图
public static FilesResp uploadFileAndThum(MultipartFile file, HttpServletRequest request) throws IOException{
String realpath = request.getSession().getServletContext().getRealPath(FILE_PATH);
//上传图片
FilesResp fileResp = uploadFile(file,request);
//生成缩略图
File srcImageFile = new File(realpath,fileResp.getFileName());
try {
makeSmallImage(srcImageFile,realpath + "/thum_"+fileResp.getFileName());
}catch (Exception e){
System.out.println("生成缩略图出错");
}
return new FilesResp(fileResp.getFileName(),"thum_"+fileResp.getFileName(),getDomain(request));
}
public static File getFile(String fileName,HttpServletRequest request) {
String realpath = request.getSession().getServletContext().getRealPath(FILE_PATH);
return new File(realpath, fileName);
}
/**
* 生成缩略图
* @param srcImageFile 源图片文件的File实例 File file = new File("文件名");
* @param dstImageFileName 待生成的缩略图片完整路径(生成的格式为:image/jpeg);
* @throws Exception
*/
public static void makeSmallImage(File srcImageFile,String dstImageFileName) throws Exception {
FileOutputStream fileOutputStream = null;
JPEGImageEncoder encoder = null;
BufferedImage tagImage = null;
Image srcImage = null;
try{
srcImage = ImageIO.read(srcImageFile);
int srcWidth = srcImage.getWidth(null);//原图片宽度
int srcHeight = srcImage.getHeight(null);//原图片高度
int dstMaxSize = 120;//目标缩略图的最大宽度/高度,宽度与高度将按比例缩写
int dstWidth = srcWidth;//缩略图宽度
int dstHeight = srcHeight;//缩略图高度
float scale = 0;
//计算缩略图的宽和高
if(srcWidth>dstMaxSize){
dstWidth = dstMaxSize;
scale = (float)srcWidth/(float)dstMaxSize;
dstHeight = Math.round((float)srcHeight/scale);
}
srcHeight = dstHeight;
if(srcHeight>dstMaxSize){
dstHeight = dstMaxSize;
scale = (float)srcHeight/(float)dstMaxSize;
dstWidth = Math.round((float)dstWidth/scale);
}
//生成缩略图
tagImage = new BufferedImage(dstWidth,dstHeight,BufferedImage.TYPE_INT_RGB);
tagImage.getGraphics().drawImage(srcImage,0,0,dstWidth,dstHeight,null);
fileOutputStream = new FileOutputStream(dstImageFileName);
encoder = JPEGCodec.createJPEGEncoder(fileOutputStream);
encoder.encode(tagImage);
fileOutputStream.close();
fileOutputStream = null;
}finally{
if(fileOutputStream!=null){
try{
fileOutputStream.close();
}catch(Exception e){
}
fileOutputStream = null;
}
encoder = null;
tagImage = null;
srcImage = null;
System.gc();
}
}
//获取域名
private static String getDomain(HttpServletRequest request){
StringBuffer url = request.getRequestURL();
return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
}
}
3方法的返回类型 FilesResp
这个类型是我自己写的,大家也可以不用他,自己去定义,既然例子中有,我就把返回类型贴出来,里面的返回值生成了各种常用的标签,因为后面想搭一个自己的图库
public class Resp {
public static Resp succeedResp(Object data){
Resp resp = new Resp();
resp.setStatus(1);
resp.setData(data);
resp.setMsg("返回成功");
return resp;
}
public static Resp succeedRespWithMsgAndData(String msg,Object data){
Resp resp = new Resp();
resp.setStatus(1);
resp.setData(data);
resp.setMsg(msg);
return resp;
}
public static Resp succeedRespWithMsg(String msg){
return succeedRespWithMsgAndData(msg,null);
}
public static Resp failureResp(String msg){
Resp resp = new Resp();
resp.setStatus(0);
resp.setMsg(msg);
return resp;
}
private int status;
private String msg;
protected Object data;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
package com.jumppo.plantassistant.dao.model.response;
import org.springframework.http.HttpRequest;
import javax.servlet.http.HttpServletRequest;
/**
* Created by zteliuyw on 15/7/13.
*/
public class FilesResp {
private String fileName;
private String downloadUrl;
private String previewUrl;
private String htmlTag;
private String aTag;
private String mdTag;
private String thum_fileName;
private String thum_downloadUrl;
private String thum_previewUrl;
private String thum_htmlTag;
private String thum_aTag;
private String thum_mdTag;
public FilesResp(String fileName){
this.fileName = fileName;
this.downloadUrl = "/files/download?fileName=" + fileName;
this.previewUrl = "/files/preview?fileName=" + fileName;
this.htmlTag = "<img src=\" "+ this.previewUrl +" \" />";
this.aTag = "<a href=\"图片超链接地址\"><img src=\" "+ this.previewUrl +" \" /><a>";
this.mdTag = "![图片文字:]("+ this.previewUrl + ")";
}
public FilesResp(String fileName,String domain){
this.fileName = fileName;
this.downloadUrl = domain + "/files/download?fileName=" + fileName;
this.previewUrl = domain + "/files/preview?fileName=" + fileName;
this.htmlTag = "<img src=' "+ this.previewUrl +" ' />";
this.aTag = "<a href='图片超链接地址'> <img src='"+ this.previewUrl +" ' /><a>";
this.mdTag = "![图片文字:]("+ this.previewUrl + ")";
}
public FilesResp(String fileName,String thumFileName,String domain){
this(fileName, domain);
this.thum_fileName = thumFileName;
this.thum_downloadUrl = domain + "/files/download?fileName=" + thumFileName;
this.thum_previewUrl = domain + "/files/preview?fileName=" + thumFileName;
this.thum_htmlTag = "<img src=' "+ this.thum_previewUrl +" ' />";
this.thum_aTag = "<a href='图片超链接地址'> <img src='"+ this.thum_previewUrl +" ' /><a>";
this.thum_mdTag = "![图片文字:]("+ this.thum_previewUrl + ")";
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getDownloadUrl() {
return downloadUrl;
}
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
public String getPreviewUrl() {
return previewUrl;
}
public void setPreviewUrl(String previewUrl) {
this.previewUrl = previewUrl;
}
public String getHtmlTag() {
return htmlTag;
}
public void setHtmlTag(String htmlTag) {
this.htmlTag = htmlTag;
}
public String getaTag() {
return aTag;
}
public void setaTag(String aTag) {
this.aTag = aTag;
}
public String getMdTag() {
return mdTag;
}
public void setMdTag(String mdTag) {
this.mdTag = mdTag;
}
public String getThum_fileName() {
return thum_fileName;
}
public void setThum_fileName(String thum_fileName) {
this.thum_fileName = thum_fileName;
}
public String getThum_downloadUrl() {
return thum_downloadUrl;
}
public void setThum_downloadUrl(String thum_downloadUrl) {
this.thum_downloadUrl = thum_downloadUrl;
}
public String getThum_previewUrl() {
return thum_previewUrl;
}
public void setThum_previewUrl(String thum_previewUrl) {
this.thum_previewUrl = thum_previewUrl;
}
public String getThum_htmlTag() {
return thum_htmlTag;
}
public void setThum_htmlTag(String thum_htmlTag) {
this.thum_htmlTag = thum_htmlTag;
}
public String getThum_aTag() {
return thum_aTag;
}
public void setThum_aTag(String thum_aTag) {
this.thum_aTag = thum_aTag;
}
public String getThum_mdTag() {
return thum_mdTag;
}
public void setThum_mdTag(String thum_mdTag) {
this.thum_mdTag = thum_mdTag;
}
}
4 最后是接受文件上传的控制器
有几点和大家说明下:
-
1:单个文件上传,路由参数这样写: @RequestParam(“file”) MultipartFile file,那么文件在表单中的name属性就必须是flie(不是文件名,是文件对应的name属性),这里是简单的写法,相当于 MultipartFile file = ((MultipartHttpServletRequest) request).getFile(“file”);
- 2:多个文件上传,参数@RequestParam(“files”) MultipartFile[] files
- 3:下载和预览,这两个方法其实只相差一个地方,response.setHeader(“Content-Disposition”, “attachment; filename=” + fileName);,这段话会通知浏览器以下载的方式处理流
@RestController
@RequestMapping("/files")
public class FliesController {
@RequestMapping("upload")
public Resp upload(HttpServletRequest request,
HttpServletResponse response, @RequestParam("file") MultipartFile file){
System.out.println("files/upload");
try {
//MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
FilesResp filesResp = FilesService.uploadFile(file, request);
return Resp.succeedResp(filesResp);
}
catch (Exception e){
e.printStackTrace();
}
return Resp.failureResp("图片上传失败");
}
@RequestMapping("uploadFileAndThum")
public Resp uploadFileAndThum(HttpServletRequest request,
HttpServletResponse response, @RequestParam("file") MultipartFile file){
System.out.println("files/upload");
try {
//MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
FilesResp filesResp = FilesService.uploadFileAndThum(file, request);
return Resp.succeedResp(filesResp);
}
catch (Exception e){
e.printStackTrace();
}
return Resp.failureResp("图片上传失败");
}
@RequestMapping("batchUpload")
public Resp batchUpload(HttpServletRequest request,
HttpServletResponse response,
@RequestParam("files") MultipartFile[] files) throws IOException {
List<FilesResp> list = new ArrayList<FilesResp>();
try {
for (MultipartFile file :files) {
FilesResp flesResp = FilesService.uploadFile(file, request);
list.add(flesResp);
// System.out.println("filePath:" + filePath);
}
return Resp.succeedResp(list);
}
catch (Exception e){
e.printStackTrace();
}
return Resp.failureResp("文件上传失败");
}
@RequestMapping("download")
public void download(String fileName, HttpServletResponse response,HttpServletRequest request) throws IOException {
OutputStream os = response.getOutputStream();
try {
response.reset();
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
response.setContentType("image/jpeg; charset=utf-8");
os.write(FileUtils.readFileToByteArray(FilesService.getFile(fileName,request)));
os.flush();
} finally {
if (os != null) {
os.close();
}
}
}
@RequestMapping("preview")
public void preview(String fileName, HttpServletResponse response,HttpServletRequest request) throws IOException {
OutputStream os = response.getOutputStream();
try {
response.reset();
// response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
response.setContentType("image/jpeg; charset=utf-8");
os.write(FileUtils.readFileToByteArray(FilesService.getFile(fileName,request)));
os.flush();
} finally {
if (os != null) {
os.close();
}
}
}
}
返回的json例子
{
"status": 1,
"msg": "返回成功",
"data": {
"fileName": "1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
"downloadUrl": "http://localhost:8070/files/download?fileName=1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
"previewUrl": "http://localhost:8070/files/preview?fileName=1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
"htmlTag": "<img src=' http://localhost:8070/files/preview?fileName=1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png ' />",
"aTag": "<a href='图片超链接地址'> <img src='http://localhost:8070/files/preview?fileName=1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png ' /><a>",
"mdTag": "![图片文字:](http://localhost:8070/files/preview?fileName=1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png)",
"thum_fileName": "thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
"thum_downloadUrl": "http://localhost:8070/files/download?fileName=thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
"thum_previewUrl": "http://localhost:8070/files/preview?fileName=thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png",
"thum_htmlTag": "<img src=' http://localhost:8070/files/preview?fileName=thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png ' />",
"thum_aTag": "<a href='图片超链接地址'> <img src='http://localhost:8070/files/preview?fileName=thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png ' /><a>",
"thum_mdTag": "![图片文字:](http://localhost:8070/files/preview?fileName=thum_1436776126050_EEFC7812-B34E-43B1-9DCE-1CA965EE20B0.png)"
}
}