位置: IT常识 - 正文

SpringBoot简单优雅实现图片上传功能(超详细)(springboot jni)

编辑:rootadmin
SpringBoot简单优雅实现图片上传功能(超详细) 文章目录前言技术栈项目目录前端实现index.htmlscript.js后端实现MultipartFile 介绍配置文件实体类ControllerAjaxResultMapperService拦截器测试结果展示前言

推荐整理分享SpringBoot简单优雅实现图片上传功能(超详细)(springboot jni),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:springboot 教程,springboot ci,springbootcsdn,springboot简单例子,springboot ci,springboot简单例子,springboot简单例子,springboot.,内容如对您有帮助,希望把文章链接给更多的朋友!

最近有一个需求需要实现图片上传,因此,本人找到了一个可以快速实现该功能的插件mini-upload-form。在此记录分享一下使用过程。

mini-upload-form的Github跳转 将程序从github拉下后,前端页面index.html可简单修改后直接使用,我们的精力主要放在后端实现。

技术栈jdk1.8.0_162maven-3.3.9mybatis-plus项目目录

需将mini-upload-from中assets文件下的资源引入自己项目中。除外还需引入bootstrap和jquery。

前端实现index.html<!DOCTYPE html><html><head> <meta charset="utf-8"/> <title>Mini Ajax File Upload Form</title> <!-- The main CSS file --> <link href="mini-upload-form/css/style.css" rel="stylesheet"/> <link href="bootstrap/css/bootstrap.css" rel="stylesheet"/></head><body><div class="row"> <div class="col align-self-start"> <div><h4>上传照片:</h4></div> <div class="d-flex flex-row flex-wrap mb-5" id="upload-img-container"> <p>暂无</p> </div> </div></div><div class="row"> <div class="col align-self-start"> <form id="upload" method="post" action="/file/upload" enctype="multipart/form-data"> <div id="note" class="text-white"></div> <div id="drop"> 拖到此区域 <a>浏览本地</a> <input id="uploadFile" type="file" name="file" multiple/> </div> <ul> <!-- The file uploads will be shown here --> </ul> </form> <div class="col align-self-start"> </div> <div class="row"> <div class="col align-self-start"> <div class="text-center"> <a type="button" id="submit-file-btn" class="text-center btn btn-info text-white">提交</a> </div> </div> </div> </div></div><script src="js/jquery-1.11.3.js"></script><script src="bootstrap/js/bootstrap.js"></script><script src="mini-upload-form/js/jquery.knob.js"></script><!-- jQuery File Upload Dependencies --><script src="mini-upload-form/js/jquery.ui.widget.js"></script><script src="mini-upload-form/js/jquery.iframe-transport.js"></script><script src="mini-upload-form/js/jquery.fileupload.js"></script><!-- Our main JS file --><script src="mini-upload-form/js/script.js"></script></body></html>script.js

本文还实现了上传成功后回写到前端页面,所以需修改script.js添加提交成功后回调函数。

// Automatically upload the file once it is added to the queue var jqXHR = data.submit().success(function (result) { var status = result['code']; var fileUri = result['fileUri']; var fileId = result['fileId']; var originFileName = result['originFileName']; if (status!='200'){ data.context.addClass('error'); numError++; }else{ images.push(fileId) localStorage.setItem('cd_files', JSON.stringify(images)) numSuccess++; $("#upload-img-container>p:nth-child(1)").remove() const imageHTML = "<div style='width:100px;height:100px;margin:.5rem;text-align:center'>"+ "<image class='rounded' style='width:100%;height:100%' src="+staticServer + fileUri +" alt=>"+ "<p class='text-center text-muted ' style='word-wrap: break-word;'>"+originFileName+"</p></div>"; $("#upload-img-container").append(imageHTML) } updateNote(); }); // Update the note function updateNote() { if($('#note').length) $('#note').html('<span>' + numSuccess + '</span> 个成功上传.<br /><span id="note-error">' + numError + '</span> 个上传失败.' + (numError > 0 ? ' <a href="#" id="btn-retry"> (Retry all)</a>' : '')); }后端实现MultipartFile 介绍SpringBoot简单优雅实现图片上传功能(超详细)(springboot jni)

