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

相关推荐
JH30734 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
qq_12498707537 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_7 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
2301_818732067 小时前
前端调用控制层接口,进不去,报错415,类型不匹配
java·spring boot·spring·tomcat·intellij-idea
汤姆yu11 小时前
基于springboot的尿毒症健康管理系统
java·spring boot·后端
暮色妖娆丶11 小时前
Spring 源码分析 单例 Bean 的创建过程
spring boot·后端·spring
biyezuopinvip12 小时前
基于Spring Boot的企业网盘的设计与实现(任务书)
java·spring boot·后端·vue·ssm·任务书·企业网盘的设计与实现
JavaGuide12 小时前
一款悄然崛起的国产规则引擎,让业务编排效率提升 10 倍!
java·spring boot
figo10tf13 小时前
Spring Boot项目集成Redisson 原始依赖与 Spring Boot Starter 的流程
java·spring boot·后端
zhangyi_viva13 小时前
Spring Boot(七):Swagger 接口文档
java·spring boot·后端