java 上传文件注意事项

1、文件名有特殊字符的情况,所以最好是文件名前台url编码,后台再url解码,这点在下载的时候也一样
2、文件大小一定要设置,spring boot 有默认。
3、文件名校验:
3.1、文件后缀校验
3.2、content-type校验
3.3、通过文件流,校验文件头,真实校验

其中,单纯的文件后缀和content-type校验,容易被绕过,只有文件流才能真实的判断出这个文件是什么类型的。
一般的做法就是先通过后缀过滤,绝大部分请求还是正常人
然后再通过流截取文件头信息,判断文件的真实类型。

特别注意: txt文本文档时没有头的,所以不能通过判断头来过滤,以下是网友的一些建议,摘过来供参考:

bmp,jpg等图象文件,可以判断文件头,来确定它的文件类型
但txt没有文件头的,无法判断它是否是txt文件
所以,只能分析文件中所有数据,看看是不是都是可以显示的字符
如果都是可以显示的字符,说明它可以当作txt文件进行阅读,否则,会有乱码出现
这显然要先了解一下什么是文本类的文件,其实说白了,就是ACSII码文件。二进制文件与文本文件的显著差别在于:二进制文件中可能会出现数目众多的0,而文本文件中则不会有,因为文本文件中除了一些特殊的控制字符(比如\n,\r,\t)以外,都是可见字符。
补充1:
除了.txt文件以外,其它的各种文件似乎都会有二进制文件头,这些文件头都很特别,比如0xFEFE、0xFDFD等等。必须说明的一点是.doc文件严格的说,它不应该是一个文本文件,因为它内部有大量的不可见的控制字符,而且最关键的是,它内部允许包含0,并且它有二进制的头数据块。
如果你真想鉴别所有的,你所期望的文本类文件的话,比如.txt、.doc这些文件,你就必须了解这些文件的文件格式,当然.txt是没有固定格式的,但它有一个特征是,不会含有0。
补充2:
对于unicode的文本文件来说,它也是有文件头的,根据大小尾的不同,分别是FFFE和FEFF,严格的说,unicode的文件,不能说是文本文件。
回到你的补充问题,如果想确认一个文件是不是文本文件,加入说是ANSI的,你可以遍历整个文件,看是否存在0,如果没有那么就是了,如果具有FFFE或者FEFF文件头的unicode文件,那么你所关注的对象是,00,也就是两个连续的0。

个人认为,
要么就是把所有可能的文件后缀都放在那个判断的map中(下面代码中会初始化),然后再拿不到就认为是txt类型
要么就是遍历整个文件,看是否存在0,没有就是txt

下面是相关代码:


@Slf4j
public class FileCheckUtil {// 缓存文件头信息-文件头信息private static final HashMap<String, String> MFILETYPES = new HashMap<String, String>();static {//pdf,word,excel,pptMFILETYPES.put("25504446", "pdf");MFILETYPES.put("255044462D312E", "pdf");MFILETYPES.put("D0CF11E0", "xls");//ppt、doc、xls 2003版本文件MFILETYPES.put("504B0304", "xlsx");//pptx、docx、xlsx 2007以上版本文件// imagesMFILETYPES.put("FFD8FFE0", "jpg");MFILETYPES.put("FFD8FF", "jpg");MFILETYPES.put("89504E47", "png");MFILETYPES.put("47494638", "gif");MFILETYPES.put("49492A00", "tif");MFILETYPES.put("424D", "bmp");// CADMFILETYPES.put("41433130", "dwg");//音视频MFILETYPES.put("57415645", "wav");MFILETYPES.put("41564920", "avi");MFILETYPES.put("2E524D46", "rm");MFILETYPES.put("000001BA", "mpg");MFILETYPES.put("000001B3", "mpg");MFILETYPES.put("6D6F6F76", "mov");MFILETYPES.put("3026B2758E66CF11", "asf");//其他MFILETYPES.put("38425053", "psd");MFILETYPES.put("7B5C727466", "rtf"); // 日记本MFILETYPES.put("3C3F786D6C", "xml");MFILETYPES.put("68746D6C3E", "html");MFILETYPES.put("44656C69766572792D646174653A", "eml"); // 邮件MFILETYPES.put("5374616E64617264204A", "mdb");MFILETYPES.put("252150532D41646F6265", "ps");MFILETYPES.put("52617221", "rar");MFILETYPES.put("4D546864", "mid");MFILETYPES.put("1F8B08", "gz");}public static String getRealFileType(FileInputStream is) {return MFILETYPES.get(getFileHeader(is));}public static String getFileHeader(FileInputStream is) {String value = null;try {byte[] b = new byte[4];/** int read() 从此输入流中读取一个数据字节。int read(byte[] b) 从此输入流中将最多 b.length* 个字节的数据读入一个 byte 数组中。 int read(byte[] b, int off, int len)* 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。*/int read = is.read(b, 0, b.length);log.debug("read:{}", read);value = bytesToHexString(b);} catch (Exception e) {} finally {if (null != is) {try {is.close();} catch (IOException e) {}}}return value;}private static String bytesToHexString(byte[] src) {StringBuilder builder = new StringBuilder();if (src == null || src.length <= 0) {return null;}String hv;for (int i = 0; i < src.length; i++) {// 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式,并转换为大写hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();if (hv.length() < 2) {builder.append(0);}builder.append(hv);}log.debug("builder.toString()={}", builder.toString());return builder.toString();}public static void main(String[] args) throws Exception {//        final String fileType = getRealFileType(new FileInputStream("D:\\ccc2007.doc"));
//        System.out.println(fileType);}
}

