本次的项目环境为 SpringBoot 2.0.4, JDK8.0. 服务器环境为CentOS7.0, Nginx的忘了版本.

前言

SpringBoot使用MultiPartFile接收来自表单的file文件,然后进行 服务器 的上传是一个项目最基本的需求,我以前的项目都是基于SpringMVC框架搭建的,所以在使用SpringBoot的时候进行MultiPartFile上传遇到了坑,这里说一下,其中主要包含两个坑点.

使用transferTo()方法写入File时找不到文件路径.

访问文件时 Nginx 的403 forbidden问题.

使用transferTo()方法写入File时找不到文件路径

在我们解决问题之前,我们先看一下封装的上传方法以及报错日志.

public static final String BASE_PATH = "/test/";

public static String upload(MultipartFile imageFile) {

if (imageFile.isEmpty()) {

return null;

}

String filename = imageFile.getOriginalFilename();

String ext= null;

if(filename.contains(".")){

ext = filename.substring(filename.lastIndexOf("."));

}else{

ext = "";

}

String uuid = UUID.randomUUID().toString().replaceAll("-", "");

String nfileName = uuid + ext;

String dirPath = DateFormatUtils.format(new Date(), "yyyyMMdd");

String filepath = BASE_PATH.endsWith("/") ? BASE_PATH+dirPath : BASE_PATH+"/"+dirPath;

File targetFile = new File(filepath, nfileName);

if (!targetFile.exists()) {

targetFile.mkdirs();

} else {

targetFile.delete();

}

try {

imageFile.transferTo(targetFile);

} catch (IllegalStateException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

String accessUrl = "/"+nfileName;

logger.debug("上传文件成功 URL:" + nfileName);

return accessUrl;

}

报错日志如下所示.

java.io.IOException: java.io.FileNotFoundException: /test/20181025/be3676dffca94c6dac5e96a1a41dcd97.jpg (Is a directory)

at org.apache.catalina.core.ApplicationPart.write(ApplicationPart.java:122)

at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.transferTo(StandardMultipartHttpServletRequest.java:255)

at com.dong.runline.common.utils.UploadUtils.upload(UploadUtils.java:56)

at com.dong.runline.controller.TimeLineController.createTimeLineAction(TimeLineController.java:55)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

这里就出现了 java.io.FileNotFoundException 错误,这是怎么造成的呢?,通过Debug下的断点我们发现是下面的位置发生了错误.

这里我用的本地环境进行了测试,发现本地创建了这个样的一个路径,最后的图片被创建成一个这样的路径.

在SpringMVC环境下并没有这样的问题,在SpringBoot却出现了这样的问题,那么到底怎么造成的呢?网上的很多博客写到,通过查询transferTo()方法源码找到了问题关键所在.

@Override

public void transferTo(File dest) throws IOException, IllegalStateException {

this.part.write(dest.getPath());

}

我们接着进入write()方法.

@Override

public void write(String fileName) throws IOException {

File file = new File(fileName);

if (!file.isAbsolute()) {

file = new File(location, fileName);

}

try {

fileItem.write(file);

} catch (Exception e) {

throw new IOException(e);

}

}

这时候我们看到如果!file.isAbsolute()成立,也就是我们没有使用绝对路径,那么file = new File(location,fileName);会在原来的基础上加上location路径.这就是原因所在,解决起来也很方便,网上总共有两种方案.

使用绝对路径

修改location的值

第一种方案我们就不过多解释了,我们看一下如何修改location的值.我们只需要在启动类中注入如下Bean即可.把路径指向我们的存储路径.

@Bean

MultipartConfigElement multipartConfigElement() {

MultipartConfigFactory factory = new MultipartConfigFactory();

factory.setLocation(UploadUtils.BASE_PATH);

return factory.createMultipartConfig();

}

然后我们再修改下UploadUtils中的创建File方法即可.

String uuid = UUID.randomUUID().toString().replaceAll("-", "");

String nfileName = uuid + ext;

File targetFile = new File(nfileName);

if (!targetFile.exists()) {

targetFile.mkdirs();

} else {

targetFile.delete();

}

访问文件时Nginx的403 forbidden问题

所谓的Nginx的403错误其实就是访问权限错误.当前用户没有访问该资源的权限,这样理解的话,我们就有两种方案可行.一,降低文件访问的权限等级.二,升高用户的访问权限.下面我们一个一个来看一下如何进行实现.

降低文件访问的权限等级

降低文件的访问权限,我们只需要用到 chmod指令即可.这里简单解释一下chmod指令.

在Mac的使用过程中我们也经常会修改 某个文件的权限,例如:

chmod 777 file

如果如上设置的话,那么任何一个用户都会对这个file文件拥有全部权限.

那么为什么是三位数呢?这是因为这三位数分别代表着档案拥有者User、群组Group、其他Other三者的权限.也就是说拥有者的权限等级为7,群组的权限等级为7,其他权限等级也为7.

那么为什么是7呢?这是因为一个 linux 文件总共有三种权限,分别是读r,写w,操作x.对应的值分别是4,2,1.当一个用户对某个文件拥有7的数值时,这时候为4+2+1,也就是说他拥有该文件全部的权限.

上面说了 chmod指令的如何使用,那么接下来我们就可以对服务器的文件使用chmod 664 file指令,然后降低文件访问的权限等级.使全部用户都拥有文件的访问权限.但是问题来了,难道用户上传一次,我们就需要手动修改一次文件的权限,这显然是不正确的,那么我们该怎么办呢?这时候我们就需要提高用户的访问权限了.

升高用户的访问权限

提高用户的访问权限,这里其实是修改Nginx的启动者,我们把启动者设置为最多权限者,那么我们就可以访问到文件了.

首先我们先看是谁启动了Nginx需要用到如下的指令.

ps aux | grep "nginx: worker process" | awk '{print $1}'

这里我已经做了修改,截图如下所示.

本来要是不对Nginx的配置进行任何设置访问的话,那么第一个root应该为nobody,也就是Nginx的启动者.先前已经使用** ls -l file **指令查询了文件的权限情况,root 拥有读写权限,other没有任何权限.所以我们要把启动者改为root即可.

打开Nginx配置文件所在的位置,{nginx}表示你的nginx安装路径.

vi {nginx}/conf/nginx.conf

添加启动者,如下所示.

user root

返回到sbin目录中,准备检测配置文件和重新启动Ngnix.

cd ../sbin/

检测配置文件的正确性

./nginx -t

检测没有任何问题,重新启动

./nginx -s reload

这时候即可正常访问到文件了.

结语

这篇博客算是日常的问题收集吧,整理一下.没什么可多说的,就是搞事.欢迎关注骚栋

作者:神经骚栋

链接:https://www.jianshu.com/p/d8666f2e698f

springboot文件上传服务器,SpringBoot: 浅谈文件上传和访问的坑 (MultiPartFile)相关推荐

  1. nginx 上传文件漏洞_浅谈文件上传漏洞(其他方式绕过总结)

    前言 上一篇文章简单的介绍了绕过客户端检测,现在总结一下其他方式绕过. 正文 1.1 服务端MIME类型检测绕过 检测原理:用户上传文件时,服务器会获取这个文件的MIME值,与事先设置好的进行比对,如 ...

  2. 浅谈云上攻防 --SSRF 漏洞带来的新威胁

    前言 在<浅谈云上攻防--元数据服务带来的安全挑战>一文中,生动形象的为我们讲述了元数据服务所面临的一系列安全问题,而其中的问题之一就是通过SSRF去攻击元数据服务:文中列举了2019年美 ...

  3. 浅谈:飞鸽传书 的TCP/IP原理

    浅谈:飞鸽传书 的TCP/IP原理,adj  兴趣浓厚的 飞鸽传书:见闻广博的,博识的he is hot in mathematics and chemistry  (他数学和化学极好.)复合词语ho ...

  4. 浅谈线上教学--致2019年的那个寒冬

    浅谈线上教学–致2019年的那个寒冬   突如其来的新型冠状病毒感染的肺炎疫情,仿佛给生活按下了暂停键,居家隔离成为这个超长寒假的常态,在家学.在线学成了摆在莘莘学子面前的头等大事.教育部对此高度重视 ...

  5. 大文件上传服务器、支持超大文件HTTP断点续传实践总结

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/ababab12345/ article/details/80490621 最近由于笔者所在的研发集团产品需要,需要支持高性能的 ...

  6. 大文件上传服务器:支持超大文件HTTP断点续传的实现办法

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 来源:blog.csdn.net/ababab12345/a ...

  7. js文件 本地 上传服务器地址,js 本地文件同步服务器地址

    js 本地文件同步服务器地址 内容精选 换一换 用户可以将本地NAS存储中的数据,通过云专线迁移至云上SFS Turbo文件系统中,进行云上业务拓展.此方案通过在云上创建一台Linux操作系统的云服务 ...

  8. 浅谈云上攻防——云服务器攻防矩阵

    前言 云服务器(Cloud Virtual Machine,CVM)是一种较为常见的云服务,为用户提供安全可靠以及高效的计算服务.用户可以灵活的扩展以及缩减计算资源,以适应变化的业务需求.使用云服务器 ...

  9. Android上传文件到Web服务器,PHP接收文件(一)

    Android上传文件到服务器,通常采用构造http协议的方法,模拟网页POST方法传输文件,服务器端可以采用JavaServlet或者PHP来接收要传输的文件.使用JavaServlet来接收文件的 ...

最新文章

  1. Springer投稿 tex上传PDF乱码
  2. java 轻量级map,java Map 遍历速度最优解
  3. php json 美化,php JSON数据格式化(美化)的方法
  4. poj 1704 HDU-4315 阶梯博弈
  5. [凯立德]2013夏季卓豪华版2686-2E23J0Dsp1自适应程序懒人包
  6. 个人博客系统需求文档
  7. wmf和emf格式的图片有什么区别? JPG图片如何转换WMF文件?
  8. 陪集分解的几个简单应用
  9. 6个实例电路,详解雷击浪涌的防护
  10. java 过载_过载保护【转载】
  11. 重阳节PPT模板推荐
  12. 上海公积金网上提取全流程(图文版)在职公积金,离职公积金都可以提取
  13. 【案例】畅捷通T+无生产管理模块情况下按产成品统计直接材料成本
  14. 今年巴菲特的午餐上,躺着流血的地产商
  15. 论文浅尝 - IJCAI2022 | 基于自适应虚词增强的小样本逆关系分类
  16. 解锁AI技能:深度学习利用OCT图像诊断眼内视网膜疾病
  17. 干细胞膜包载鱼精蛋白/胰岛素/5-氟脲嘧啶/盐酸伐昔洛韦纳米药物(细胞膜纳米仿生物)
  18. nyoj 301递推求值 (矩阵+快速幂)
  19. 如何通过百度指数分析用户的真实需求?
  20. 【Axure10视频教程】第九章 设置选中

热门文章

  1. MatConvnet工具箱文档翻译理解(2)
  2. 一个简单的插件框架示例
  3. DEPHI中tform类的构造函数与FORMCREATE的关系
  4. 计算机组成原理知识查漏补缺
  5. SQL语句快速回忆——SQL基础知识点汇总
  6. 用Windows Live Writer离线写博客
  7. springMVC九大组件及一次请求流程
  8. 三星宣布 Linux on DeX:手机秒变 Ubuntu 桌面环境
  9. Unity3d DLL脚本通用解密方法
  10. NDK 交叉编译常用变量