首页 > 编程 > Java > 正文

SpringBoot文件上传控制及Java 获取和判断文件头信息

2019-11-26 10:42:21
字体:
来源:转载
供稿:网友

之前在使用SpringBoot进行文件上传时,遇到了很多问题。于是在翻阅了很多的博文之后,总算将上传功能进行了相应的完善,便在这里记录下来,供自己以后查阅。

首先,是建立一个标准的SpringBoot 的工程,这里使用的IDE是Intellij Idea,为了方便配置,将默认的配置文件替换为了application.yml。

1.在index.html中进行文件上传功能,这里使用的文件上传方式是ajax,当然也可以按照自己的具体要求使用传统的表单文件上传。

<!DOCTYPE html> <html lang="en"> <head>  <meta charset="UTF-8">  <title>上传测试</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()">上传</button>  <progress id="progressBar" value="0" max="100"></progress>  <script>   function doUpload() {    var fileObj = document.getElementById("file").files[0]; // js 获取文件对象    var FileController = "/upload";     // 接收上传文件的后台地址    // FormData 对象    var form = new FormData();    form.append("file",fileObj);    // XMLHttpRequest 对象    var xhr = new XMLHttpRequest();    //为请求添加返回处理函数    xhr.onreadystatechange=function () {     if(this.readyState == 4 && this.status == 200){      var b = this.responseText;      if(b == "success"){       alert("上传成功!");      }else{       alert("上传失败!");      }     }    };    xhr.open("post", FileController, true);    //使用进度条记录上传进度    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.在MainController添加文件上传的API,并返回上传结果

@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);   // 保存   try {    file.transferTo(saveFile);    return "success";   } catch (Exception e) {    e.printStackTrace();    return "fail";   }  } 

这时,我们进行测试,就可以发现,文件上传已经完成了。

很多时候,我们在进行文件上传时,特别是向普通用户开放文件上传功能时,需要对上传文件的格式进行控制,以防止黑客将病毒脚本上传。单纯的将文件名的类型进行截取的方式非常容易遭到破解,上传者只需要将病毒改换文件名便可以完成上传。

这时候我们可以读取文件的十六进制的文件头,来判断文件真正的格式。

因为我们发现,在我们读取文件的二进制数据并将其转换为十六进制时,同类型文件的文件头数据是相同的,即使改变了其后缀,这个数据也不会改变,例如,png文件的文件头为“89504E47”。

首先,我们将文件的数据进行读取

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();  } } 

然后在文件上传的api中进行调用

FileUtil.getFileHeader(file) 

这时候,我们只需要进行简单的字符串比对,判断调用的返回值是否为“89504E47”,就可以知道上传的是否为png文件。

下面看下 Java 获取和判断文件头信息

 import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; /**  * 获取和判断文件头信息  *  * @author Sud  *  */ public class GetTypeByHead {  // 缓存文件头信息-文件头信息  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"); // 日记本   mFileTypes.put("3C3F786D6C", "xml");   mFileTypes.put("68746D6C3E", "html");   mFileTypes.put("44656C69766572792D646174653A", "eml"); // 邮件   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");  }  /**   * 根据文件路径获取文件头信息   *   * @param filePath   *   文件路径   * @return 文件头信息   */  public static String getFileType(String filePath) {   System.out.println(getFileHeader(filePath));   System.out.println(mFileTypes.get(getFileHeader(filePath)));   return mFileTypes.get(getFileHeader(filePath));  }  /**   * 根据文件路径获取文件头信息   *   * @param filePath   *   文件路径   * @return 文件头信息   */  public static String getFileHeader(String filePath) {   FileInputStream is = null;   String value = null;   try {    is = new FileInputStream(filePath);    byte[] b = new byte[4];    /*     * int read() 从此输入流中读取一个数据字节。 int read(byte[] b) 从此输入流中将最多 b.length     * 个字节的数据读入一个 byte 数组中。 int read(byte[] b, int off, int len)     * 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。     */    is.read(b, 0, b.length);    value = bytesToHexString(b);   } catch (Exception e) {   } finally {    if (null != is) {     try {      is.close();     } catch (IOException e) {     }    }   }   return value;  }  /**   * 将要读取文件头信息的文件的byte数组转换成string类型表示   *   * @param src   *   要读取文件头信息的文件的byte数组   * @return 文件头信息   */  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);   }   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);  } } 

总结

以上所述是小编给大家介绍的SpringBoot文件上传控制及Java 获取和判断文件头信息,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表