SpringBoot2:web开发常用功能实现及原理解析-上传与下载

文章目录

一、上传文件

1、前端上传文件给Java接口

Controller接口

此接口支持上传单个文件和多个文件,并保存在本地

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

/**
 * 文件上传测试
 */
@Slf4j
@RestController
public class FileTestController {

	/**
	 * MultipartFile 自动封装上传过来的文件
	 * @param headerImg
	 * @param photos
	 * @return
	 */
	@PostMapping("/upload")
	public String upload(
						 @RequestPart("headerImg") MultipartFile headerImg,
						 @RequestPart("photos") MultipartFile[] photos) throws IOException {

		log.info("上传的信息:headerImg={},photos={}",
				headerImg.getSize(),photos.length);

		if(!headerImg.isEmpty()){
			//保存到文件服务器,OSS服务器
			String originalFilename = headerImg.getOriginalFilename();
			headerImg.transferTo(new File("E:\\workspace\\boot-05-web-01\\headerImg\\"+originalFilename));
		}

		if(photos.length > 0){
			for (MultipartFile photo : photos) {
				if(!photo.isEmpty()){
					String originalFilename = photo.getOriginalFilename();
					photo.transferTo(new File("E:\\workspace\\boot-05-web-01\\photos\\"+originalFilename));
				}
			}
		}

		return "OK";
	}

}

yaml配置

yaml 复制代码
spring:
  servlet:
    multipart:
      max-file-size: 10MB		单个文件最大值
      max-request-size: 100MB	单次请求上传文件最大值
      file-size-threshold: 4KB	内存中IO流,满4KB就开始写入磁盘

Postman调用传参

2、Java接口上传文件给Java接口

我这里是将前端接收过来的文件转发到另外一个接口,也就是一种上传操作。

如果,你要将本地文件上传过去,那么,修改下代码,读取本地文件,格式转化一下即可。

RestTemplateConfig

java 复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

	@Bean
	public RestTemplate restTemplate(){
		return new RestTemplate();
	}

}

Java转发文件接口

java 复制代码
	@PostMapping("/upload")
	public String upload(
						 @RequestPart("headerImg") MultipartFile headerImg,
						 @RequestPart("photos") MultipartFile[] photos) throws IOException {

		log.info("上传的信息:headerImg={},photos={}",
				headerImg.getSize(),photos.length);

		String url="http://127.0.0.1:8080//upload2";
		//封装请求头
		HttpHeaders httpHeaders = new HttpHeaders();
		httpHeaders.set("Content-Type", MediaType.MULTIPART_FORM_DATA_VALUE + ";charset=UTF-8");
		httpHeaders.set("test1", "1");
		httpHeaders.set("test2", "2");

		MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
		//文件处理
		FileSystemResource headerImgFile = new FileSystemResource(multipartFile2File(headerImg));
		form.add("headerImg", headerImgFile);
		FileSystemResource[] photosArr = new FileSystemResource[photos.length];
		for (int i = 0; i < photos.length; i++) {
			photosArr[i] = new FileSystemResource(multipartFile2File(photos[i]));
			form.add("photos", photosArr[i]);
		}

		HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(form, httpHeaders);

		RestTemplate restTemplate = new RestTemplate();
		//发送请求
		String result = restTemplate.postForObject(url, files,String.class);

		return result;
	}
	
	private static File multipartFile2File(@NonNull MultipartFile multipartFile) {
		// 获取文件名
		String fileName = multipartFile.getOriginalFilename();
		// 获取文件前缀
		String prefix = fileName.substring(0, fileName.lastIndexOf("."));
		//获取文件后缀
		String suffix = fileName.substring(fileName.lastIndexOf("."));
		try {
			//生成临时文件
			//文件名字必须大于3,否则报错
			File file = File.createTempFile(prefix, suffix);
			//将原文件转换成新建的临时文件
			multipartFile.transferTo(file);
			file.deleteOnExit();
			return file;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;

	}

Java接收文件接口

java 复制代码
	@PostMapping("/upload2")
	public String upload2(
			@RequestPart("headerImg") MultipartFile headerImg,
			@RequestPart("photos") MultipartFile[] photos) throws IOException {

			if(!headerImg.isEmpty()){
				//保存到文件服务器,OSS服务器
				String originalFilename = headerImg.getOriginalFilename();
				headerImg.transferTo(new File("E:\\workspace\\boot-05-web-01\\headerImg\\"+originalFilename));
			}

			if(photos.length > 0){
				for (MultipartFile photo : photos) {
					if(!photo.isEmpty()){
						String originalFilename = photo.getOriginalFilename();
						photo.transferTo(new File("E:\\workspace\\boot-05-web-01\\photos\\"+originalFilename));
					}
				}
			}

			return "upload2 OK";
	}

二、下载文件

1、前端调用Java接口下载文件

Controller

java 复制代码
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@Slf4j
@RestController
public class FileTestController {

	private static final String FILE_DIRECTORY = "E:\\workspace\\boot-05-web-01\\photos";

	@GetMapping("/files/{fileName:.+}")
	public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) throws IOException {
		Path filePath = Paths.get(FILE_DIRECTORY).resolve(fileName).normalize();
		Resource resource = new FileUrlResource(String.valueOf(filePath));

		if (!resource.exists()) {
			throw new FileNotFoundException("File not found " + fileName);
		}

		// 设置下载文件的响应头
		HttpHeaders headers = new HttpHeaders();
		headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");

		return ResponseEntity.ok()
				.headers(headers)
				.body(resource);
	}

}