MultipartFile是SpringMVC提供简化上传操作的工具类。

在不使用框架之前,都是使用原生的HttpServletRequest来接收上传的数据,文件是以二进制流传递到后端的,然后需要我们自己转换为File类。使用了MultipartFile工具类之后,我们对文件上传的操作就简便许多了。 MultipartFile接口方法

package org.springframework.web.multipart;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.nio.file.Files;import java.nio.file.Path;import org.springframework.core.io.InputStreamSource;import org.springframework.core.io.Resource;import org.springframework.lang.Nullable;import org.springframework.util.FileCopyUtils;public interface MultipartFile extends InputStreamSource {//getName() 返回参数的名称 String getName();//获取源文件的昵称 @Nullable String getOriginalFilename();//getContentType() 返回文件的内容类型 @Nullable String getContentType();//isEmpty() 判断是否为空,或者上传的文件是否有内容 boolean isEmpty();//getSize() 返回文件大小 以字节为单位 long getSize();//getBytes() 将文件内容转化成一个byte[] 返回 byte[] getBytes() throws IOException;//getInputStream() 返回InputStream读取文件的内容 InputStream getInputStream() throws IOException; default Resource getResource() { return new MultipartFileResource(this); }//transferTo(File dest) 用来把 MultipartFile 转换换成 File void transferTo(File var1) throws IOException, IllegalStateException; default void transferTo(Path dest) throws IOException, IllegalStateException { FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest)); }}配置文件# serverserver.port=8010# datasourcespring.datasource.url=jdbc:mysql://xxxx:3306/upload?characterEncoding=utf-8&useSSL=falsespring.datasource.username=***spring.datasource.password=****spring.datasource.driver-class-name=com.mysql.jdbc.Driver# upload size settingspring.servlet.multipart.max-file-size=30MBspring.servlet.multipart.max-request-size=30MB file.upload.dir=D://uploadfile.visit.path=upload实体类

图片存储实体类SysFile

@Data@Builder@TableName("sys_file")public class SysFile { private String fileId; private String mediaType; private String fileFormat; private String filePath; private String originalName; private Long fileSize; private Integer imageWidth; private Integer imageHeight; private String createUserId; private Date createDate; private String updateUserId; private Date updateDate;}Controller@RestController@RequestMapping("/file")public class FileUploadController { @Autowired private LocalStorageService localStorageService; @RequestMapping("/upload") public AjaxResult upload(@RequestParam("file") MultipartFile file) throws Exception { try { if (file.isEmpty()) { throw new RuntimeException("上传文件不能为空"); } return localStorageService.upload(file); } catch (Exception e) { e.printStackTrace(); return AjaxResult.error("文件上传失败"); } }}AjaxResultpublic class AjaxResult extends HashMap<String, Object> { private static final long serialVersionUID = 1L; /** * 状态码 */ public static final String CODE_TAG = "code"; /** * 返回内容 */ public static final String MSG_TAG = "msg"; /** * 数据对象 */ public static final String DATA_TAG = "data"; /** * 状态类型 */ public enum Type { /** * 成功 */ SUCCESS(200), /** * 警告 */ WARN(301), /** * 错误 */ ERROR(500); private final int value; Type(int value) { this.value = value; } public int value() { return this.value; } } /** * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 */ public AjaxResult() { } /** * 初始化一个新创建的AjaxResult对象 * * @param type 状态类型 * @param msg 返回内容 */ public AjaxResult(Type type, String msg) { super.put(CODE_TAG, type.value); super.put(MSG_TAG, msg); } /** * 初始化一个新创建的 AjaxResult 对象 * * @param type 状态类型 * @param msg 返回内容 * @param data 数据对象 */ public AjaxResult(Type type, String msg, Object data) { super.put(CODE_TAG, type.value); super.put(MSG_TAG, msg); if (!ObjectUtils.isEmpty(data)) { super.put(DATA_TAG, data); } } /** * 返回成功消息 * * @return 成功消息 */ public static AjaxResult success() { return AjaxResult.success("操作成功"); } /** * 返回成功数据 * * @return 成功消息 */ public static AjaxResult success(Object data) { return AjaxResult.success("操作成功", data); } /** * 返回成功消息 * * @param msg 返回内容 * @return 成功消息 */ public static AjaxResult success(String msg) { return AjaxResult.success(msg, null); } /** * 返回成功消息 * * @param msg 返回内容 * @param data 数据对象 * @return 成功消息 */ public static AjaxResult success(String msg, Object data) { return new AjaxResult(Type.SUCCESS, msg, data); } /** * 返回警告消息 * * @param msg 返回内容 * @return 警告消息 */ public static AjaxResult warn(String msg) { return AjaxResult.warn(msg, null); } /** * 返回警告消息 * * @param msg 返回内容 * @param data 数据对象 * @return 警告消息 */ public static AjaxResult warn(String msg, Object data) { return new AjaxResult(Type.WARN, msg, data); } /** * 返回错误消息 * * @return */ public static AjaxResult error() { return AjaxResult.error("操作失败"); } /** * 返回错误消息 * * @param msg 返回内容 * @return 警告消息 */ public static AjaxResult error(String msg) { return AjaxResult.error(msg, null); } /** * 返回错误消息 * * @param msg 返回内容 * @param data 数据对象 * @return 警告消息 */ public static AjaxResult error(String msg, Object data) { return new AjaxResult(Type.ERROR, msg, data); } /** * 方便链式调用 * * @param key 键 * @param value 值 * @return 数据对象 */ @Override public AjaxResult put(String key, Object value) { super.put(key, value); return this; }}Mapper

SysFileMapper

@Mapperpublic interface SysFileMapper extends BaseMapper<SysFile> {}Service

SysFileService

public interface SysFileService extends IService<SysFile> {}@Servicepublic class sysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {}

LocalStorageService

@Slf4j@Service("localStorageService")public class LocalStorageService { @Autowired private SysFileService sysFileService; @Value("${file.upload.dir}") private String uploadDir; @Value("${file.visit.path:upload}") private String visitPath; private static final String[] ALLOW_FILE_TYPES = { "jpg", "jpeg", "png"}; public AjaxResult upload(MultipartFile file) throws Exception { String contentType = file.getContentType().toLowerCase(); boolean allowType = false; for (String allowFileType : ALLOW_FILE_TYPES) { if(contentType.contains(allowFileType)) { allowType = true; break; } } if (!allowType) { return AjaxResult.error("请上传正确的文件格式"); } String fileId = UUID.randomUUID().toString(); String subFolder = hashBy256(fileId); File destFolder = new File(uploadDir + File.separator + subFolder); if (!destFolder.exists()) { destFolder.mkdirs(); } String originalFilename = file.getOriginalFilename(); String fileExt = getFileType(originalFilename); String destFileName = fileId + "." + fileExt; File destFile = new File(uploadDir + File.separator + subFolder + File.separator + destFileName); log.info("file saved in: {}", destFile.getAbsoluteFile()); file.transferTo(destFile); String filePath = visitPath + File.separator + subFolder + File.separator + destFileName; String fileUri = transferPathAsImageUri(filePath); Long fileSize = file.getSize(); SysFile sysFile = SysFile.builder() .fileId(fileId) .filePath(filePath) .fileFormat(fileExt) .fileSize(fileSize) .mediaType(contentType) .originalName(originalFilename) .build(); sysFileService.save(sysFile); return AjaxResult.success() .put("fileId", fileId) .put("filePath", filePath) .put("originFileName", originalFilename) .put("fileName", destFileName) .put("fileUri", fileUri); } private String getFileType(String originalFilename){ int extPos = originalFilename.lastIndexOf("."); if (extPos != -1) { return originalFilename.substring(extPos + 1); } throw new RuntimeException("未知类型"); } public static String hashBy256(String str) { String s = Integer.toHexString(Math.abs(str.hashCode()) % 256).toUpperCase(); if (s.length() == 1) { s = "0" + s; } return s; } public static String transferPathAsImageUri(String fileServerPath) { if (!StringUtils.hasLength(fileServerPath)) { return null; } return "/" + fileServerPath.replaceAll("\\\\", "/"); }}拦截器

ResourceConfig,该拦截器用于上传后回写到界面

@Configurationpublic class ResourceConfig implements WebMvcConfigurer { @Value("${file.visit.path:upload}") private String visitPath; @Value("${file.upload.dir}") private String resourceDir; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/" + visitPath + "/**").addResourceLocations("file:" + resourceDir + "/"); }}测试结果展示

前端界面

到此,完整的图片上传功能就结束了,希望本文对您有所帮助。

本文链接地址:https://www.jiuchutong.com/zhishi/298884.html 转载请保留说明!

上一篇:YOLO系列 --- YOLOV7算法(二):YOLO V7算法detect.py代码解析(yolo系列算法比较)

下一篇:torch.cuda常用指令(torch.cuda.is_available())

  • ipad迷你2相当于苹果几(ipad迷你2)(ipad迷你2是多少寸)

    ipad迷你2相当于苹果几(ipad迷你2)(ipad迷你2是多少寸)

  • 企业微信视频会议怎么开(企业微信视频会议录制)

    企业微信视频会议怎么开(企业微信视频会议录制)

  • opporeno4是否有耳机孔吗(opporeno4官方标配有没有耳机)

    opporeno4是否有耳机孔吗(opporeno4官方标配有没有耳机)

  • 谷歌商城无法登录是什么原因(谷歌商城无法登入)

    谷歌商城无法登录是什么原因(谷歌商城无法登入)

  • 电脑qq消息显示全在一侧是为什么(为什么电脑qq收到消息但是页面没有出现)

    电脑qq消息显示全在一侧是为什么(为什么电脑qq收到消息但是页面没有出现)

  • 拼多多的sku编码是什么意思(拼多多sku编码怎么填举例)

    拼多多的sku编码是什么意思(拼多多sku编码怎么填举例)

  • 微信提示绑定的qq异常(微信提示绑定的身份证到期但是新的)

    微信提示绑定的qq异常(微信提示绑定的身份证到期但是新的)

  • soul屏蔽通讯录有啥用(soul屏蔽信息)

    soul屏蔽通讯录有啥用(soul屏蔽信息)

  • xr另外一个卡槽在哪(xr另一张卡显示不出来怎么办)

    xr另外一个卡槽在哪(xr另一张卡显示不出来怎么办)

  • 京东账户注销怎么恢复(京东账户注销怎么办理)

    京东账户注销怎么恢复(京东账户注销怎么办理)

  • 屋内烟感器红灯一直亮(屋内烟感器红灯一直亮,但没有声音)

    屋内烟感器红灯一直亮(屋内烟感器红灯一直亮,但没有声音)

  • 华为p40pro用的什么系统(华为p40pro用的什么充电线)

    华为p40pro用的什么系统(华为p40pro用的什么充电线)

  • 苹果11跟苹果x的区别(苹果11与苹果x那个好)

    苹果11跟苹果x的区别(苹果11与苹果x那个好)

  • 抖音的数据中心在哪里(抖音的数据中心账号搜索量准确吗)

    抖音的数据中心在哪里(抖音的数据中心账号搜索量准确吗)

  • 携程购票5元的附加是什么(携程购票5元的票怎么退)

    携程购票5元的附加是什么(携程购票5元的票怎么退)

  • 芒果tv怎么解绑银行卡(芒果tv怎么解绑QQ)

    芒果tv怎么解绑银行卡(芒果tv怎么解绑QQ)

  • 什么叫应用场景(应用场景解决方案是什么意思)

    什么叫应用场景(应用场景解决方案是什么意思)

  • 相册怎么制作成视频(相册怎么制作成短片)

    相册怎么制作成视频(相册怎么制作成短片)

  • oicq几几年出的(oicq是哪年出来的)

    oicq几几年出的(oicq是哪年出来的)

  • oppok3是多少瓦快充(oppok3多少w)

    oppok3是多少瓦快充(oppok3多少w)

  • 拼多多免费发红包在哪(拼多多免费发红包怎么发)

    拼多多免费发红包在哪(拼多多免费发红包怎么发)

  • 魅族16s防水等级(魅族16s防水级别)

    魅族16s防水等级(魅族16s防水级别)

  • xsmax双卡双待怎么插(xsmax双卡双待怎么总是在搜信号)

    xsmax双卡双待怎么插(xsmax双卡双待怎么总是在搜信号)

  • win10excel变成英文了(window10excel表格英文变中文)

    win10excel变成英文了(window10excel表格英文变中文)

  • word分节符在哪里找(word分节符在哪些视图中可以看到)

    word分节符在哪里找(word分节符在哪些视图中可以看到)

  • 在Win10系统中,如何设置PIN密码登录?(在win10系统中,如何限制孩子玩原神游戏)

    在Win10系统中,如何设置PIN密码登录?(在win10系统中,如何限制孩子玩原神游戏)

  • Yolov5中使用Resnet18作为主干网络(yolov5中使用的限制目标宽高的方法防止梯度爆炸)

    Yolov5中使用Resnet18作为主干网络(yolov5中使用的限制目标宽高的方法防止梯度爆炸)

  • 材料按实际成本计价时发出成本的计算方法有
  • 小规模纳税人增值税优惠政策
  • 注册资本认缴到哪里
  • 没有数字的公章有效吗三方协议盖的章没有数字
  • 应付账款赊销率和周转率的区别
  • 收回个人社会保险费是否可以冲红管理费用
  • 跨越发票冲红,填了红字信息表,没有负数发票
  • 企业一直亏损但是汇算清缴调增
  • 企业在什么情况下辞退员工不需要补偿
  • 什么叫税后利息费用
  • 房产税收取标准有哪些
  • 帮客户代付保证金违法吗
  • 企业设备维修管理制度
  • 发票对方认证不了怎么回事
  • 房屋征收服务中心是干什么的
  • 分公司开票总公司收款行吗
  • 企业所得税审计的内容包括哪四个方面
  • 闲置的房屋可以计提折旧吗
  • 记账凭证的科目不会填
  • 坏账准备核销和转销的区别
  • 企业的不征税收入用于支出所形成的资产,其计算的折旧
  • 进项税和销项税的借贷方向
  • 退货抵扣是什么意思
  • 固定资产进项税额怎么做账
  • 企业发生待摊费怎么处理
  • 如何关闭开始菜单快捷键
  • 新个人所得税的发展现状
  • php二维数组遍历
  • 其他生活服务业增值税税率
  • 铁杆茉莉的养殖方法
  • PHP:curl_reset()的用法_cURL函数
  • PHP:proc_get_status()的用法_命令行函数
  • 超市内账会计一般每月做什么
  • 免税和免征增值税是一个意思么
  • uniapp如何使用
  • 公司投资款无法收回
  • php实现上传图片功能
  • php调用url
  • redis 缓存框架
  • 财务人离职了怎么说
  • 手撕代码题目集锦
  • vue有哪些内容
  • densenet网络结构详解
  • 深度学习数据集—水果数据集大合集
  • 应收账款期末余额在借方还是贷方
  • 小规模纳税人购入货物收到增值税专用发票
  • 财务费用有发票吗
  • 异地工程税
  • 企业怎么开启承兑业务
  • 视同销售要不要确认收入?
  • 对外投资损失可以抵税吗
  • 职工福利费的会计处理
  • 补缴年报所得税怎么填
  • 应付职工薪酬代扣社保
  • 库存周转率中销量怎么算
  • 信息服务费可以抵扣吗
  • 动物园会计核算办法
  • 小规模印花税怎么报
  • win7 mysql5.7.21安装
  • mysql 1449解决
  • sql怎么比较两个表字段的内容
  • win7怎么清除记录
  • win2003加速开机
  • 一键ghost还原备份
  • linux删除一个非空子目录命令
  • windows7怎么设置右键菜单
  • android自定义搜索框
  • jquery1
  • 批处理文件.bat
  • opengl入门教程
  • python网络爬虫教程
  • android 动效
  • 用js实现导航栏的下拉列表
  • 如何控制孩子的手机使用时间
  • python数字类型及操作
  • 苏州市总工会主要领导
  • 县级税务
  • 2021年四川医保缴费截止时间
  • 重庆税务自助取票地点
  • 电信部门可以知道通话内容吗?
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设