728x90

출처

application.properties

#File upload settings
# support multipart uploads (default: true)
spring.servlet.multipart.enabled=true
# Threshold at which files are written to memory (default: 0B)
#spring.servlet.multipart.file-size-threshold=0B 
# Temporary storage space for uploaded files
spring.servlet.multipart.location=d:/usr/local/cnssm/resources
# Maximum size of the file (default: 1MB)
spring.servlet.multipart.max-file-size=10144MB
# Maximum size of request (default: 10MB)
spring.servlet.multipart.max-request-size=10144MB

FileStorageProperties.java

package com.bx.config.property;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(prefix = "spring.servlet.multipart")
public class FileStorageProperties {

	private String location;

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}
}

FileUploadController.java

package com.bx.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.stream.Collectors;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.bx.common.util.ExcelUtil;
import com.bx.config.property.FileStorageProperties;
import com.bx.service.FileStorageService;

@Controller
public class FileUploadController {

	@Autowired
	private FileStorageService fileStorageService;

	@Autowired
	private FileStorageProperties fileStorageProperties;

	@RequestMapping(value = "/bx/uploadFile", method = RequestMethod.POST)
	public String uploadFile(@RequestParam("file") MultipartFile file, ModelMap modelMap) {
		String fileName = fileStorageService.storeFile(file);
		modelMap.put("fileName", fileName);
		
		try {
			if (fileName != null && (fileName.endsWith(".xls") || fileName.endsWith(".xlsx"))) {
				FileInputStream fis = new FileInputStream(new File(fileStorageProperties.getLocation() + "/" + fileName));
				Workbook workbook = new XSSFWorkbook(fis);
				
				Sheet sheet = workbook.getSheetAt(0); // 첫 번째 시트 가져오기
				
				// 행 반복 (첫 번째 행부터 마지막 행까지)
				for (Row row : sheet) {
					// 열 반복 (첫 번째 열부터 마지막 열까지)
					for (Cell cell : row) {
						// 셀 값 출력
						System.out.print(ExcelUtil.getCellValue(cell) + "\t");
					}
					System.out.println(); // 행 끝나면 줄바꿈
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return "bx/uploadOk";
	}

	@RequestMapping(value = "/uploadMultipleFiles", method = RequestMethod.POST)
	public String uploadMultipleFiles(@RequestParam("files") MultipartFile[] files, ModelMap modelMap) {
		Arrays.asList(files).stream().map(file -> uploadFile(file, modelMap)).collect(Collectors.toList());

		return "bx/uploadOk";
	}

}

FileStorageService.java

package com.bx.service;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import com.bx.common.exception.FileNotFoundException;
import com.bx.common.exception.FileStorageException;
import com.bx.config.property.FileStorageProperties;

@Service
public class FileStorageService {

	private final Path fileStorageLocation;

	@Autowired
	public FileStorageService(FileStorageProperties fileStorageProperties) {
		this.fileStorageLocation = Paths.get(fileStorageProperties.getLocation()).toAbsolutePath().normalize();

		try {
			Files.createDirectories(this.fileStorageLocation);
		} catch (Exception ex) {
			throw new FileStorageException("Could not create the directory where the uploaded files will be stored.", ex);
		}
	}

	public String storeFile(MultipartFile file) {
		// Normalize file name
		String fileName = StringUtils.cleanPath(file.getOriginalFilename());

		try {
			// Check if the file's name contains invalid characters
			if (fileName.contains("..")) {
				throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
			}

			// Copy file to the target location (Replacing existing file with the same name)
			Path targetLocation = this.fileStorageLocation.resolve(fileName);
			Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);

			return fileName;
		} catch (IOException ex) {
			throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
		}
	}

	public Resource loadFileAsResource(String fileName) {
		try {
			Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
			Resource resource = new UrlResource(filePath.toUri());
			if (resource.exists()) {
				return resource;
			} else {
				throw new FileNotFoundException("File not found " + fileName);
			}
		} catch (MalformedURLException ex) {
			throw new FileNotFoundException("File not found " + fileName, ex);
		}
	}
}

FileNotFoundException.java

package com.bx.common.exception;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(HttpStatus.NOT_FOUND)
public class FileNotFoundException extends RuntimeException {

	private static final long serialVersionUID = 1L;
	
	public FileNotFoundException(String message) {
		super(message);
	}
	
	public FileNotFoundException(String message, Throwable cause) {
		super(message, cause);
	}
}

FileStorageException.java

package com.bx.common.exception;

public class FileStorageException extends RuntimeException {
	
	private static final long serialVersionUID = 1L;

	public FileStorageException(String message) {
		super(message);
	}
	
	public FileStorageException(String message, Throwable cause) {
		super(message, cause);
	}
}

HTML

<form method="post" action="<c:url value="/cnssm/uploadFile"/>" enctype="multipart/form-data">

  <div>
    file : <input type="file" name="file" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
  </div>
  
  <input type="submit">

</form>
728x90
728x90

Linux 쉘 접속

D:\docker>docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED       STATUS          PORTS                                                                 NAMES
7ce950bfb3c5   ubuntu:22.04   "/bin/bash"   4 hours ago   Up 18 minutes   0.0.0.0:1080->80/tcp, 0.0.0.0:1443->443/tcp, 0.0.0.0:1880->8080/tcp   cnssm-ubuntu
 
D:\docker>docker exec -it 7ce950bfb3c5 /bin/bash
root@0:/#

openjdk 17 설치

jdk 설치

root@0:/# apt install openjdk-17-jdk

JAVA_HOME 설정

root@0:/# echo "export JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::")" | tee /etc/profile.d/java_home.sh
root@0:/# source /etc/profile.d/java_home.sh

java 설치 확인

root@0:/# java --version
openjdk 17.0.13 2024-10-15
OpenJDK Runtime Environment (build 17.0.13+11-Ubuntu-2ubuntu122.04)
OpenJDK 64-Bit Server VM (build 17.0.13+11-Ubuntu-2ubuntu122.04, mixed mode, sharing)
root@0:/# javac --version
javac 17.0.13
root@0:/# echo $JAVA_HOME
/usr/lib/jvm/java-17-openjdk-amd64
root@0:/#

Tomcat 설치

tomcat 계정 생성

root@0:~# useradd tomcat -s /sbin/nologin

Tomcat 다운로드 및 설치

root@0:~# wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.34/bin/apache-tomcat-10.1.34.tar.gz
root@0:~# tar xvf apache-tomcat-10.1.34.tar.gz
root@0:~# mv apache-tomcat-10.1.34 /usr/local/

tomcat 사용자 변경

root@0:~# chown tomcat:tomcat -R /usr/local/apache-tomcat-10.1.34/

tomcat 서비스 파일 생성

root@0:~# vi /etc/init.d/tomcat
#!/bin/bash

### BEGIN INIT INFO
# Provides:          tomcat
# Required-Start:    $network $remote_fs $syslog
# Required-Stop:     $network $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start Tomcat at boot time
# Description:       Start Tomcat at boot time
### END INIT INFO

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export CATALINA_HOME=/usr/local/apache-tomcat-10.1.34
export JAVA_OPTS="-Xms250m -Xmx1024m"

RETVAL=$?
case $1 in
start)
    if [ -f $CATALINA_HOME/bin/startup.sh ];
    then
        echo $"Starting Tomcat"
        su -p -s /bin/sh tomcat $CATALINA_HOME/bin/startup.sh
    fi
    ;; 
stop)   
    if [ -f $CATALINA_HOME/bin/shutdown.sh ];
    then
        echo $"Stopping Tomcat"
        su -p -s /bin/sh tomcat $CATALINA_HOME/bin/shutdown.sh
    fi
    ;; 
