Detailed example of SpringBoot+nginx to achieve resource upload function

Detailed example of SpringBoot+nginx to achieve resource upload function

Recently, I have been learning to use nginx to place static resources, such as pictures, videos, css/js, etc. Let me record some learning tips below.

1. nginx installation and configuration

The server used by the editor is Alibaba Cloud's lightweight application server, and the system uses Ubuntu. Remember to open TCP port 9090. If you do not use port 9090 as the server port, you do not need to do so.

Install

First of all, it is necessary to obtain the installation package. Here is a nginx-1.11.3-ubuntu.tar.gz https://pan.baidu.com/s/1vvb41QkOJ4VqfyFckXBkjA (password 45wz)

The editor puts the installation package in /usr/nginx, enters the directory and executes tar -zxvf nginx-1.11.3.tar.gz to decompress it

Configuration

Modify /usr/nginx/conf/nginx.conf:

server {
 listen 9090;
 server_name localhost;

 location ~ .(jpg|png|jpeg|gif|bmp)$ { #Recognizable file suffix root /usr/nginx/image/; #Image mapping path autoindex on; #Turn on automatic indexing expires 1h; #Expiration time}
 location ~ .(css|js)$ {
  root /usr/nginx/static/;
  autoindex on;
  expires 1h;
 } 
 location ~ .(AVI|mov|rmvb|rm|FLV|mp4|3GP)$ {
  root /usr/nginx/video/;
  autoindex on;
  expires 1h;
 }

Modify what needs to be modified, add what needs to be added, and remember not to delete randomly

The last step is to start nginx and execute ./usr/nginx/sbin/nginx

At this point, the server nginx is ready

You can try to put the image 01.jpg in /usr/nginx/image, and then go to http://ip:9090/01.jpg locally to see if the image can be accessed.

2. SpringBoot implements resource upload

pom.xml:

<parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>2.1.7.RELEASE</version>
</parent>
<dependencies>
 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <version>2.1.7.RELEASE</version>
 </dependency>
 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <version>2.1.7.RELEASE</version>
  <scope>test</scope>
 </dependency>
 <!-- Apache Tool Kit -->
 <dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.8.1</version>
 </dependency>
 <dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-io</artifactId>
  <version>1.3.2</version>
 </dependency>
 <dependency>
  <groupId>commons-net</groupId>
  <artifactId>commons-net</artifactId>
  <version>3.6</version>
 </dependency>
 <!-- File upload component-->
 <dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.3.3</version>
 </dependency>
 <dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.16.22</version>
 </dependency>
 <dependency>
  <groupId>com.jcraft</groupId>
  <artifactId>jsch</artifactId>
  <version>0.1.54</version>
 </dependency>
 <dependency>
  <groupId>joda-time</groupId>
  <artifactId>joda-time</artifactId>
  <version>2.10.3</version>
 </dependency>
</dependencies>

appilcation.yml:

ftp:
 host: your own server ip
 userName: server account password: server password port: 22
 rootPath: /usr/nginx/image
 img:
 url: http://ip:9090/ # ftp.img.url can be omitted. It is only used to return the file path after the file is successfully uploaded.

Tool class FtpUtil.class:

import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.InputStream;
import java.util.Properties;
@Component
public class FtpUtil {
 private static Logger logger = LoggerFactory.getLogger(FtpUtil.class);
 /**
  * ftp server ip address */
 private static String host;
 @Value("${ftp.host}")
 public void setHost(String val){
  FtpUtil.host = val;
 }
 /**
  * Port */
 private static int port;
 @Value("${ftp.port}")
 public void setPort(int val){
  FtpUtil.port = val;
 }
 /**
  * username*/
 private static String userName;
 @Value("${ftp.userName}")
 public void setUserName(String val){
  FtpUtil.userName = val;
 }
 /**
  * password*/
 private static String password;
 @Value("${ftp.password}")
 public void setPassword(String val){
  FtpUtil.password = val;
 }
 /**
  * The root directory where the images are stored */
 private static String rootPath;
 @Value("${ftp.rootPath}")
 public void setRootPath(String val){
  FtpUtil.rootPath = val;
 }
 /**
  * Path to store the image */
 private static String imgUrl;
 @Value("${ftp.img.url}")
 public void setImgUrl(String val){
  FtpUtil.imgUrl = val;
 }
 /**
  * Get connection */
 private static ChannelSftp getChannel() throws Exception{
  JSch jsch = new JSch();
  //->ssh root@host:port
  Session sshSession = jsch.getSession(userName,host,port);
  //Password sshSession.setPassword(password);
  Properties sshConfig = new Properties();
  sshConfig.put("StrictHostKeyChecking", "no");
  sshSession.setConfig(sshConfig);
  sshSession.connect();
  Channel channel = sshSession.openChannel("sftp");
  channel.connect();
  return (ChannelSftp) channel;
 }
 /**
  * FTP upload image * @param inputStream image io stream * @param imagePath path, create a directory if it does not exist * @param imagesName image name * @return urlStr image storage path */
 public static String putImages(InputStream inputStream, String imagePath, String imagesName){
  try {
   ChannelSftp sftp = getChannel();
   String path = rootPath + imagePath + "/";
   createDir(path,sftp);
   //Upload files sftp.put(inputStream, path + imagesName);
   logger.info("Upload successful!");
   sftp.quit();
   sftp.exit();
   //Process the returned path String resultFile;
   resultFile = imgUrl + imagePath + imagesName;
   return resultFile;
  } catch (Exception e) {
   logger.error("Upload failed: " + e.getMessage());
  }
  return "";
 }
 /**
  * Create a directory */
 private static void createDir(String path,ChannelSftp sftp) throws SftpException {
  String[] folders = path.split("/");
  sftp.cd("/");
  for ( String folder : folders ) {
   if ( folder.length() > 0 ) {
    try {
     sftp.cd( folder );
    }catch ( SftpException e ) {
     sftp.mkdir( folder );
     sftp.cd( folder );
    }
   }
  }
 }
 /**
  * Delete image */
 public static void delImages(String imagesName){
  try {
   ChannelSftp sftp = getChannel();
   String path = rootPath + imagesName;
   sftp.rm(path);
   sftp.quit();
   sftp.exit();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

Tool class IDUtils.class (modify the uploaded image name):

import java.util.Random;
public class IDUtils {
 /**
  * Generate a random picture name */
 public static String genImageName() {
  //Get the long integer value of the current time including milliseconds long millis = System.currentTimeMillis();
  //Add three random numbers Random random = new Random();
  int end3 = random.nextInt(999);
  //If there are less than three digits, add 0 in front
  String str = millis + String.format("%03d", end3);
  return str;
 }
}

NginxService.class:

import com.wzy.util.FtpUtil;
import com.wzy.util.IDUtils;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
/**
 * @Package: com.wzy.service
 * @Author: Clarence1
 * @Date: 2019/10/4 21:34
 */
@Service
@Slf4j
public class NginxService {
 public Object uploadPicture(MultipartFile uploadFile) {
  //1. Generate a new file name for the uploaded image //1.1 Get the original file name String oldName = uploadFile.getOriginalFilename();
  //1.2 Use the IDUtils tool class to generate a new file name, new file name = newName + file suffix String newName = IDUtils.genImageName();
  assert oldName != null;
  newName = newName + oldName.substring(oldName.lastIndexOf("."));
  //1.3 Generate a subdirectory for storing files on the server String filePath = new DateTime().toString("/yyyyMMdd/");
  //2. Upload the image to the image server //2.1 Get the uploaded io stream InputStream input = null;
  try {
   input = uploadFile.getInputStream();
  } catch (IOException e) {
   e.printStackTrace();
  }
  //2.2 Call the FtpUtil tool class to upload return FtpUtil.putImages(input, filePath, newName);
 }
}

NginxController.class:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wzy.service.NginxService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.util.HashMap;
import java.util.Map;
@RestController
@Slf4j
public class NginxController {
 @Autowired
 private NginxService nginxService;
 /**
  * You can upload pictures and videos. Just configure a recognizable suffix in the nginx configuration*/
 @PostMapping("/upload")
 public String pictureUpload(@RequestParam(value = "file") MultipartFile uploadFile) {
  long begin = System.currentTimeMillis();
  String json = "";
  try {
   Object result = nginxService.uploadPicture(uploadFile);
   json = new ObjectMapper().writeValueAsString(result);
  } catch (JsonProcessingException e) {
   e.printStackTrace();
  }
  long end = System.currentTimeMillis();
  log.info("Task completed, total time consumed: [" + (end-begin) + "] milliseconds");
  return json;
 }
 @PostMapping("/uploads")
 public Object picturesUpload(@RequestParam(value = "file") MultipartFile[] uploadFile) {
  long begin = System.currentTimeMillis();
  Map<Object, Object> map = new HashMap<>(10);
  int count = 0;
  for (MultipartFile file : uploadFile) {
   Object result = nginxService.uploadPicture(file);
   map.put(count, result);
   count++;
  }
  long end = System.currentTimeMillis();
  log.info("Task completed, total time consumed: [" + (end-begin) + "] milliseconds");
  return map;
 }
}

Start the project, Postman artifact

Notice:

1. If you want to upload videos and pictures together, just modify the nginx.conf configuration file and add the corresponding video suffix. The code remains unchanged and is also placed in /usr/image after uploading. Otherwise, the file can be uploaded but cannot be accessed.

2. The uploads interface in the above code is used to upload multiple files

Source code download

Summarize

The above is the SpringBoot+nginx resource upload function introduced by the editor. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to you in time. I would also like to thank everyone for their support of the 123WORDPRESS.COM website!
If you find this article helpful, please feel free to reprint it and please indicate the source. Thank you!

You may also be interested in:
  • Detailed tutorial on deploying Springboot or Nginx using Kubernetes
  • Detailed tutorial on how to deploy Springboot project using Nginx on the server (jar package)
  • Nginx reverse proxy springboot jar package process analysis
  • Springsession nginx reverse proxy integration process
  • Springboot+nginx+https+linux to achieve load balancing and domain name access simple test
  • SpringBoot integrates FastDFS+Nginx to integrate Token-based anti-hotlinking method
  • Use dockercompose to build springboot-mysql-nginx application
  • Detailed explanation of Spring Boot WebSocket integration and nginx configuration
  • Detailed explanation of the process of realizing dynamic and static separation in Springmvc nginx

<<:  Detailed example of using useState in react

>>:  Detailed explanation of Mysql logical architecture

Recommend

In-depth understanding of MySQL self-connection and join association

1. MySQL self-connection MySQL sometimes needs to...

Detailed explanation of how to use $props, $attrs and $listeners in Vue

Table of contents background 1. Document Descript...

33 ice and snow fonts recommended for download (personal and commercial)

01 Winter Flakes (Individual only) 02 Snowtop Cap...

How to modify the default storage engine in MySQL

mysql storage engine: The MySQL server adopts a m...

A brief discussion on Flink's fault-tolerant mechanism: job execution and daemon

Table of contents 1. Job Execution Fault Toleranc...

Define your own ajax function using JavaScript

Since the network requests initiated by native js...

Design theory: the basics of font design

<br />Words are the inevitable product of hu...

Nginx uses ctx to realize data sharing and context modification functions

Environment: init_worker_by_lua, set_by_lua, rewr...

A brief discussion on MySQL index optimization analysis

Why are the SQL queries you write slow? Why do th...

Correct modification steps for Docker's default network segment

background A colleague is working on his security...

Detailed explanation of Linux one-line command to process batch files

Preface The best method may not be the one you ca...

Native JS music player

This article example shares the specific code of ...

How to solve the mysql ERROR 1045 (28000)-- Access denied for user problem

Problem description (the following discussion is ...