java 上传文件注意事项 您所在的位置:网站首页 vs多文件编程注意事项 java 上传文件注意事项

java 上传文件注意事项

2024-06-04 23:51| 来源: 网络整理| 查看: 265

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 MFILETYPES = new HashMap(); static { //pdf,word,excel,ppt MFILETYPES.put("25504446", "pdf"); MFILETYPES.put("255044462D312E", "pdf"); MFILETYPES.put("D0CF11E0", "xls");//ppt、doc、xls 2003版本文件 MFILETYPES.put("504B0304", "xlsx");//pptx、docx、xlsx 2007以上版本文件 // images MFILETYPES.put("FFD8FFE0", "jpg"); MFILETYPES.put("FFD8FF", "jpg"); MFILETYPES.put("89504E47", "png"); MFILETYPES.put("47494638", "gif"); MFILETYPES.put("49492A00", "tif"); MFILETYPES.put("424D", "bmp"); // CAD MFILETYPES.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 // 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式,并转换为大写 hv = Integer.toHexString(src[i] & 0xFF).toUpperCase(); if (hv.length() // final String fileType = getRealFileType(new FileInputStream("D:\\ccc2007.doc")); // System.out.println(fileType); } } 正式的controller: //提前定义支持的后缀类型 private static final List 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; }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有