springboot之文件上传、图片预览(thymeleaf+layui)

springboot自带图片服务器,但是一般我们都不会用,文件这一块因为灵活性比较高,可能每个公司的都不一样,因此最好还是自己来搞定。

一、思路

1、上传 ①.使用spring的正常上传,文件存储路径为磁盘任意位置,可配置 ②.业务表中存附件id ③.前端使用Layui 2、预览 ①.使用nginx代理,只需要根据附件id获取图片路径即可

二、上传

1.建表

CREATE TABLE `sys_accessory` (
 `id` varchar(32) DEFAULT NULL,
 `original_name` varchar(256) DEFAULT NULL COMMENT '原文件名\n',
 `file_size` int(11) DEFAULT NULL COMMENT '文件大小(单位:字节)',
 `path` varchar(256) DEFAULT NULL COMMENT '存储路径',
 `category` varchar(32) DEFAULT NULL COMMENT '分类',
 `create_time` datetime DEFAULT NULL COMMENT '创建时间',
 `create_user` varchar(32) DEFAULT NULL COMMENT '创建人',
 `is_del` char(1) DEFAULT NULL COMMENT '是否删除(1:是,0:否)'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='附件表';

2.文件上传的主要代码 上传的返回值是附件id,因为上传后其他操作需要(比如保存用户头像)需要用到

@RequestMapping("upload")
 public ResultModel<String> upload(@RequestParam("file") MultipartFile file, String userId, @RequestParam("category") String category) {

 String originalName = file.getOriginalFilename();
 long fileSize = file.getSize();
 String ext = originalName.substring(originalName.lastIndexOf(".") + 1, originalName.length());
 String tmpName = genTmpFileName();
 String path = File.separator + category + File.separator + tmpName + "." + ext;
 try {
 File targetFile = new File(uploadBasePath + path);
 if (!targetFile.getParentFile().exists()){
 targetFile.getParentFile().mkdirs();
 }
 file.transferTo(targetFile);
 SysAccessory accessory = getAcc(userId,originalName,Integer.parseInt(String.valueOf(fileSize)),path,category);
 return sysAccessoryService.upload(accessory);
 } catch (IOException e) {
 e.printStackTrace();
 }
 return ResultModel.defaultError(null);
 }

 private SysAccessory getAcc(String userId, String originalName, Integer fileSize, String path, String category) {
 SysAccessory accessory = new SysAccessory();
 accessory.setCreateTime(new Date());
 accessory.setCreateUser(userId);
 accessory.setIsDel(Constants.NEGATIVE);
 accessory.setOriginalName(originalName);
 accessory.setFileSize(fileSize);
 accessory.setPath(path);
 accessory.setCategory(category);
 return accessory;
 }

 private String genTmpFileName() {
 return DateUtil.date_string(new Date(), "yyyyMMddHHmmssssss");
 }

其实比较复杂的是页面上的操作,每一个做过上传的相信也都有体会,但是这个layui已经帮我们简化了很多,基于上传是一个公用方法,此处我又做了一次抽取,代码如下

var upload = function (eleId, layUpload, done,extendParam, error, accept, exts) {
 layUpload.render({
 elem: eleId //绑定元素
 , url: uploadPath //上传接口--此处通过配置的全局变量获取
 , accept: accept === undefined ? 'file' : accept
 , exts: exts === undefined ? 'jpg|png|gif|bmp|jpeg' : exts
 , data: extendParam
 , done: function (res) {
 //上传完毕回调
 if (typeof (done) === 'function') {
 console.log(res);
 if (res.code === '0'){
 done(res.data);
 }
 }
 }
 , error: function () {
 //请求异常回调
 if (typeof (error) === 'function') {
 error()
 }
 }
 });
 };

参数解释: eleId:绑定上传事件元素id layUpload:layui的upload模块,也可以在此处使用layui.use再次获取 done:上传成功回调 默认传这三个方法就够了,如果不需要处理失败等情况的话(但是不建议这么干)


extendParam:自定义扩展参数 error:失败回调 accept:接收类型(layui默认:file) exts:文件扩展名(layui默认:jpg|png|gif|bmp|jpeg) 3.前端页面

<!--这只是上传文件代码,其他表单信息忽略-->
 <button type="button" class="layui-btn" id="test1">
 <i class="layui-icon">&#xe67c;</i>上传图片
 </button>
 <input type="hidden" id="photo" name="photo" value="">
<div id="previewPhoto">
 <img src="/images/default-mem.png" th:src="${defaultImageViewPath+user.photo}" alt="" style="width: 80px;height: 80px;">
</div>
<script>
 layui.use('form', function () {
 var form = layui.form, upload = layui.upload,$=layui.jquery;
 form.render();
 Common.uploadFile('#test1', upload, function (data) {
 $("#photo").val(data); //回写附件id,用于提交表单时保存到业务表
 $("#previewPhoto img").attr("src",defaultImageViewPath + data);//图片回显,样式可以自己随便写
 },{category:'photo'});
 //监听提交
 form.on('submit(formDemo)', function (data) {
 layer.msg(JSON.stringify(data.field));
 //TODO ajax提交表单
 return false;
 });
 });
</script>

三、效果

头像上传

四、预览

预览更简单,只需要获取图片路径,配合nginx即可。 nginx配置

server {
 listen 80;
 server_name localhost;

 #charset koi8-r;

 #access_log logs/host.access.log main;

 location / {
 root html;
 index index.html index.htm;
 }
 location /file {
 alias D:\easyboot;
 allow all;
 autoindex on;
 }
}

java代码部分:

@RequestMapping("open")
 public void upload(@RequestParam("id") String id, HttpServletResponse response) {
 response.setHeader("Access-Control-Allow-Origin", "*");
 SysAccessory accessory = sysAccessoryService.getById(id).getData();
 if (accessory == null){
 return;
 }
 String path = viewBasePath + accessory.getPath();
 try {
 response.sendRedirect(path);
 } catch (IOException e) {
 e.printStackTrace();
 }

 }

访问路径:

访问url

目标结果:

目标结果

这只是简单的图片上传和预览,具体文件类型怎么控制,真实文件类型怎么获取,批量上传等等都没有,只是给小伙伴们一个简单的demo可以参考,有问题的欢迎随时撩我,或者关注我的公众号获取更多信息。

原文发布于微信公众号 - 陌与尘埃(grq100296)

原文发表时间:2018-03-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏魏艾斯博客www.vpsss.net

MySQL 数据库类型从 InnoDB 转换为 MyISAM

19060
来自专栏友弟技术工作室

Beego Models之四模型定义

使用orm定义,然后使用cmd方式,自动建表,不过在实际生产中还是直接使用sql操作的,这种模型定义在生产环境中定义的比较少,基本上都是直接使用基本类型,一些特...

30320
来自专栏魏艾斯博客www.vpsss.net

MySQL 数据库类型从 InnoDB 转换为 MyISAM

魏艾斯博客有一个 wordpress 站点,有一天无意中发现数据库挺大的,可是这个站也就不到 10 篇文章,没道理这么大的数据库啊。然后开始查找原因,发现在 p...

528220
来自专栏阿杜的世界

Java Web技术经验总结(十四)

这个语句如果只是查询前面几页,或者是表的数据量不大(小于10万),就没有问题,否则就会出现慢查询。参考文章:【MySQL】 性能优化之 延迟关联进行了优化。

7610
来自专栏地方网络工作室的专栏

mysql 命令行补全工具 mycli

mysql 命令行补全工具 mycli 前言 我们在连接mysql数据库的时候,大多数情况下是使用gui图形界面的工具的。但是,有时候连接数据库还是命令行方便,...

34070
来自专栏乐沙弥的世界

PGA的设置与调整

    PGA,即程序全局区(Program Global Area),是Oracle体系机构的重要组成部分。Oracle 数据库对系统内存的总开销即是PGA+...

10020
来自专栏耕耘实录

windows中PLSQL/Developer、Oracle InstantClient的安装与配置

版权声明:本文为耕耘实录原创文章,各大自媒体平台同步更新。欢迎转载,转载请注明出处,谢谢

23630
来自专栏chenssy

【死磕Sharding-jdbc】---最大努力型事务

在分布式数据库的场景下,相信对于该数据库的操作最终一定可以成功,所以通过最大努力反复尝试送达操作。

16830
来自专栏西安-晁州

beego中orm关联查询使用解析

这两天在学习beego框架,之前学习的时候遗漏了很多东西,比如orm、缓存、应用监控、模板处理等,这里将通过实例记录下如何使用beego自带的orm进行关联查询...

53700
来自专栏积累沉淀

Python快速学习第九天--安装并操作Mysql数据库

python操作mysql数据库 Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口。...

28780

扫码关注云+社区

领取腾讯云代金券