Spring boot builds a file server to solve the problem of uploading and downloading multiple pictures at the same time

In normal business scenarios, it is inevitable to build a file upload server as a public service. Generally, only a single file is uploaded. In the actual business scenario, it is found that uploading a single file does not meet some business needs. Therefore, we need to solve how to write an interface for uploading multiple files at the same time and return the downloadable file address;

No more nonsense. We won't build a spring boot project from scratch. If you don't know, please go directly to the official website to view the instance.

Let's take the above picture as an example. The example is relatively simple and for reference only:

1 back end upload picture interface logic

UploadController.java
package com.zz.controllers.fileUpload;
import com.zz.Application;
import com.zz.model.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.multipartfile;
import java.io.*;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.UUID;
import static com.zz.config.ConfigConstants.getFileDir;
@RestController
@Configuration
public class UploadController {
 private static final Logger log = LoggerFactory.getLogger(Application.class);
 @Value("${server.port}")
 private String port;
 //获取当前IP地址
 public String getIp() {
  InetAddress localhost = null;
  try {
   localhost = Inet4Address.getLocalHost();
  } catch (Exception e) {
   log.error(e.getMessage());
   e.printStackTrace();
  }
  return localhost.getHostAddress();
 }
 @PostMapping(value = "/upload",consumes = {"multipart/form-data"})
 public Response upload(@RequestParam("file") multipartfile[] files,Response response) {
  log.info("上传多个文件");
  StringBuilder builder = new StringBuilder();
  // file address
  String fileAddress ="http://"+ getIp()+ ":" + port + File.separator;
  ArrayList<String> imgurls = new ArrayList<String>();
  try {
   for (int i = 0; i < files.length; i++) {
    // old file name
    String fileName = files[i].getOriginalFilename();
    // new filename
    String generateFileName = UUID.randomUUID().toString().replaceAll("-","") + fileName.substring(fileName.lastIndexOf("."));
    // store filename
    String distFileAddress = fileAddress + generateFileName;
    builder.append(distFileAddress+",");
    imgurls.add(distFileAddress);
    // generate file to disk
    files[i].transferTo(new File(getFileDir() + generateFileName));
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  response.setMsg("success");
  log.info(builder.toString());
  response.setData(imgurls);
  return response;
 }
}

Relative to the reception of a single file, we directly accept multiple file objects, and then traverse to generate each corresponding address.

Of which:

Getfiledir sets the address where the pictures are stored. I choose to store them elsewhere than the project

com.zz.config.ConfigConstants.getFileDir
package com.zz.config;
public class ConfigConstants {
 public static String fileDir;
 public static String getFileDir() {
  fileDir = "/Users/wz/projects/blog/uploadFile/";
  return fileDir;
 }
}

After we generate files to the specified folder, how can we configure the current server to access the static file and image resources outside the project and download them?

We will use the spring boot configuration file application YML, there are other methods, such as webmvcconfigurer, which will not be repeated here.

application.yml
pring:
 jpa:
 show-sql: true
 hibernate:
  ddl-auto: update
 servlet:
 multipart:
  max-file-size: 10MB
  max-request-size: 10MB
 profiles:
 active: dev
 # 静态资源配置
 mvc:
 static-path-pattern: /**
 resources:
 static-locations: file:/Users/wz/projects/blog/uploadFile/,classpath:/static/,classpath:/resources/,classpath:/file/,classpath:/templates/
server:
 use-forward-headers: true
 tomcat:
 remote-ip-header: X-Real-IP
 protocol-header: X-Forwarded-Proto
#自定义
my:
 tokenURL: "55555"
 authURL: "88888"

After that, we are in the generated results http://192.168.31.77:8080/a7ef32e3922b46aea256a93dd53de288.png , such an address can substantially point the file to file: / users / WZ / projects / blog / UploadFile /, which is roughly a simple file server configuration. Of course, it is far less than this. There are compression functions, which will be discussed later.

The back-end logic is clear;

How can the front end send multiple file objects to the back end at the same time?

2. How to transfer parameters when uploading multiple files at the front end

html

<input type="file" multiple class="el-upload" accept="image/*" name="file">

js

//upload
var uploadBtn = document.querySelector('.el-upload');
uploadBtn.onchange = function (e) {
 let files = this.files;
 console.log(this.files);
 const xhr = new XMLHttpRequest();
 xhr.open("post","/upload",true);
 // xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
 xhr.onreadystatechange = function () {
  if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
   console.log(JSON.parse(this.responseText));
   const {data} = JSON.parse(this.responseText);
   if(!data) return;
   const imageList = data.slice(0);
   let imageStr = '';
   imageList.forEach(img=>{
    imageStr += `<img src="${img}" />`;
   });
   document.getElementById("result").innerHTML = imageStr;
  }
 };
 const formData = new FormData();
 // 多个file 同时上传
 if(files && files.length){
  for (let i=0;i<files.length;i++) {
   formData.append("file",files[i])
  }
 }
 console.log(formData);
 xhr.send(formData);
};

The front end sends a post request through formdata parameters;

Different from the previous single formdata append(); Here, we can append multiple binary file streams with the same name at the same time;

! [image-20191123234150228](assets/image-

. png)

As shown in the figure, when we deploy to the server, it can be used as a web server for everyone.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>