日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 上传文件注意事项

發布時間:2024/7/23 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 上传文件注意事项的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。