java 上传文件注意事项
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 上传文件注意事项相关推荐
- java上传文件功能_Java MemoryMapped文件的功能
java上传文件功能 Java MemoryMapped文件的功能 在JDK 1.4中,内存映射文件的一个有趣功能被添加到Java中,该功能允许将任何文件映射到OS内存以进行有效读取. 内存映射文件可 ...
- java 上传文件到服务器_java上传文件到OSS云服务器(二)
上篇文章中已经把接口端和service业务层写了,这次就把OSS上传文件的工具类补上. 一.首先配置好OSS服务器各项节点,这是在springboot中appliaction.yml配置文件中的写法. ...
- JAVA上传文件图片到服务器保存
这里我记录一个比较简单方便操作的JAVA上传文件图片到服务器并且保存! 首先是页面 html的 我这是提交一个文件和类型 <div style="border: 1px solid ...
- Java上传文件到minio
Minio 是个基于 Golang 编写的开源对象存储套件,基于Apache License v2.0开源协议,虽然轻量,却拥有着不错的性能.而且学习成本低,安装运维简单,开箱即用,提供 Java 客 ...
- Java上传文件保存到指定路径
Java上传文件保存到指定路径 上代码 @PostMapping("/file-upload")@ApiOperation(value = "上传swagger.json ...
- java上传文件到远程服务器(一)---HttpURLConnection方式
我们在之前的文章 JavaWeb静态资源分离思路 中已经了解到要把文件上传到静态资源服务器有三种方式: java上传文件到ftp服务器(这个方案需要在静态资源服务器安装ftp服务) java使用Htt ...
- java上传文件到服务器,java上传文件到云服务器
java上传文件到云服务器 内容精选 换一换 安装传输工具在本地主机和Windows云服务器上分别安装数据传输工具,将文件上传到云服务器.例如QQ.exe.在本地主机和Windows云服务器上分别安装 ...
- java上传文件图片到服务器保存,Java上传文件图片到服务器的方法
这里我记录一个比较简单方便操作的java上传文件图片到服务器并且保存,具体内容如下 首先是页面html的 我这是提交一个文件和类型 我是添加一张临时图片得到微信的media_id保存数据库! en ...
- Java上传文件到数据库
Java上传文件到数据库 首先在开始本文之前推荐一篇我非常喜欢的博主--孤傲苍狼的一篇相关博文. JavaWeb学习总结(五十)--文件上传和下载 http://www.cnblogs.com/xdp ...
最新文章
- 《C程序猿从校园到职场》勘误
- 匿名内部类的简单使用
- return 关键字 c
- 备忘之--apache下为站点添加错误页面
- 光流 | OpenCV3实现LK Optical Flow(代码类)
- ctrl导致开机弹出计算机,Win7系统开机黑屏提示Press Ctrl+Alt+Del to restart如何解决...
- [机器学习] 模型评价参数,准确率,召回率,F1-score
- uva 1625——Color Length
- Zookeeper----基本原理
- [告知]在评论中发布广告者必删!
- C# 输入选择文件夹
- 第二章 HTML5存储 JSON格式
- 试题2 入门训练 圆的面积
- 在Migration中操作新添加的字段
- 网上很多NV21数据直接使用BitmapFactory的代码是错误的
- python opencv读取图像并生成plt文件
- 海思Hi3519/Hi3559-使用cmake编译sdk代码
- JAVA版商城 B2B2C商城 多用户入驻商城 直播带货商城 新零售商城 o2o商城 拼团商城 分销商城 直播商城 短视频商城 VR商城 社交电商 分销商城 saas商城spring cloud商城
- 设计一个分数类java_Java 有理数类 分数类 Rational类的设计与实现
- C --cp2 类似cat工具的小程序。