一、SpringBoot上传文件到数据库
文件上传到数据库是一个常见的需求,可以用于保存用户上传的图片等二进制文件。在SpringBoot中,使用Spring提供的Hibernate框架,配合Spring的JdbcTemplate实现文件上传到数据库。
首先,需要定义数据库表来存储上传的文件信息,包括文件ID,文件名,文件类型,文件大小和文件内容等字段。创建对应的Java类,并添加注解来映射数据库表和字段:
@Entity @Table(name = "t_file") public class File { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; //文件ID @Column(name = "file_name") private String fileName; //文件名 @Column(name = "file_type") private String fileType; //文件类型 @Column(name = "file_size") private Long fileSize; //文件大小 @Lob @Basic(fetch = FetchType.LAZY) @Column(name = "file_content") private byte[] fileContent; //文件内容 //省略get/set方法 }
接下来,编写控制器来实现文件上传到数据库。使用Spring的MultipartFile接口来处理上传的文件,通过JdbcTemplate来将文件信息存储到数据库。代码如下:
@RestController @RequestMapping("/file") public class FileController { @Autowired private JdbcTemplate jdbcTemplate; @PostMapping("/upload") public String upload(@RequestParam("file") MultipartFile file) throws IOException { String fileName = file.getOriginalFilename(); String fileType = file.getContentType(); Long fileSize = file.getSize(); byte[] fileContent = file.getBytes(); String sql = "INSERT INTO t_file (file_name, file_type, file_size, file_content) VALUES (?, ?, ?, ?)"; jdbcTemplate.update(sql, fileName, fileType, fileSize, fileContent); return "file uploaded successfully"; } }
在浏览器中访问http://localhost:8080/file/upload,上传文件即可保存到数据库中。这样就实现了上传文件到数据库的功能。
二、SpringBoot上传文件和参数
在实际开发中,文件上传往往需要与其他表单数据一起提交,比如上传用户头像时,还需要同时提交用户名和密码等信息。SpringBoot也支持同时上传文件和参数。
可以使用@RequestParam注解来获取上传的文件和表单参数,示例代码如下:
@PostMapping("/uploadWithParam") public String uploadWithParam(@RequestParam("file") MultipartFile file, @RequestParam("username") String username, @RequestParam("password") String password) throws IOException { String fileName = file.getOriginalFilename(); String fileType = file.getContentType(); Long fileSize = file.getSize(); byte[] fileContent = file.getBytes(); //保存文件到数据库或服务器 //省略代码 return "file uploaded successfully with user "+username+" and password "+password; }
在浏览器中访问http://localhost:8080/file/uploadWithParam,同时上传文件和参数即可。
三、SpringBoot多线程上传文件
当上传的文件较大时,可能需要较长时间才能完成上传。为了提高上传效率,可以使用多线程技术来实现文件的分块上传。SpringBoot也支持多线程上传文件。
可以使用Java的Executor框架来创建线程池,将文件分块后,将每一块交给线程池中的线程处理。当所有线程都执行完毕后,将文件块合并成完整的文件。示例代码如下:
@PostMapping("/uploadMultiThread") public String uploadMultiThread(@RequestParam("file") MultipartFile file) throws IOException, ExecutionException, InterruptedException { ExecutorService executor = Executors.newFixedThreadPool(3); String fileName = file.getOriginalFilename(); String fileType = file.getContentType(); Long fileSize = file.getSize(); byte[] fileContent = file.getBytes(); int chunkSize = 1024*1024; //每个线程上传1MB的数据 int numChunks = (int)Math.ceil(fileSize/chunkSize); //计算要上传的线程数 List> futures = new ArrayList<>(); for (int i = 0; i < numChunks; i++) { int startIndex = i*chunkSize; int endIndex = Math.min(startIndex+chunkSize, (int)fileSize); byte[] subFileContent = Arrays.copyOfRange(fileContent, startIndex, endIndex); futures.add(executor.submit(new FileUploadTask(i, subFileContent))); } List results = new ArrayList<>(); for (Future future : futures) { results.add(future.get()); } executor.shutdown(); //将所有分块合并为完整的文件,并保存到数据库或服务器 //省略代码 return "file uploaded successfully with multi-threading"; } private class FileUploadTask implements Callable { private int index; private byte[] fileContent; public FileUploadTask(int index, byte[] fileContent) { this.index = index; this.fileContent = fileContent; } @Override public String call() throws Exception { //上传分块文件 //省略代码 return "chunk "+index+" uploaded successfully"; } }
在浏览器中访问http://localhost:8080/file/uploadMultiThread,启动多线程上传文件。
四、SpringBoot上传文件到指定文件夹
有时候,需要将上传的文件保存到指定的文件夹中。SpringBoot提供了文件系统相关的API来实现上传文件到指定文件夹。
可以使用Spring的Resource接口以及Java的File类来指定存储文件的文件夹。示例代码如下:
@RestController @RequestMapping("/file") public class FileController { @Value("${upload.path}") //从配置文件中读取文件夹路径 private String uploadPath; @PostMapping("/uploadToFile") public String uploadToFile(@RequestParam("file") MultipartFile file) throws IOException { String fileName = file.getOriginalFilename(); String fileType = file.getContentType(); Long fileSize = file.getSize(); byte[] fileContent = file.getBytes(); File folder = new File(uploadPath); if (!folder.exists()) { folder.mkdirs(); //如果文件夹不存在,则创建文件夹 } Path filePath = Paths.get(uploadPath, fileName); Files.write(filePath, fileContent); return "file uploaded successfully to "+uploadPath; } }
在配置文件application.yml中添加文件夹路径:
upload: path: /tmp/upload
在浏览器中访问http://localhost:8080/file/uploadToFile,上传的文件即可保存到指定文件夹中。
五、SpringBoot异步上传文件
异步上传文件可以提高网站的性能和响应速度,由于上传操作会耗费一定时间,异步上传可以让服务器在上传过程中处理其他请求,提升系统的并发处理能力。SpringBoot提供了异步上传文件的API。
可以使用Spring的@Async注解来将上传文件的方法标记为异步执行。示例代码如下:
@RestController @RequestMapping("/file") public class FileController { @Autowired private AsyncFileUploader asyncFileUploader; @PostMapping("/uploadAsync") public String uploadAsync(@RequestParam("file") MultipartFile file) { String fileName = file.getOriginalFilename(); String fileType = file.getContentType(); Long fileSize = file.getSize(); byte[] fileContent = null; try { fileContent = file.getBytes(); } catch (IOException e) { e.printStackTrace(); } asyncFileUploader.upload(fileName, fileType, fileSize, fileContent); return "file uploaded asynchronously"; } } @Service public class AsyncFileUploader { @Async public void upload(String fileName, String fileType, Long fileSize, byte[] fileContent) { //上传文件 //省略代码 } }
在浏览器中访问http://localhost:8080/file/uploadAsync,上传文件即可异步上传。
六、SpringBoot上传文件和图片
上传图片是网站开发中的一个常见需求,SpringBoot也支持上传图片。可以通过修改前面的上传文件的代码,在上传文件时添加图片压缩等处理逻辑,实现上传图片的功能。
例如,可以使用Java的ImageIO类来将上传的图片进行压缩和缩放,代码如下:
@PostMapping("/uploadImage") public String uploadImage(@RequestParam("image") MultipartFile image) throws IOException { String imageName = image.getOriginalFilename(); String imageType = image.getContentType(); Long imageSize = image.getSize(); byte[] imageContent = image.getBytes(); //压缩和缩放图片 BufferedImage bufferedImage = ImageIO.read(image.getInputStream()); int width = bufferedImage.getWidth(); int height = bufferedImage.getHeight(); if (width > 1024 || height > 1024) { float scale = Math.min(1024f/width, 1024f/height); width = (int)(width*scale); height = (int)(height*scale); } Image scaledImage = bufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH); BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = resizedImage.createGraphics(); g2d.drawImage(scaledImage, 0, 0, null); g2d.dispose(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(resizedImage, "JPEG", outputStream); imageContent = outputStream.toByteArray(); //保存图片到数据库或服务器 //省略代码 return "image uploaded successfully"; }
在浏览器中访问http://localhost:8080/file/uploadImage,上传图片即可实现上传图片的功能。
七、SpringBoot批量上传文件
有时候,需要同时上传多个文件,SpringBoot也支持批量上传文件。可以使用Spring的MultipartHttpServletRequest类来获取所有上传的文件,然后逐个保存到数据库或服务器。示例代码如下:
@PostMapping("/uploadBatch") public String uploadBatch(HttpServletRequest request) throws IOException { MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; Iteratoriterator = multiRequest.getFileNames(); while (iterator.hasNext()) { MultipartFile file = multiRequest.getFile(iterator.next()); String fileName = file.getOriginalFilename(); String fileType = file.getContentType(); Long fileSize = file.getSize(); byte[] fileContent = file.getBytes(); //保存文件到数据库或服务器 //省略代码 } return "batch uploaded successfully"; }
在浏览器中访问http://localhost:8080/file/uploadBatch,同时上传多个文件即可实现批量上传文件的功能。