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

之前在使用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 获取和判断文件头信息,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • springboot的java配置方式(实例讲解)

    1.创建User实体类. @Data public class User { private String username; private String password; private Integer age; } 2.创建UserDao用于模拟数据库交互. public class UserDao{ public List<User> queryUserList() { List<User> result = new ArrayList<User>(); //

  • Java框架搭建之Maven、Mybatis、Spring MVC整合搭建(图文)

    本文主要介绍了Java框架搭建之Maven.Mybatis.Spring MVC整合搭建(图文),分享给大家,具体如下: SSM(Spring+SpringMVC+Mybatis),目前较为主流的企业级架构方案.标准的MVC设计模式,将整个系统划分为显示层.Controller层.Service层.Dao层四层,使用SpringMVC负责请求的转发和视图管理,Spring实现业务对象管理, MyBatis作为数据对象持久化引擎. 框架详情 Spring 是一个轻量级的Java开发框架,它是为了解

  • Java中Spring WebSocket详解

    首先 pom.xml <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.8.RELEASE</version> </parent> <dependency> <groupId>org.apache.com

  • spring的@Transactional注解用法解读

    概述 事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性. Spring Framework对事务管理提供了一致的抽象,其特点如下: 为不同的事务API提供一致的编程模型,比如JTA(Java Transaction API), JDBC, Hibernate, JPA(Java Persistence API和JDO(Java Data Objects) 支持声明式事务管理,特别是基于注解的声明式事务管理,简单易用 提供比其他事务API如JTA更简单的编程式事务管

  • 通过Spring Shell 开发 Java 命令行应用

    提到 Java,大家都会想到 Java 在服务器端应用开发中的使用.实际上,Java 在命令行应用的开发中也有一席之地.在很多情况下,相对于图形用户界面来说,命令行界面响应速度快,所占用的系统资源少.在与用户进行交互的场景比较单一时,命令行界面是更好的选择.命令行界面有其固定的交互模式.通常是由用户输入一系列的参数,在执行之后把相应的结果在控制台输出.命令行应用通常需要处理输入参数的传递和验证.输出结果的格式化等任务.Spring Shell 可以帮助简化这些常见的任务,让开发人员专注于实现应用

  • java springmvc实现验证码功能

    本文实例为大家分享了springmvc实现验证码功能展示的具体代码,供大家参考,具体内容如下 先看效果图: 思路: 首先验证码是一张图片,是一张有着随机字母.数字.图案等组成的图片,所以这图片肯定不是固定不变的,肯定是由后端随机制造出来的,前端用img的src去不断访问这个制造的方法. 第一步:前端页面编写 登录使用的是ajax方法,所以使用的是调用点击事件进行,验证码的图片放在a标签中是为了方便点击变换验证码.显示图片用的是img的src属性,因为使用的是spingmvc所以调用后台方法使用a

  • java使用spring实现读写分离的示例代码

    最近上线的项目中数据库数据已经临近饱和,最大的一张表数据已经接近3000W,百万数据的表也有几张,项目要求读数据(select)时间不能超过0.05秒,但实际情况已经不符合要求,explain建立索引,使用redis,ehcache缓存技术也已经满足不了要求,所以开始使用读写分离技术,可能以后数据量上亿或者更多的时候,需要再去考虑分布式数据库的部署,但目前来看,读写分离+缓存+索引+表分区+sql优化+负载均衡是可以满足亿级数据量的查询工作的,现在就一起来看一下亲测可用的使用spring实现读写

  • Java编程实现springMVC简单登录实例

    Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1,Struts2等. 1.新建web项目:springmvc 2.导入springmvc需要的jar包 3.配置web.xml文件(核心代码)

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

    之前在使用SpringBoot进行文件上传时,遇到了很多问题.于是在翻阅了很多的博文之后,总算将上传功能进行了相应的完善,便在这里记录下来,供自己以后查阅. 首先,是建立一个标准的SpringBoot 的工程,这里使用的IDE是Intellij Idea,为了方便配置,将默认的配置文件替换为了application.yml. 1.在index.html中进行文件上传功能,这里使用的文件上传方式是ajax,当然也可以按照自己的具体要求使用传统的表单文件上传. <!DOCTYPE html> &l

  • Java实现的获取和判断文件头信息工具类用法示例

    本文实例讲述了Java实现的获取和判断文件头信息工具类用法.分享给大家供大家参考,具体如下: package test; import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; /** * 获取和判断文件头信息 * * @author Sud * */ public class GetTypeByHead { // 缓存文件头信息-文件头信息 public static final

  • 详解SpringBoot文件上传下载和多文件上传(图文)

    最近在学习SpringBoot,以下是最近学习整理的实现文件上传下载的Java代码: 1.开发环境: IDEA15+ Maven+JDK1.8 2.新建一个maven工程: 3.工程框架 4.pom.xml文件依赖项 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation

  • SpringBoot 文件上传和下载的实现源码

    本篇文章介绍SpringBoot的上传和下载功能. 一.创建SpringBoot工程,添加依赖 compile("org.springframework.boot:spring-boot-starter-web") compile("org.springframework.boot:spring-boot-starter-thymeleaf") 工程目录为: Application.java 启动类 package hello; import org.springf

  • Springboot文件上传出现找不到指定系统路径的解决

    目录 Springboot文件上传出现找不到指定系统路径 1.问题描述 2.问题分析 3.问题解决方案 SpringBoot 上传文件时本地路径无效 错误产生的原因 解决方式有以下几点 Springboot文件上传出现找不到指定系统路径 1.问题描述 关键字:SpringMVC 4.2.4.Spring Boot 1.3.1.Servlet 3.0.文件上传 报错信息: java.io.IOException: java.io.FileNotFoundException: /tmp/tomcat

  • SpringBoot文件上传与下载功能实现详解

    目录 前言 1.引入Apache Commons FileUpload组件依赖 2.设置上传文件大小限制 3.创建选择文件视图页面 4.创建控制器 5.创建文件下载视图页面 前言 文件上传与下载是Web应用开发中常用的功能之一,在实际的Web应用开发中,为了成功上传文件,必须将表单的method设置为post,并将enctype设置为multipart/form-data 只有这样设置,浏览器才能将所选文件的二进制数据发送给服务器 从Servlet3.0开始,就提供了处理文件上传的方法,但这种文

  • 解决SpringBoot文件上传临时目录找不到的问题

    SpringBoot文件上传临时目录问题 我相信大家在把项目部署到服务器上面时候都会遇到这样一个问题: org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request;nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.133776721859504205

  • springboot文件上传保存路径的问题

    目录 springboot文件上传保存路径 配置代码如下 Springboot上传文件的问题(上传到本地文件夹中) 先建立一个controller包 静态资源目录如下 springboot文件上传保存路径 最近使用springboot整合富文本编辑器wangeditor,在整合的时候,对于图片上传时候保存路径出现了一些问题,代码如下 @PostMapping("/upload") public Result upload(MultipartFile[] file, HttpServle

  • SpringBoot文件上传同时接收复杂参数的过程详解

    目录 环境信息 问题描述 错误分析 解决方法 简单参数 总结 环境信息 Spring Boot:2.0.8.RELEASE Spring Boot内置的tomcat:tomcat-embed-core 8.5.37 问题描述 收到文件上传的开发工作,要求能适配各种场景,并且各场景的请求参数不一样,因此接收的参数不能是固定的几个字段,要有类似Map的字段来接收动态参数. 拟使用MultipartFile[] files来接收文件列表,用自定义对象UploadFileDto来接收上传参数(里面包含一

  • springboot 文件上传大小配置的方法

    springboot上传文件大小的配置我这里记录两种,一种是设置在配置文件里只有两行代码,一种是加个Bean 首先第一种: application.properties中添加 spring.http.multipart.maxFileSize=10Mb spring.http.multipart.maxRequestSize=10Mb maxFileSize 是单个文件大小 maxRequestSize是设置总上传的数据大小 这就可以了. 根据自己需求定义吧,Mb和Kb都可以,大小写也都随意,L

随机推荐