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

相关推荐
仰望星空@脚踏实地1 小时前
Spring Boot Web 服务单元测试设计指南
spring boot·后端·单元测试
一勺菠萝丶3 小时前
Spring Boot + MyBatis/MyBatis Plus:XML中循环处理List参数的终极指南
xml·spring boot·mybatis
RainbowSea4 小时前
问题:后端由于字符内容过长,前端展示精度丢失修复
java·spring boot·后端
风象南5 小时前
SpringBoot 控制器的动态注册与卸载
java·spring boot·后端
我是一只代码狗5 小时前
springboot中使用线程池
java·spring boot·后端
hello早上好5 小时前
JDK 代理原理
java·spring boot·spring
PanZonghui5 小时前
Centos项目部署之运行SpringBoot打包后的jar文件
linux·spring boot
沉着的码农6 小时前
【设计模式】基于责任链模式的参数校验
java·spring boot·分布式
zyxzyx6666 小时前
Flyway 介绍以及与 Spring Boot 集成指南
spring boot·笔记
一头生产的驴8 小时前
java整合itext pdf实现自定义PDF文件格式导出
java·spring boot·pdf·itextpdf