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

MySQL uses events to complete scheduled tasks

Events can specify the execution of SQL code once...

How to use Axios asynchronous request API in Vue

Table of contents Setting up a basic HTTP request...

Vue basic instructions example graphic explanation

Table of contents 1. v-on directive 1. Basic usag...

A brief discussion on MySQL event planning tasks

1. Check whether event is enabled show variables ...

Detailed explanation of the implementation of nginx process lock

Table of contents 1. The role of nginx process lo...

Detailed explanation of data types in JavaScript basics

Table of contents 1. Data Type 1.1 Why do we need...

Docker network principles and detailed analysis of custom networks

Docker virtualizes a bridge on the host machine. ...

Various front-end printing methods of web: CSS controls web page printing style

CSS controls the printing style of web pages : Use...

MySQL 5.7 installation and configuration tutorial under CentOS7 (YUM)

Installation environment: CentOS7 64-bit, MySQL5....

abbr mark and acronym mark

The <abbr> and <acronym> tags represen...

What is a MySQL index? Ask if you don't understand

Table of contents Overview From Binary Tree to B+...

React implements a general skeleton screen component example

Table of contents What is a skeleton screen? Demo...

MySQL 5.7.27 winx64 installation and configuration method graphic tutorial

This article shares the installation and configur...

Write a shopping mall card coupon using CSS in three steps

Today is 618, and all major shopping malls are ho...