*)
    echo $"Usage: $0 {start|stop}"
    exit 1
    ;;
esac

exit $RETVAL

서비스 등록

root@0:/# chmod +x /etc/init.d/tomcat
root@0:~# update-rc.d -f tomcat defaults
728x90
728x90

출처

컨테이너 commit 전 이미지 목록 확인

D:\docker>docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
ubuntu       22.04     0e5e4a57c249   4 months ago   117MB

컨테이너 중지

D:\docker>docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED       STATUS          PORTS                                                                 NAMES
7ce950bfb3c5   ubuntu:22.04   "/bin/bash"   4 hours ago   Up 30 minutes   0.0.0.0:1080->80/tcp, 0.0.0.0:1443->443/tcp, 0.0.0.0:1880->8080/tcp   cnssm-ubuntu
 
D:\docker>docker stop 7ce950bfb3c5
7ce950bfb3c5

컨테이너 commit

D:\docker>docker commit -p 7ce950bfb3c5 ubuntu-nginx
sha256:f41c3c19a473d68563cbffec77605a85a20b39e8cf3f1a771adbcf6be9c85a75

컨테이너 삭제

D:\docker>docker rm 7ce950bfb3c5
7ce950bfb3c5

컨테이너 commit 후 이미지 목록 확인

D:\docker>docker images
REPOSITORY     TAG       IMAGE ID       CREATED         SIZE
ubuntu-nginx   latest    f41c3c19a473   4 minutes ago   329MB
ubuntu         22.04     0e5e4a57c249   4 months ago    117MB

이미지 복사

D:\docker>docker save -o ubuntu-nginx.tar ubuntu-nginx:latest