测试方法:

浏览器直接发送get请求即可
http://127.0.0.1:8080/files/andriod1749898216865912222.jpg

2、Java接口下载网络文件到本地

Controller

java 复制代码
	@GetMapping("/downloadNetFileToLocal")
	public Object downloadNetFileToLocal(@RequestParam("url") String fileUrl) throws Exception {
		JSONObject result = new JSONObject();

		String fileName = fileUrl.split("/")[fileUrl.split("/").length-1];
		URL url = new URL(fileUrl);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		connection.setConnectTimeout(5000);
		InputStream inputStream = connection.getInputStream();

		FileOutputStream fileOutputStream = new FileOutputStream("E:\\workspace\\boot-05-web-01\\photos\\"+fileName);
		byte[] buffer = new byte[1024];
		int byteread;
		int bytesum = 0;
		while ((byteread = inputStream.read(buffer)) != -1){
			bytesum += byteread;
			fileOutputStream.write(buffer,0,byteread);
		}
		fileOutputStream.close();
		result.put("bytes",bytesum);
		result.put("code",200);
		return result.toString();
	}

测试地址:
http://127.0.0.1:8080/downloadNetFileToLocal?url=https://img-blog.csdnimg.cn/166e183e84094c44bbc8ad66500cef5b.jpeg

3、前端调用Java接口下载网络文件

java 复制代码
	@GetMapping("/downloadNetFile")
	public ResponseEntity<?> downloadNetFile(@RequestParam("url") String fileUrl) throws Exception {
		String fileName = fileUrl.split("/")[fileUrl.split("/").length-1];
		URL url = new URL(fileUrl);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");
		connection.setConnectTimeout(5000);
		InputStream inputStream = connection.getInputStream();
		byte[] bytes = streamToByteArray(inputStream);
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		headers.setContentLength(bytes.length);
		headers.setContentDispositionFormData("attachment", fileName);
		return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
	}

	/**
	 * 功能:将输入流转换成 byte[]
	 *
	 * @param is
	 * @return
	 * @throws Exception
	 */
	public static byte[] streamToByteArray(InputStream is) throws Exception {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象
		byte[] b = new byte[1024];
		int len;
		while ((len = is.read(b)) != -1) {
			bos.write(b, 0, len);
		}
		byte[] array = bos.toByteArray();
		bos.close();
		return array;
	}

测试地址:http://127.0.0.1:8080/downloadNetFile?url=https://img-blog.csdnimg.cn/166e183e84094c44bbc8ad66500cef5b.jpeg

相关推荐
小蜗牛慢慢爬行22 分钟前
有关异步场景的 10 大 Spring Boot 面试问题
java·开发语言·网络·spring boot·后端·spring·面试
Allen Bright29 分钟前
Spring Boot 整合 RabbitMQ:手动 ACK 与 QoS 配置详解
spring boot·rabbitmq·java-rabbitmq
goTsHgo1 小时前
在 Spring Boot 的 MVC 框架中 路径匹配的实现 详解
spring boot·后端·mvc
钱多多_qdd1 小时前
spring cache源码解析(四)——从@EnableCaching开始来阅读源码
java·spring boot·spring
飞的肖1 小时前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
Q_19284999061 小时前
基于Spring Boot的摄影器材租赁回收系统
java·spring boot·后端
gb42152872 小时前
springboot中Jackson库和jsonpath库的区别和联系。
java·spring boot·后端
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭11 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
AskHarries14 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
isolusion15 小时前
Springboot的创建方式
java·spring boot·后端