I encountered many problems when using SpringBoot to upload files. So after reading a lot of blog posts, I finally improved the upload function accordingly, so I recorded it here for my future review.
First, we are creating a standard SpringBoot project. The IDE used here is Intellij Idea. For easy configuration, the default configuration file is replaced with application.yml.
1. The file upload function is performed in index.html. The file upload method used here is ajax. Of course, you can also use traditional form files to upload according to your specific requirements.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Upload test</title> <script type="text/javascript" src="js/jquery-3.2.1.min.js"></script> </head> <body> <input id="file" type="file" name="file"/> <br/> <button id="upload" onclick="doUpload()">Upload</button> <progress id="progressBar" value="0" max="100"></progress> <script> function doUpload() { var fileObj = document.getElementById("file").files[0]; // js Get file object var FileController = "/upload"; // Receive the background address of uploaded file// FormData object var form = new FormData(); form.append("file",fileObj); // XMLHttpRequest object var xhr = new XMLHttpRequest(); // Add return processing function xhr.onreadystatechange=function () { if(this.readyState == 4 && this.status == 200){ var b = this.responseText; if(b == "success"){ alert("upload successful!"); }else{ alert("upload failed!"); } } } }; xhr.open("post", FileController, true); //Use progress bar to record the upload progress xhr.upload.addEventListener("progress", progressFunction, false); xhr.send(form); } function progressFunction(evt) { var progressBar = document.getElementById("progressBar"); var percentageDiv = document.getElementById("percentage"); if (evt.lengthComputable) { progressBar.max = evt.total; progressBar.value = evt.loaded; percentageDiv.innerHTML = Math.round(evt.loaded / evt.total * 100) + "%"; } } </script> </body> </html> 2. Add file upload API in MainController and return upload results
@PostMapping("/upload") @ResponseBody public String upload(HttpServletRequest request, @RequestParam("file") MultipartFile file) { String path = "E://upload//"; String fileName = file.getOriginalFilename(); System.out.println(fileName); File targetFile = new File(path); if (!targetFile.exists()) { targetFile.mkdirs(); } File saveFile=new File(path+fileName); // Save try { file.transferTo(saveFile); return "success"; } catch (Exception e) { e.printStackTrace(); return "fail"; } }At this time, we conduct tests and we can find that the file upload has been completed.
Many times, when we upload files, especially when opening the file upload function to ordinary users, we need to control the format of the uploaded file to prevent hackers from uploading virus scripts. The way of simply intercepting the file name type is very easy to crack. The uploader only needs to change the virus to file name to complete the upload.
At this time, we can read the hexadecimal file header of the file to determine the true format of the file.
Because we found that when we read the binary data of the file and convert it to hexadecimal, the file header data of the same type of file is the same, and even if its suffix is changed, this data will not change. For example, the file header of the png file is "89504E47".
First, we read the file data
public class FileUtil { public static String getFileHeader( MultipartFile file) { InputStream is = null; String value = null; try { is = file.getInputStream(); byte[] b = new byte[4]; is.read(b, 0, b.length); 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++) { hv = Integer.toHexString(src[i] & 0xFF).toUpperCase(); if (hv.length() < 2) { builder.append(0); } builder.append(hv); } System.out.println(builder.toString()); return builder.toString(); } }Then make the call in the file uploaded API
FileUtil.getFileHeader(file)
At this time, we only need to perform a simple string comparison and determine whether the call's return value is "89504E47", and we can know whether the uploaded is a png file.
Let's take a look at Java to obtain and judge file header information
import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; /** * Get and judge file header information* * @author Sud * */ public class GetTypeByHead { // Cache file header information - file header information public static final HashMap<String, String> mFileTypes = new HashMap<String, String>(); static { // images mFileTypes.put("FFD8FF", "jpg"); mFileTypes.put("89504E47", "png"); mFileTypes.put("47494638", "gif"); mFileTypes.put("49492A00", "tif"); mFileTypes.put("424D", "bmp"); // mFileTypes.put("41433130", "dwg"); // CAD mFileTypes.put("38425053", "psd"); mFileTypes.put("7B5C727466", "rtf"); // diary mFileTypes.put("3C3F786D6C", "xml"); mFileTypes.put("68746D6C3E", "html"); mFileTypes.put("44656C69766572792D646174653A", "eml"); // Email mFileTypes.put("D0CF11E0", "doc"); mFileTypes.put("5374616E64617264204A", "mdb"); mFileTypes.put("252150532D41646F6265", "ps"); mFileTypes.put("255044462D312E", "pdf"); mFileTypes.put("504B0304", "docx"); mFileTypes.put("52617221", "rar"); 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("4D546864", "mid"); mFileTypes.put("1F8B08", "gz"); mFileTypes.put("4D5A9000", "exe/dll"); mFileTypes.put("75736167", "txt"); } /** * Get file header information based on file path* * @param filePath * File path * @return File header information */ public static String getFileType(String filePath) { System.out.println(getFileHeader(filePath)); System.out.println(mFileTypes.get(getFileHeader(filePath))); return mFileTypes.get(getFileHeader(filePath)); } /** * Get file header information based on file path * * @param filePath * File path * @return File header information */ public static String getFileHeader(String filePath) { FileInputStream is = null; String value = null; try { is = new FileInputStream(filePath); byte[] b = new byte[4]; /* * int read() Read a data byte from this input stream. int read(byte[] b) Read up to a byte array of data of b.length * bytes from this input stream. int read(byte[] b, int off, int len) * Read up to len bytes of data from this input stream into a byte array. */ is.read(b, 0, b.length); value = bytesToHexString(b); } catch (Exception e) { } finally { if (null != is) { try { is.close(); } catch (IOException e) { } } } return value; } /** * Convert the byte array of the file to read the file header information into a string type representing * * @param src * byte array of the file to read the file header information* @return File header information*/ 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++) { // Return a string representation of an integer parameter in hexadecimal (base 16) unsigned integer and convert it to uppercase hv = Integer.toHexString(src[i] & 0xFF).toUpperCase(); if (hv.length() < 2) { builder.append(0); } builder.append(hv); } System.out.println(builder.toString()); return builder.toString(); } public static void main(String[] args) throws Exception { final String fileType = getFileType("D://Ry4S_JAVA.dll"); System.out.println(fileType); } }Summarize
The above is the SpringBoot file upload control and Java acquisition and judgment file header information introduced to you. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support to Wulin.com website!