이미지 삭제

D:\docker>docker rmi ubuntu-nginx:latest
Untagged: ubuntu-nginx:latest
Deleted: sha256:f41c3c19a473d68563cbffec77605a85a20b39e8cf3f1a771adbcf6be9c85a75
 
D:\docker>docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
ubuntu       22.04     0e5e4a57c249   4 months ago   117MB

이미지 복원

D:\docker>docker load -i ubuntu-nginx.tar
Loaded image: ubuntu-nginx:latest
 
D:\docker>docker images
REPOSITORY     TAG       IMAGE ID       CREATED          SIZE
ubuntu-nginx   latest    f41c3c19a473   12 minutes ago   329MB
ubuntu         22.04     0e5e4a57c249   4 months ago     117MB

컨터이너 생성

D:\docker>docker run -it ^
--hostname 0.0.0.0 ^
--publish 2080:80 --publish 2443:443 --publish 2880:8080 ^
--name bxmas-ubuntu ^
--restart always ^
--volume //d/docker/bxmas/bxmas_home2:/usr/local/bxmas_home ^
ubuntu-nginx:latest ^
/bin/bash

nginx 서비스 시작

root@0:/usr/local/bxmas_home# service nginx start
 * Starting Nginx Server...
728x90
728x90

Ubuntu 도커 이미지 설치

D:\docker>docker run -it ^
--hostname 0.0.0.0 ^
--publish 1080:80 --publish 1443:443 --publish 1880:8080 ^
--name bxmas-ubuntu ^
--restart always ^
--volume //d/docker/bxmas/bxmas_home:/usr/local/bxmas_home ^
ubuntu:22.04 ^
/bin/bash
 
root@0:/#

OS 업데이트

root@0:/# apt update
root@0:/# apt upgrade

Linux 쉘 접속

D:\docker>docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED       STATUS          PORTS                                                                 NAMES
7ce950bfb3c5   ubuntu:22.04   "/bin/bash"   4 hours ago   Up 18 minutes   0.0.0.0:1080->80/tcp, 0.0.0.0:1443->443/tcp, 0.0.0.0:1880->8080/tcp   cnssm-ubuntu
 
D:\docker>docker exec -it 7ce950bfb3c5 /bin/bash
root@0:/#

openjdk 17 설치

jdk 설치

root@0:/# apt install openjdk-17-jdk

JAVA_HOME 설정

root@0:/# echo "export JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::")" | tee /etc/profile.d/java_home.sh
root@0:/# source /etc/profile.d/java_home.sh

java 설치 확인

root@0:/# java --version
openjdk 17.0.13 2024-10-15
OpenJDK Runtime Environment (build 17.0.13+11-Ubuntu-2ubuntu122.04)
OpenJDK 64-Bit Server VM (build 17.0.13+11-Ubuntu-2ubuntu122.04, mixed mode, sharing)
root@0:/# javac --version
javac 17.0.13
root@0:/# echo $JAVA_HOME
/usr/lib/jvm/java-17-openjdk-amd64
root@0:/#

nginx 설치

nginx 계정 생성

root@0:~# useradd nginx -s /sbin/nologin

nginx 빌드 환경 설정

root@0:~# apt install gcc g++ make perl
root@0:~# mkdir nginx_source
root@0:~# cd nginx_source/
root@0:~/nginx_source# apt install wget
root@0:~/nginx_source# wget https://nginx.org/download/nginx-1.20.1.tar.gz
root@0:~/nginx_source# tar xvf nginx-1.20.1.tar.gz
root@0:~/nginx_source# wget  https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz
root@0:~/nginx_source# tar xvf pcre-8.45.tar.gz
root@0:~/nginx_source# wget https://www.openssl.org/source/openssl-1.1.1l.tar.gz
root@0:~/nginx_source# tar -xzvf openssl-1.1.1l.tar.gz
root@0:~/nginx_source# wget https://www.zlib.net/fossils/zlib-1.2.11.tar.gz
root@0:~/nginx_source# tar xvf zlib-1.2.11.tar.gz
root@0:~/nginx_source# cd nginx-1.20.1/
root@0:~/nginx_source/nginx-1.20.1#

configure

root@0:~/nginx_source/nginx-1.20.1# ./configure \
--user=nginx \
--group=nginx \
--with-http_sub_module \
--with-zlib=../zlib-1.2.11 \
--with-pcre=../pcre-8.45 \
--with-openssl=../openssl-1.1.1l \
--with-http_ssl_module \
--prefix=/usr/local/nginx \
--conf-path=/usr/local/bxmas_home/nginx_conf/nginx.conf
 