正式的controller:

 //提前定义支持的后缀类型private static final List<String> FILETYPELIST = Arrays.asList("txt", "doc", "docx", "xls", "xlsx", "pdf");@PostMapping(value = "/upload")public BaseResponseDTO uploadFile(@RequestParam("file") MultipartFile file) throws IOException {BaseResponseDTO data = checkFile(file);if (data != null) {return data;}// 获取文件名String originalFilename = file.getOriginalFilename();long now = System.currentTimeMillis();//文件名是以时间戳_真实文件名存储的originalFilename = now + "_" + originalFilename;// 设置文件存储路径String filePath = "/app/upload/";String path = filePath + originalFilename;File dest = new File(path);file.transferTo(dest);// 文件写入return new BaseResponseDTO<>(HTTPState.OK.getCode(), HTTPState.OK.getMsg(), originalFilename);}private String checkFile(MultipartFile file) throws IOException {//校验文件为空if (file.isEmpty()) {return "error";}//简单校验后缀String fileName = file.getOriginalFilename();if (fileName != null) {String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);log.debug("suffix:" + suffix);if (!FILETYPELIST.contains(suffix)) {return "error";}}//校验文件真实类型String fileType = FileCheckUtil.getRealFileType((FileInputStream) file.getInputStream());log.debug("fileType:" + fileType);if (fileType != null && !FILETYPELIST.contains(fileType)) {return "error";}return null;}

java 上传文件注意事项相关推荐

  1. java上传文件功能_Java MemoryMapped文件的功能

    java上传文件功能 Java MemoryMapped文件的功能 在JDK 1.4中,内存映射文件的一个有趣功能被添加到Java中,该功能允许将任何文件映射到OS内存以进行有效读取. 内存映射文件可 ...

  2. java 上传文件到服务器_java上传文件到OSS云服务器(二)

    上篇文章中已经把接口端和service业务层写了,这次就把OSS上传文件的工具类补上. 一.首先配置好OSS服务器各项节点,这是在springboot中appliaction.yml配置文件中的写法. ...

  3. JAVA上传文件图片到服务器保存

    这里我记录一个比较简单方便操作的JAVA上传文件图片到服务器并且保存! 首先是页面 html的   我这是提交一个文件和类型 <div style="border: 1px solid ...

  4. Java上传文件到minio

    Minio 是个基于 Golang 编写的开源对象存储套件,基于Apache License v2.0开源协议,虽然轻量,却拥有着不错的性能.而且学习成本低,安装运维简单,开箱即用,提供 Java 客 ...

  5. Java上传文件保存到指定路径

    Java上传文件保存到指定路径 上代码 @PostMapping("/file-upload")@ApiOperation(value = "上传swagger.json ...

  6. java上传文件到远程服务器(一)---HttpURLConnection方式

    我们在之前的文章 JavaWeb静态资源分离思路 中已经了解到要把文件上传到静态资源服务器有三种方式: java上传文件到ftp服务器(这个方案需要在静态资源服务器安装ftp服务) java使用Htt ...

  7. java上传文件到服务器,java上传文件到云服务器

    java上传文件到云服务器 内容精选 换一换 安装传输工具在本地主机和Windows云服务器上分别安装数据传输工具,将文件上传到云服务器.例如QQ.exe.在本地主机和Windows云服务器上分别安装 ...

  8. java上传文件图片到服务器保存,Java上传文件图片到服务器的方法

    这里我记录一个比较简单方便操作的java上传文件图片到服务器并且保存,具体内容如下 首先是页面html的   我这是提交一个文件和类型 我是添加一张临时图片得到微信的media_id保存数据库! en ...

  9. Java上传文件到数据库

    Java上传文件到数据库 首先在开始本文之前推荐一篇我非常喜欢的博主--孤傲苍狼的一篇相关博文. JavaWeb学习总结(五十)--文件上传和下载 http://www.cnblogs.com/xdp ...

最新文章

  1. 《C程序猿从校园到职场》勘误
  2. 匿名内部类的简单使用
  3. return 关键字 c
  4. 备忘之--apache下为站点添加错误页面
  5. 光流 | OpenCV3实现LK Optical Flow(代码类)
  6. ctrl导致开机弹出计算机,Win7系统开机黑屏提示Press Ctrl+Alt+Del to restart如何解决...
  7. [机器学习] 模型评价参数,准确率,召回率,F1-score
  8. uva 1625——Color Length
  9. Zookeeper----基本原理
  10. [告知]在评论中发布广告者必删!
  11. C# 输入选择文件夹
  12. 第二章 HTML5存储 JSON格式
  13. 试题2 入门训练 圆的面积
  14. 在Migration中操作新添加的字段
  15. 网上很多NV21数据直接使用BitmapFactory的代码是错误的
  16. python opencv读取图像并生成plt文件
  17. 海思Hi3519/Hi3559-使用cmake编译sdk代码
  18. JAVA版商城 B2B2C商城 多用户入驻商城 直播带货商城 新零售商城 o2o商城 拼团商城 分销商城 直播商城 短视频商城 VR商城 社交电商 分销商城 saas商城spring cloud商城
  19. 设计一个分数类java_Java 有理数类 分数类 Rational类的设计与实现
  20. C --cp2 类似cat工具的小程序。

热门文章

  1. 算法(二叉树-矩阵-堆排序)
  2. Linux或者Mac解压乱码问题
  3. launchMode
  4. git编译安装与常见问题解决
  5. page.ClientScript.RegisterStartupScript
  6. 【转】 VC MFC 钩子 实现 自绘 窗体 标题栏 非客户区
  7. .net打包自动安装数据库
  8. 操作系统学习笔记-2.1.5线程概念和多线程模型
  9. 操作系统学习笔记-05-中断和异常
  10. Hadoop相关技术