引入依赖

<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方式相关推荐

  1. Springboot文件上传 百度ocr文字识别提取

    前言 在学习过程中突然发现我以前用的文件上传真的好傻.以前的博客记录中还沾沾自喜文件上传模板可以套用,不接收新事物,却发现原来Springboot的文件上传如此简单. 首先,文件上传的三种方式,普通文 ...

  2. SpringBoot文件上传源码解析

    一.SpringMVC文件上传源码分析前言(这部分我觉得原作者写的很好) 该如何研究SpringMVC的文件上传的源码呢? 研究源码并不是仅仅知道程序是怎样运行的,而应该从宏观的角度.不同的立场去看待 ...

  3. 补习系列(11)-springboot 文件上传原理

    一.文件上传原理 一个文件上传的过程如下图所示: 浏览器发起HTTP POST请求,指定请求头: Content-Type: multipart/form-data 服务端解析请求内容,执行文件保存处 ...

  4. SpringBoot 文件上传 通过Content-Type和文件头判断文件类型

    SpringBoot 文件上传 通过Content-Type和文件头判断文件类型 一.关于MIME MIME的全称是Multipurpose Internet Mail Extensions,即多用途 ...

  5. SpringBoot文件上传和下载

    SpringBoot文件上传和下载 一.SpringBoot文件上传 1.SpringMVC文件上传 1.Client处理 选择文件(1)form表单 选择文件 method="post&q ...

  6. 【文件上传漏洞绕过方式】

    目录 前言 正文 总结 前言 目前,文件上传往往在业务中不可避免,也是极其容易出现上传漏洞.根据owasptop10中的排名,文件上传漏洞(属于攻击检测和防范不足)高居其中.今天和大家分享常见的文件上 ...

  7. 解决Springboot文件上传报错,java.io.FileNotFoundException: D:\System\Temp\tomcat.819...00.tmp (系统找不到指定的文件。)

    Springboot文件上传,csdn上的方法无非是下面这两个: imgFile.transferTo(imageFolder); // 方法一/*** 方法二* FileUtils.copyInpu ...

  8. springboot文件上传下载实战 ——文件上传、下载、在线打开、删除

    springboot文件上传下载实战 文件上传 文件上传核心 UserFileController 文件上传测试 文件下载与在线打开 文件下载.在线打开核心 UserFileController 文件 ...

  9. springboot文件上传下载实战 —— 登录功能、展示所有文件

    springboot文件上传下载实战 创建项目 pom.xml 数据库建表与环境准备 建表SQL 配置文件 application.properties 整体架构 前端页面 登录页面 login.ht ...

最新文章

  1. 蓝图跑酷游戏教学的项目文件
  2. myeclipse6-ejb3入门
  3. Rhythmk 学习 Hibernate 09 - Hibernate HQL
  4. 如何寻找高质量流量日入三百+
  5. 智能车声标定位相关算法优化
  6. Theatre Square
  7. CF990G-GCD Counting【dfs】
  8. 计算机考试用英语怎么说,“全国大学生计算机等级考试一级”英语怎么说?
  9. 我新买的GTX1050为何装上去一直是黑屏
  10. animation-fill-mode属性的理解
  11. MATLAB实现FFT算法
  12. **LPC1788加密与解密方法**
  13. 吉他入门:吉他音阶训练入门教程(二)
  14. 结构体初始化为0的技巧!!
  15. python 图片转换为ico图标
  16. Java 动态眨眼 EyesJPanel (整理)
  17. 1-2 Verilog 4位 二选一 多路选择器
  18. 重磅!上海出落户新政:双一流应届硕士可直接落户!
  19. 云服务器添加交换分区
  20. c语言中怎么对圆环填充颜色,ps里怎么把圆环填充两种颜色

热门文章

  1. linux中top显示的信息详解,Linux中top显示信息详解
  2. 10天精读掌握:计算机组成与设计COAD:Patterson and Hennessy 第6天 2018/10.31
  3. python学习===从键盘输入一些字符,逐个把它们写到磁盘文件上,直到输入一个 # 为止。...
  4. Web调用浏览器摄像头
  5. Android 应用详情查看
  6. 数据结构实验7《基于Dijsktra算法的最短路径求解》
  7. python正弦波叠加方波_无穷多个(幅值)和(频率)不等的正弦波叠加就能形成周期方波。_学小易找答案...
  8. mysql批量删除重复数据库_建站经验:sql语句快速删除重复内容之我见
  9. 微信小程序--嘟嘟会议--会议发布和我的会议查看
  10. 恶搞小程序:鼠标不受控制+无限弹窗