41、Springboot 文件上传 采用Base64方式
引入依赖
<dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.6</version>
</dependency>
<dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.8</version>
</dependency>
<dependency><groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId><version>2.4</version><classifier>jdk15</classifier>
</dependency>
创建 Base64 工具类
package com.lill.test.utils;import org.apache.commons.net.util.Base64;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import java.io.*;public class BaseUtils {static BASE64Encoder encoder = new sun.misc.BASE64Encoder();static BASE64Decoder decoder = new sun.misc.BASE64Decoder();/*** 得到Base64 字符串*/public static String getBase64String(File file) {FileInputStream fin = null;BufferedInputStream bin = null;ByteArrayOutputStream baos = null;BufferedOutputStream bout = null;try {// 建立读取文件的文件输出流fin = new FileInputStream(file);// 在文件输出流上安装节点流(更大效率读取)bin = new BufferedInputStream(fin);// 创建一个新的 byte 数组输出流,它具有指定大小的缓冲区容量baos = new ByteArrayOutputStream();// 创建一个新的缓冲输出流,以将数据写入指定的底层输出流bout = new BufferedOutputStream(baos);byte[] buffer = new byte[1024];int len = bin.read(buffer);while (len != -1) {bout.write(buffer, 0, len);len = bin.read(buffer);}// 刷新此输出流并强制写出所有缓冲的输出字节,必须这行代码,否则有可能有问题bout.flush();byte[] bytes = baos.toByteArray();return Base64.encodeBase64String(bytes).trim();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {fin.close();bin.close();// 关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException// IOException// baos.close();bout.close();} catch (IOException e) {e.printStackTrace();}}return null;}/*** 将base64编码转换成文件*/public static void base64StringToFile(String base64sString, String fileFullName) {BufferedInputStream bin = null;FileOutputStream fout = null;BufferedOutputStream bout = null;try {// 将base64编码的字符串解码成字节数组byte[] bytes = decoder.decodeBuffer(base64sString);// 创建一个将bytes作为其缓冲区的ByteArrayInputStream对象ByteArrayInputStream bais = new ByteArrayInputStream(bytes);// 创建从底层输入流中读取数据的缓冲输入流对象bin = new BufferedInputStream(bais);// 指定输出的文件File file = new File(fileFullName);// 创建到指定文件的输出流fout = new FileOutputStream(file);// 为文件输出流对接缓冲输出流对象bout = new BufferedOutputStream(fout);byte[] buffers = new byte[1024];int len = bin.read(buffers);while (len != -1) {bout.write(buffers, 0, len);len = bin.read(buffers);}// 刷新此输出流并强制写出所有缓冲的输出字节,必须这行代码,否则有可能有问题bout.flush();} catch (IOException e) {e.printStackTrace();} finally {try {bin.close();fout.close();bout.close();} catch (IOException e) {e.printStackTrace();}}}public static InputStream base64StrToInputStream(String base64string) {ByteArrayInputStream stream = null;try {BASE64Decoder decoder = new BASE64Decoder();byte[] bytes1 = decoder.decodeBuffer(base64string);stream = new ByteArrayInputStream(bytes1);} catch (Exception e) {e.printStackTrace();}return stream;}
}
解除上传文件大小限制,在application.yml文件中做下简单配置
spring: http: multipart: max-file-size: 512MBmax-request-size: 4096MB
upload:image:url: D:/fileUpload/images/file:url: D:/fileUpload/files/
由于开发的是测试案例,所以大小给的随意了一些,具体请参照自身业务需要设定,另外,如果实际运行过程中,还会存在大小限制而无法上传的问题,请看下Tomcat或者Nginx配置,这也是我遇到过的情况,
Tomcat下文件上传大小,默认为2M(2097152),需要对server.xml做下修改
<Connector port="8080"maxThreads="150" minSpareThreads="25" maxSpareThreads="75"enableLookups="false" redirectPort="8443" acceptCount="100"debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK"maxPostSize="209715200"/>
Nginx下文件上传大小,需要对nginx.conf做下修改
http{……client_max_body_size 200M;……
}
设置完大小限制之后,都要重新启动下,使其生效
创建上传ImageController类
package com.lill.test.controller;import com.lill.test.common.Const;
import com.lill.test.dao.IFileParameterRepository;
import com.lill.test.entity.FileParameter;
import com.lill.test.threads.DelService;
import com.lill.test.threads.FtpService;
import com.lill.test.utils.*;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.Date;@Controller
@RequestMapping("/image")
@CrossOrigin(origins = "*", maxAge = 3600)
public class ImageController {// 图片上传存储的路径@Value("${upload.image.url}")private String imageDir;@Value("${upload.file.url}")private String fileDir;private Logger logger = LoggerFactory.getLogger(ImageController.class);/*** FTP 相关配置*/@Value("${ftp.username}")private String userName;@Value("${ftp.password}")private String passWord;@Value("${ftp.host}")private String ip;@Value("${ftp.port}")private int port;@Value("${ftp.filepath}")private String CURRENT_DIR;@PostMapping(value = "/uploadImageForBase64")@ResponseBodypublic JsonResult uploadImageForBase64(@RequestParam(value = "type", required = true) String type,@RequestParam(value = "fileBase", required = true) String fileBase,@RequestParam(value = "delPath", required = false, defaultValue = "") String delPath,HttpServletRequest request,HttpServletResponse response) throws FileNotFoundException {if(StringUtils.isBlank(fileBase)){return JsonResult.customize(Const.ERROR_CODE, "请先选择一张图片上传", null);}try {// 执行删除程序DelService delTask = new DelService(ip, port, userName, passWord, delPath);Thread d = new Thread(delTask);d.start();}catch (Exception e){}String ext = ".png";String fileName = GuidUtils.toLower();// 创建目录String relativePath = type.concat(Const.SPER).concat(DateUtils.getDate(new Date(), "yyyy/MM/dd"));File dir = new File(imageDir.concat(Const.SPER)+ relativePath);if(!dir.exists()){dir.mkdirs();}String newFileBase = "";if(fileBase.indexOf(",")>1) {newFileBase = fileBase.substring(fileBase.indexOf(",") + 1);}else{newFileBase = fileBase;}// 生产原图String normal = dir.getPath().concat(Const.SPER).concat(fileName).concat(ext);BaseUtils.base64StringToFile(newFileBase, normal);File file = new File(normal);// 生产中图String middle = dir.getPath().concat(Const.SPER).concat(fileName).concat(Const.IMG_MIDDLE).concat(ext);// 生产缩略图String thumb = dir.getPath().concat(Const.SPER).concat(fileName).concat(Const.IMG_THUMB).concat(ext);Runnable ftpTask = new FtpService(file, dir.getPath(), relativePath, fileName, ext,ip, port, userName, passWord);Thread t = new Thread(ftpTask);t.start();return JsonResult.ok("文件上传成功", entity);}private boolean isPic(String ext) {String _ext = ext.trim().toLowerCase();if(_ext.equals(".png")||_ext.equals(".jpeg")||_ext.equals(".jpg")||_ext.equals(".bmp")){return true;}else{return false;}}@GetMapping("/showImage")public void showImage(@RequestParam(value = "filePath", required = true) String filePath,HttpServletResponse response){try {showFtpImage(ip, port, userName, passWord, filePath, response);} catch (Exception e) {e.printStackTrace();}}@PostMapping("/deleteFileByPath")@ResponseBodypublic JsonResult deleteFileByPath(@RequestParam(value = "filePath", required = true) String filePath){delFtpImage(ip, port, userName, passWord, filePath);return JsonResult.ok("图片删除成功", null);}private void uploadFileToFtp(String ip, int port, String userName, String passWord, File file, String fileName, boolean needDelete, String relativePath){try {FtpUtils ftpUtils = FtpUtils.getInstance();ftpUtils.getFTPClient(ip, port, userName, passWord);ftpUtils.uploadToFtp(new FileInputStream(file), fileName, needDelete, relativePath);} catch (Exception e) {}}private void showFtpImage(String ip, int port, String userName, String passWord, String filePath, HttpServletResponse response){try {FtpUtils ftpUtils = FtpUtils.getInstance();FTPClient ftpClient = ftpUtils.getFTPClient(ip, port, userName, passWord);ftpClient.retrieveFile(filePath, response.getOutputStream());} catch (Exception e) {}}private void delFtpImage(String ip, int port, String userName, String passWord, String filePath){try {FtpUtils ftpUtils = FtpUtils.getInstance();FTPClient ftpClient = ftpUtils.getFTPClient(ip, port, userName, passWord);ftpClient.deleteFile(filePath);} catch (Exception e) {}}}
上面类中分别引用了工具类 JsonResult、FtpUtils、DateUtils, 请看后面内容,会逐个描述出来
创建JsonResult工具类
package com.lill.test.utils;import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.lill.test.common.Const;import java.io.Serializable;@JsonInclude(JsonInclude.Include.ALWAYS)
public class JsonResult implements Serializable {private String code;private String message;private Object data;private JsonResult(){}private static JsonResult buildJsonResult(String code, String message, Object data){JsonResult result = new JsonResult();result.setCode(code);result.setMessage(message);result.setData(data);return result;}public static JsonResult ok(){return buildJsonResult("10000", "请求成功", null);}public static JsonResult ok(Object data){return buildJsonResult("10000", "请求成功", data);}public static JsonResult ok(String message, Object data){return buildJsonResult("10000", message, data);}public static JsonResult customize(String code, String message, Object data){return buildJsonResult(code, message, data);}public static JsonResult error(){return buildJsonResult(Const.ERROR_CODE, "请求失败", null);}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}}
创建Const公共属性类
package com.lill.test.common;public class Const {/*** 失败业务CODE*/public final static String ERROR_CODE = "10001";/*** 统一异常CODE*/public final static String WARN_CODE = "10002";/*** 图片(中图)标记*/public final static String IMG_MIDDLE = "_middle";/*** 图片(缩略图)标记*/public final static String IMG_THUMB = "_thumb";/*** 目录分隔符*/public final static String SPER = "/";}
创建DateUtils工具类
package com.lill.test.utils;import org.apache.commons.lang.StringUtils;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.TimeZone;public class DateUtils {private static TimeZone shanghaiZone = TimeZone.getTimeZone("Asia/Shanghai");public static String getDate(){Calendar cal = Calendar.getInstance(shanghaiZone);return cal.get(Calendar.YEAR) + "/" + (cal.get(Calendar.MONTH) +1) + "/" + cal.get(Calendar.DATE);}public static String getLongDateString(){SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");String longdate = sdf.format(new Date());return longdate;}public static String random(long len) throws Exception {String[] arr = new String[]{"0","1","2","3","4","5","6","7","8","9"};if(len<=0){throw new Exception("长度有误");}String suffix = "";for (int i=0; i<len; i++){Random r = new Random();int index = r.nextInt(10);if(index == 10) {index = 0;}suffix += arr[index];}return suffix;}public static Date getDate(String datestr) {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");Date date = null;try {date = sdf.parse(datestr);} catch (ParseException e) {e.printStackTrace();}return date;}public static Date getDate(String datestr, String pattern) {if(StringUtils.isBlank(pattern)){pattern = "yyyy-MM-dd";}SimpleDateFormat sdf = new SimpleDateFormat(pattern);Date date = null;try {date = sdf.parse(datestr);} catch (ParseException e) {e.printStackTrace();}return date;}/*** 获取过期时间,年月日* @param curr 基点日期* @param expire 过期间隔* @param type 0、日 1、月 2、年* @return*/public static Date calExpireDate(Date curr, int expire, int type) throws Exception {if(expire>0) {Calendar c = Calendar.getInstance();c.setTime(curr);if (type == 1) {c.add(Calendar.MONTH, expire);} else if (type == 2) {c.add(Calendar.YEAR, expire);} else {c.add(Calendar.DATE, expire);}return c.getTime();}else{throw new Exception("过期间隔必须大于零");}}public static Date getDateTime(String datestr, String pattern) {if(StringUtils.isBlank(pattern)){pattern = "yyyy-MM-dd HH:mm:ss";}return getDate(datestr.replace(".0", ""), pattern);}public static String getDateTime(Date date, String pattern){if(StringUtils.isBlank(pattern)){pattern = "yyyy-MM-dd HH:mm:ss";}SimpleDateFormat sdf = new SimpleDateFormat(pattern);return sdf.format(date);}public static String getDate(Date date, String pattern){if(StringUtils.isBlank(pattern)){pattern = "yyyy-MM-dd";}return getDateTime(date, pattern);}
}
创建FtpUtils工具类
package com.lill.test.utils;import com.lill.test.common.Const;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;public class FtpUtils {private Logger logger = LoggerFactory.getLogger(FtpUtils.class);private static FtpUtils instance = null;private FtpUtils(){}public static FtpUtils getInstance(){instance = new FtpUtils();return instance;}// ftp客户端private FTPClient ftpClient = null;/*** 获取 Ftp连接对象* @param ip IP 地址* @param port 端口号* @param userName 账户* @param passWord 密码* @return* @throws IOException*/public FTPClient getFTPClient(String ip, int port, String userName, String passWord) throws IOException {if (ftpClient==null) {int reply;try {ftpClient=new FTPClient();ftpClient.connect(ip,port);ftpClient.login(userName,passWord);reply = ftpClient.getReplyCode();if (!FTPReply.isPositiveCompletion(reply)) {ftpClient.disconnect();}return ftpClient;}catch(Exception ex){throw ex;}}return null;}/*** 带点的* @param fileName* @return*/public static String getExtention(String fileName) {int pos = fileName.lastIndexOf(".");return fileName.substring(pos);}/*** 不带点* @param fileName* @return*/public static String getNoPointExtention(String fileName) {int pos = fileName.lastIndexOf(".");return fileName.substring(pos +1);}/**** 功能:根据当前时间获取文件目录* @return String*/public static String getDateDir(Date dateParam){SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");return sdf.format(dateParam);}/*** 设置传输文件的类型[文本文件或者二进制文件]** @param fileType* --BINARY_FILE_TYPE、ASCII_FILE_TYPE*/private void setFileType(int fileType) {try {ftpClient.setFileType(fileType);} catch (Exception e) {}}/**** 功能:关闭连接*/public void closeConnect() {try {if (ftpClient != null) {ftpClient.logout();ftpClient.disconnect();}} catch (Exception e) {}}/*** 转码[GBK -> ISO-8859-1] 不同的平台需要不同的转码** @param obj* @return*/private String gbkToIso8859(Object obj) {try {if (obj == null)return "";elsereturn new String(obj.toString().getBytes("GBK"), "iso-8859-1");} catch (Exception e) {return "";}}/**** 功能:上传文件附件到文件服务器* @param buffIn:上传文件流* @param fileName:保存文件名称* @param needDelete:是否同时删除* @return* @throws IOException*/public boolean uploadToFtp(InputStream buffIn, String fileName, boolean needDelete, String relativePath)throws FTPConnectionClosedException, IOException,Exception {boolean returnValue = false;// 上传文件try {// 设置传输二进制文件setFileType(FTP.BINARY_FILE_TYPE);int reply = ftpClient.getReplyCode();if(!FTPReply.isPositiveCompletion(reply)){ftpClient.disconnect();throw new IOException("Ftp连接失败");}ftpClient.enterLocalPassiveMode();// 支持动态创建多级目录createDir(relativePath);// 上传文件到ftpreturnValue = ftpClient.storeFile(fileName, buffIn);if(needDelete){ftpClient.deleteFile(fileName);}// 输出操作结果信息if (returnValue) {System.out.println("文件上传成功");} else {System.out.println("文件上传失败");}buffIn.close();// 关闭连接closeConnect();} catch (Exception e) {returnValue = false;throw e;} finally {try {if (buffIn != null) {buffIn.close();}} catch (Exception e) {}if (ftpClient.isConnected()) {closeConnect();}}return returnValue;}/*** 创建目录(有则切换目录,没有则创建目录)* @param dir* @return*/public boolean createDir(String dir){String d;try {//目录编码,解决中文路径问题d = new String(dir.toString().getBytes("GBK"),"iso-8859-1");//尝试切入目录if(ftpClient.changeWorkingDirectory(d))return true;String[] arr = dir.split(Const.SPER);StringBuffer sbfDir=new StringBuffer();//循环生成子目录for(String s : arr){sbfDir.append(Const.SPER);sbfDir.append(s);//目录编码,解决中文路径问题d = new String(sbfDir.toString().getBytes("GBK"),"iso-8859-1");//尝试切入目录if(ftpClient.changeWorkingDirectory(d))continue;if(!ftpClient.makeDirectory(d)){return false;}}//将目录切换至指定路径return ftpClient.changeWorkingDirectory(d);} catch (Exception e) {e.printStackTrace();return false;}}}
创建 FtpService 线程类,用于处理图片文件传至FTP服务器
package com.lill.test.threads;import com.lill.test.common.Const;
import com.lill.test.utils.FtpUtils;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;public class FtpService implements Runnable {private Logger logger = LoggerFactory.getLogger(FtpService.class);/*** 物理路径*/private String physicalPath;/*** 相对路径*/private String relativePath;/*** 文件名称(重命名后)*/private String fileName;/*** 扩展名*/private String ext;private File file;private String ip;private int port;private String userName;private String passWord;public FtpService(File file, String physicalPath, String relativePath, String fileName, String ext,String ip, int port, String userName, String passWord) {this.file = file;this.physicalPath = physicalPath;this.relativePath = relativePath;this.fileName = fileName;this.ext = ext;this.ip = ip;this.port = port;this.userName = userName;this.passWord = passWord;}public FtpService() {}@Overridepublic void run() {try {// 上传至FTPuploadFileToFtp(ip, port, userName, passWord, file, fileName.concat(ext), false, relativePath);// 生产中图String middle = physicalPath.concat(Const.SPER).concat(fileName).concat(Const.IMG_MIDDLE).concat(ext);Thumbnails.of(file).scale(0.5).outputQuality(0.8).toFile(middle);File fileMiddle = new File(middle);// 上传至FTPuploadFileToFtp(ip, port, userName, passWord, fileMiddle, fileName.concat(Const.IMG_MIDDLE).concat(ext), false, relativePath);// 生产缩略图String thumb = physicalPath.concat(Const.SPER).concat(fileName).concat(Const.IMG_THUMB).concat(ext);Thumbnails.of(file).scale(0.25).outputQuality(0.8).toFile(thumb);File fileThumb = new File(thumb);// 上传至FTPuploadFileToFtp(ip, port, userName, passWord, fileThumb, fileName.concat(Const.IMG_THUMB).concat(ext), false, relativePath);// 删除临时文件file.delete();fileMiddle.delete();fileThumb.delete();} catch (IOException e) {e.printStackTrace();}}protected void uploadFileToFtp(String ip, int port, String userName, String passWord, File file, String fileName, boolean needDelete, String relativePath){try {FtpUtils ftpUtils = FtpUtils.getInstance();ftpUtils.getFTPClient(ip, port, userName, passWord);ftpUtils.uploadToFtp(new FileInputStream(file), fileName, needDelete, relativePath);} catch (Exception e) {}}protected void showFtpImage(String ip, int port, String userName, String passWord, String filePath, HttpServletResponse response){try {FtpUtils ftpUtils = FtpUtils.getInstance();FTPClient ftpClient = ftpUtils.getFTPClient(ip, port, userName, passWord);ftpClient.retrieveFile(filePath, response.getOutputStream());} catch (Exception e) {}}protected void delFtpImage(String ip, int port, String userName, String passWord, String filePath){try {FtpUtils ftpUtils = FtpUtils.getInstance();FTPClient ftpClient = ftpUtils.getFTPClient(ip, port, userName, passWord);// 如果路径中包含中文,下面代码必定要写上String tmpfilePath = new String(filePath.getBytes("GBK"),"iso-8859-1");ftpClient.deleteFile(tmpfilePath);} catch (Exception e) {}}
}
创建DelService线程类,用于处理删除FTP服务器上的图片
package com.lill.test.threads;import com.lill.test.common.Const;
import com.lill.test.utils.FtpUtils;
import com.lill.test.utils.NameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.FTPClient;public class DelService implements Runnable {private String ip;private int port;private String userName;private String passWord;private String delPath;public DelService() {}public DelService(String ip, int port, String userName, String passWord, String delPath) {this.ip = ip;this.port = port;this.userName = userName;this.passWord = passWord;this.delPath = delPath;}@Overridepublic void run() {// 如果删除图片路径不为空,执行删除操作if (StringUtils.isNotBlank(delPath)) {if (delPath.indexOf("showImage") > 0) {String[] arr = delPath.split("=");String tmpExt = NameUtils.getFileExtension(arr[1]);// 将要被删除的原图地址String tmpfilePath = arr[1].replace(Const.IMG_MIDDLE, "").replace(Const.IMG_THUMB, "");delFtpImage(ip, port, userName, passWord, tmpfilePath);// 将要被删除的中图地址String tmpFileMiddle = tmpfilePath.replace(tmpExt, "").concat(Const.IMG_MIDDLE).concat(tmpExt);delFtpImage(ip, port, userName, passWord, tmpFileMiddle);// 将要删除的缩略图地址String tmpFileThumb = tmpfilePath.replace(tmpExt, "").concat(Const.IMG_THUMB).concat(tmpExt);delFtpImage(ip, port, userName, passWord, tmpFileThumb);} else {delFtpImage(ip, port, userName, passWord, delPath);}}}protected void delFtpImage(String ip, int port, String userName, String passWord, String filePath){try {FtpUtils ftpUtils = FtpUtils.getInstance();FTPClient ftpClient = ftpUtils.getFTPClient(ip, port, userName, passWord);// 如果路径中包含中文,下面代码必定要写上String tmpfilePath = new String(filePath.getBytes("GBK"),"iso-8859-1");ftpClient.deleteFile(tmpfilePath);} catch (Exception e) {}}
}
相关的示例代码,均在上面描述中,采用FTP方式处理图片的存储,Controller在接收到Base64数据之后,会在当前服务器上转化为原始图片,然后交给FtpService 线程类进行后续处理,线程类负责,将原始图片再另外生成 中图和缩略图,最后将这三张图片同时传至FTP进行存储,并在传输成功之后,删除应用服务器上临时生成的这三张图片。
41、Springboot 文件上传 采用Base64方式相关推荐
- Springboot文件上传 百度ocr文字识别提取
前言 在学习过程中突然发现我以前用的文件上传真的好傻.以前的博客记录中还沾沾自喜文件上传模板可以套用,不接收新事物,却发现原来Springboot的文件上传如此简单. 首先,文件上传的三种方式,普通文 ...
- SpringBoot文件上传源码解析
一.SpringMVC文件上传源码分析前言(这部分我觉得原作者写的很好) 该如何研究SpringMVC的文件上传的源码呢? 研究源码并不是仅仅知道程序是怎样运行的,而应该从宏观的角度.不同的立场去看待 ...
- 补习系列(11)-springboot 文件上传原理
一.文件上传原理 一个文件上传的过程如下图所示: 浏览器发起HTTP POST请求,指定请求头: Content-Type: multipart/form-data 服务端解析请求内容,执行文件保存处 ...
- SpringBoot 文件上传 通过Content-Type和文件头判断文件类型
SpringBoot 文件上传 通过Content-Type和文件头判断文件类型 一.关于MIME MIME的全称是Multipurpose Internet Mail Extensions,即多用途 ...
- SpringBoot文件上传和下载
SpringBoot文件上传和下载 一.SpringBoot文件上传 1.SpringMVC文件上传 1.Client处理 选择文件(1)form表单 选择文件 method="post&q ...
- 【文件上传漏洞绕过方式】
目录 前言 正文 总结 前言 目前,文件上传往往在业务中不可避免,也是极其容易出现上传漏洞.根据owasptop10中的排名,文件上传漏洞(属于攻击检测和防范不足)高居其中.今天和大家分享常见的文件上 ...
- 解决Springboot文件上传报错,java.io.FileNotFoundException: D:\System\Temp\tomcat.819...00.tmp (系统找不到指定的文件。)
Springboot文件上传,csdn上的方法无非是下面这两个: imgFile.transferTo(imageFolder); // 方法一/*** 方法二* FileUtils.copyInpu ...
- springboot文件上传下载实战 ——文件上传、下载、在线打开、删除
springboot文件上传下载实战 文件上传 文件上传核心 UserFileController 文件上传测试 文件下载与在线打开 文件下载.在线打开核心 UserFileController 文件 ...
- springboot文件上传下载实战 —— 登录功能、展示所有文件
springboot文件上传下载实战 创建项目 pom.xml 数据库建表与环境准备 建表SQL 配置文件 application.properties 整体架构 前端页面 登录页面 login.ht ...
最新文章
- 蓝图跑酷游戏教学的项目文件
- myeclipse6-ejb3入门
- Rhythmk 学习 Hibernate 09 - Hibernate HQL
- 如何寻找高质量流量日入三百+
- 智能车声标定位相关算法优化
- Theatre Square
- CF990G-GCD Counting【dfs】
- 计算机考试用英语怎么说,“全国大学生计算机等级考试一级”英语怎么说?
- 我新买的GTX1050为何装上去一直是黑屏
- animation-fill-mode属性的理解
- MATLAB实现FFT算法
- **LPC1788加密与解密方法**
- 吉他入门:吉他音阶训练入门教程(二)
- 结构体初始化为0的技巧!!
- python 图片转换为ico图标
- Java 动态眨眼 EyesJPanel (整理)
- 1-2 Verilog 4位 二选一 多路选择器
- 重磅!上海出落户新政:双一流应届硕士可直接落户!
- 云服务器添加交换分区
- c语言中怎么对圆环填充颜色,ps里怎么把圆环填充两种颜色
热门文章
- linux中top显示的信息详解,Linux中top显示信息详解
- 10天精读掌握:计算机组成与设计COAD:Patterson and Hennessy 第6天 2018/10.31
- python学习===从键盘输入一些字符,逐个把它们写到磁盘文件上,直到输入一个 # 为止。...
- Web调用浏览器摄像头
- Android 应用详情查看
- 数据结构实验7《基于Dijsktra算法的最短路径求解》
- python正弦波叠加方波_无穷多个(幅值)和(频率)不等的正弦波叠加就能形成周期方波。_学小易找答案...
- mysql批量删除重复数据库_建站经验:sql语句快速删除重复内容之我见
- 微信小程序--嘟嘟会议--会议发布和我的会议查看
- 恶搞小程序:鼠标不受控制+无限弹窗