Configuration summary
  + using PCRE library: ../pcre-8.45
  + using OpenSSL library: ../openssl-1.1.1l
  + using zlib library: ../zlib-1.2.11
 
  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/bxmas_home/nginx_conf"
  nginx configuration file: "/usr/local/bxmas_home/nginx_conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

make

root@0:~/nginx_source/nginx-1.20.1# make
 
-lcrypt ../pcre-8.45/.libs/libpcre.a ../openssl-1.1.1l/.openssl/lib/libssl.a ../openssl-1.1.1l/.openssl/lib/libcrypto.a ../zlib-1.2.11/libz.a \
-Wl,-E
sed -e "s|%%PREFIX%%|/usr/local/nginx|" \
        -e "s|%%PID_PATH%%|/usr/local/nginx/logs/nginx.pid|" \
        -e "s|%%CONF_PATH%%|/usr/local/bxmas_home/nginx_conf/nginx.conf|" \
        -e "s|%%ERROR_LOG_PATH%%|/usr/local/nginx/logs/error.log|" \
        < man/nginx.8 > objs/nginx.8
make[1]: Leaving directory '/root/nginx_source/nginx-1.20.1'

make install

root@0:~/nginx_source/nginx-1.20.1# make install
make -f objs/Makefile install
make[1]: Entering directory '/root/nginx_source/nginx-1.20.1'
test -d '/usr/local/nginx' || mkdir -p '/usr/local/nginx'
test -d '/usr/local/nginx/sbin' \
        || mkdir -p '/usr/local/nginx/sbin'
test ! -f '/usr/local/nginx/sbin/nginx' \
        || mv '/usr/local/nginx/sbin/nginx' \
                '/usr/local/nginx/sbin/nginx.old'
cp objs/nginx '/usr/local/nginx/sbin/nginx'
test -d '/usr/local/bxmas_home/nginx_conf' \
        || mkdir -p '/usr/local/bxmas_home/nginx_conf'
cp conf/koi-win '/usr/local/bxmas_home/nginx_conf'
cp conf/koi-utf '/usr/local/bxmas_home/nginx_conf'
cp conf/win-utf '/usr/local/bxmas_home/nginx_conf'
test -f '/usr/local/bxmas_home/nginx_conf/mime.types' \
        || cp conf/mime.types '/usr/local/bxmas_home/nginx_conf'
cp conf/mime.types '/usr/local/bxmas_home/nginx_conf/mime.types.default'
test -f '/usr/local/bxmas_home/nginx_conf/fastcgi_params' \
        || cp conf/fastcgi_params '/usr/local/bxmas_home/nginx_conf'
cp conf/fastcgi_params \
        '/usr/local/bxmas_home/nginx_conf/fastcgi_params.default'
test -f '/usr/local/bxmas_home/nginx_conf/fastcgi.conf' \
        || cp conf/fastcgi.conf '/usr/local/bxmas_home/nginx_conf'
cp conf/fastcgi.conf '/usr/local/bxmas_home/nginx_conf/fastcgi.conf.default'
test -f '/usr/local/bxmas_home/nginx_conf/uwsgi_params' \
        || cp conf/uwsgi_params '/usr/local/bxmas_home/nginx_conf'
cp conf/uwsgi_params \
        '/usr/local/bxmas_home/nginx_conf/uwsgi_params.default'
test -f '/usr/local/bxmas_home/nginx_conf/scgi_params' \
        || cp conf/scgi_params '/usr/local/bxmas_home/nginx_conf'
cp conf/scgi_params \
        '/usr/local/bxmas_home/nginx_conf/scgi_params.default'
test -f '/usr/local/bxmas_home/nginx_conf/nginx.conf' \
        || cp conf/nginx.conf '/usr/local/bxmas_home/nginx_conf/nginx.conf'
cp conf/nginx.conf '/usr/local/bxmas_home/nginx_conf/nginx.conf.default'
test -d '/usr/local/nginx/logs' \
        || mkdir -p '/usr/local/nginx/logs'
test -d '/usr/local/nginx/logs' \
        || mkdir -p '/usr/local/nginx/logs'
test -d '/usr/local/nginx/html' \
        || cp -R html '/usr/local/nginx'
test -d '/usr/local/nginx/logs' \
        || mkdir -p '/usr/local/nginx/logs'
make[1]: Leaving directory '/root/nginx_source/nginx-1.20.1'

서비스 등록

/etc/init.d/nginx에서 환경파일(nginx.conf) 경로 수정 필요

root@0:~# wget --no-check-certificate https://raw.github.com/JasonGiedymin/nginx-init-ubuntu/master/nginx -O /etc/init.d/nginx
root@0:~# chmod +x /etc/init.d/nginx
root@0:~# update-rc.d -f nginx defaults
728x90

+ Recent posts