공통 파일 업로드 구현
- application.properties에 JSP 사용을 위한 prefix와 suffix 설정
# file - jsp
spring.mvc.view.prefix = /WEB-INF/views/
spring.mvc.view.suffix = .jsp
- webapp/WEB-INF/views 폴더를 만들고 index.jsp 파일 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/file/save" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile"/>
<button type="submit">파일업로드</button>
</form>
</body>
</html>
- pom.xml에 JSP 사용을 위한 2가지 라이브러리 추가
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
- 로컬 환경에서 파일이 저장될 경로 설정
uploadFile.path = C:/home/upload/
- 파일 업로드를 위한 UserController 컨트롤러 생성 및 FileController 수정
@Controller
public class UserController {
@GetMapping("/file/save")
public String saveFileJsp() {
// prefix: /WEB-INF/views
// suffix: .jsp
// 풀경로: /WEB-INF/views/index.jsp
return "index";
}
}
@RestController
@RequestMapping("/file")
@Api(tags = "파일 API")
public class FileController {
...
/**
* 업로드 리턴
* @return
*/
@PostMapping("/save")
@ApiOperation(value = "업로드", notes = "")
public BaseResponse<Boolean> save(@RequestParam("uploadFile") MultipartFile multipartFile) {
logger.debug("multipartFile : {}", multipartFile);
// 파일 업로드 필수 체크
if (multipartFile == null || multipartFile.isEmpty()) {
throw new BaseException(BaseResponseCode.DATA_IS_NULL);
}
// 파일이 저장될 경로
String uploadFilePath = config.getUploadFilePath();
logger.debug("uploadFilePath : {}", uploadFilePath);
// 확장자
String prefix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1, multipartFile.getOriginalFilename().length());
// 파일 이름
String filename = UUID.randomUUID().toString() + "." + prefix;
logger.info("filename : {}", filename);
// 저장될 파일 상위경로의 폴더가 없다면 생성
File folder = new File(uploadFilePath);
if (!folder.isDirectory()) {
folder.mkdirs();
}
String pathname = uploadFilePath + filename;
// 파일 생성
File dest = new File(pathname);
try {
multipartFile.transferTo(dest);
} catch (IOException e) {
e.printStackTrace();
logger.error("e", e);
}
return new BaseResponse<Boolean>(true);
}
}
- 결과
C:/home/upload 폴더에 파일이 저장됨

파일 업로드 정보 DB 저장 및 리소스 접근 설정
- Upload.xml 생성 후 파일 업로드(등록)를 위한 insert 쿼리 작성
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.examplespring.mvc.repository.UploadFileRepository">
<insert id="save" parameterType="com.example.examplespring.mvc.parameter.UploadFileParameter">
INSERT INTO T_UPLOAD_FILE
(
PATHNAME,
FILENAME,
ORIGINAL_FILENAME,
SIZE,
CONTENT_TYPE,
RESOURCE_PATHNAME,
REG_DATE
)
VALUES
(
#{pathname},
#{filename},
#{originalFilename},
#{size},
#{contentType},
#{resourcePathname},
NOW()
}
</insert>
</mapper>
- 파일 등록을 위한 UploadFileParameter, UploadFileRepository, UploadFileService 클래스 생성
@Data
public class UploadFileParameter {
private String pathname;
private String filename;
private String originalFilename;
private int size;
private String contentType;
private String resourcePathname;
}
/**
* 업로드 파일 Repository
* @author gagyeong
*/
@Repository
public interface UploadFileRepository {
void save(UploadFileParameter uploadFile);
}
/**
* 업로드 파일 서비스
* @author gagyeong
*/
@Service
public class UploadFileService {
@Autowired
private UploadFileRepository uploadFileRepository;
/**
* 등록 처리
* @param parameter
*/
public void save(UploadFileParameter parameter) {
uploadFileRepository.save(parameter);
}
}
- 리소스 접근 설정을 위해 파일 resourePath 추가 후 GlobalConfig, WebConfiguration 클래스 수정
uploadFile.resourcePath = /upload/
public class GlobalConfig {
Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ApplicationContext context;
@Autowired
private ResourceLoader resourceLoader;
private String uploadFilePath;
private String uploadResourcePath;
private String schedulerCronExample;
private boolean local;
private boolean dev;
private boolean prod;
@PostConstruct
public void init() {
logger.info("init");
String[] activeProfiles = context.getEnvironment().getActiveProfiles(); // 프로필(local, prod, dev)에 따라 프로퍼티 파일을 가져옴
String activeProfile = "local"; // 기본값
if (ObjectUtils.isNotEmpty(activeProfiles)) {
activeProfile = activeProfiles[0];
}
String resourcePath = String.format("classpath:globals/global-%s.properties", activeProfile);
try {
Resource resource = resourceLoader.getResource(resourcePath);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
// 프로퍼티 파일에 있는 uploadFile.path가 변수에 저장됨
this.uploadFilePath = properties.getProperty("uploadFile.path");
this.uploadResourcePath = properties.getProperty("uploadFile.resourcePath");
this.schedulerCronExample = properties.getProperty("scheduler.cron.example1");
// local로 서버가 올라올 경우 /home/upload
this.local = activeProfile.equals("local");
// dev로 서버가 올라올 경우 /app/upload
this.dev = activeProfile.equals("dev");
// prod로 서버가 올라올 경우 /root/upload
this.prod = activeProfile.equals("prod");
} catch (Exception e) {
logger.error("e", e);
}
}
public String getUploadFilePath() {
return uploadFilePath;
}
public String getUploadResourcePath() {
return uploadResourcePath;
}
...
}
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
...
// 브라우저에서 접근 가능 (URL로 업로드 파일 보기 가능)
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 업로드 파일 static resource 접근 경로
String resourcePattern = config().getUploadResourcePath() + "**";
// 로컬 (윈도우 환경)
if (config().isLocal()) {
registry.addResourceHandler(resourcePattern).addResourceLocations("file:///" + config().getUploadFilePath());
} else {
// 리눅스 도는 유닉스 환경
registry.addResourceHandler(resourcePattern).addResourceLocations("file:" + config().getUploadFilePath());
}
}
}
- DB 저장을 위해 FileController 클래스 수정
/**
* 파일 컨트롤러
* @author gagyeong
*/
@RestController
@RequestMapping("/file")
@Api(tags = "파일 API")
public class FileController {
...
/**
* 업로드 리턴
* @return
*/
@PostMapping("/save")
@ApiOperation(value = "업로드", notes = "")
public BaseResponse<Boolean> save(@RequestParam("uploadFile") MultipartFile multipartFile) {
logger.debug("multipartFile : {}", multipartFile);
if (multipartFile == null || multipartFile.isEmpty()) {
throw new BaseException(BaseResponseCode.DATA_IS_NULL);
}
// 날짜폴더를 추가
String currentDate = new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
String uploadFilePath = config.getUploadFilePath() + currentDate + "/";
logger.debug("uploadFilePath : {}", uploadFilePath);
String prefix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1, multipartFile.getOriginalFilename().length());
String filename = UUID.randomUUID().toString() + "." + prefix;
logger.info("filename : {}", filename);
// 저장될 파일 상위경로의 폴더가 없다면 생성
File folder = new File(uploadFilePath);
if (!folder.isDirectory()) {
folder.mkdirs();
}
String pathname = uploadFilePath + filename;
String resourcePathname = config.getUploadResourcePath() + currentDate + "/" + filename;
// 파일 생성
File dest = new File(pathname);
try {
multipartFile.transferTo(dest);
// 파일 업로드된 후 DB에 저장
UploadFileParameter parameter = new UploadFileParameter();
// 컨텐츠 종류
parameter.setContentType(multipartFile.getContentType());
// 원본 파일명
parameter.setOriginalFilename(multipartFile.getOriginalFilename());
// 저장 파일명
parameter.setFilename(filename);
// 실제 파일 저장 경로
parameter.setPathname(pathname);
// static resource 접근 경로
parameter.setResourcePathname(resourcePathname);
uploadFileService.save(parameter);
} catch (IOException e) {
e.printStackTrace();
logger.error("e", e);
}
return new BaseResponse<Boolean>(true);
}
}
- 결과
DB에 파일이 업로드되고, RESOURCE_PATHNAME 컬럼의 값을 주소창에 붙어넣으면 파일 리소스에 접근 가능

썸네일 만들기
- 썸네일 생성을 위해 pom.xml 설정
<!-- 파일 썸네일 생성 -->
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.13</version>
</dependency>
- 파일이 없을 경우를 위한 메시지 설정
public enum BaseResponseCode {
SUCCESS, // 성공
ERROR, // 실패
LOGIN_REQUIRED, // 로그인
DATA_IS_NULL, // NULL
VALIDATE_REQUIRED, // 필수 체크
UPLOAD_FILE_IS_NULL
;
}
UPLOAD_FILE_IS_NULL = There is no file upload information
- UploadFile, ThumbnailType, ThumbnailController 클래스 생성 및
UploadFileService, UploadFileRepository 클래스 수정
/**
* 썸네일 컨트롤러
* @author gagyeong
*/
@RestController
@RequestMapping("/thumbnail")
@Api(tags = "썸네일 API")
public class ThumbnailController {
final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private UploadFileService uploadFileService;
public void index(@PathVariable int uploadFileSeq) {
uploadFileService.get(uploadFileSeq);
try {
Thumbnails.of("original.jpg").size(160, 160).toFile("thumbnail.jpg");
} catch (IOException e) {
}
}
}
/**
* 업로드 파일 서비스
* @author gagyeong
*/
@Service
public class UploadFileService {
@Autowired
private UploadFileRepository uploadFileRepository;
/**
* 등록 처리
* @param parameter
*/
public void save(UploadFileParameter parameter) {
uploadFileRepository.save(parameter);
}
public UploadFile get(int uploadFileSeq) {
return uploadFileRepository.get(uploadFileSeq);
}
}
/**
* 업로드 파일 Repository
* @author gagyeong
*/
@Repository
public interface UploadFileRepository {
void save(UploadFileParameter uploadFile);
UploadFile get(int uploadFileSeq);
}
@Data
public class UploadFile {
private int uploadFileSeq;
private String pathname;
private String filename;
private String originalFilename;
private int size;
private String contentType;
private String resourcePathname;
}
public enum ThumbnailType {
WEB_MAIN(500, 300),
WEB_SUB(150, 70),
;
private int width;
private int height;
ThumbnailType(int width, int height) {
this.width = width;
this.height = height;
}
public int width() {
return width;
}
public int height() {
return height;
}
}
- 썸네일 생성을 위해 파일 정보를 가져오는 select 쿼리 작성
<select id="get" parameterType="int" resultType="com.example.examplespring.mvc.domain.UploadFile">
SELECT
PATHNAME,
FILENAME,
ORIGINAL_FILENAME,
SIZE,
CONTENT_TYPE,
RESOURCE_PATHNAME,
REG_DATE
FROM T_UPLOAD_FILE UF
WHERE UF.UPLOAD_FILE_SEQ = #{uploadFileSeq}
</select>
- 썸네일 타입을 위한 ThumbnailController 클래스 수정
/**
* 썸네일 컨트롤러
* @author gagyeong
*/
@RestController
@RequestMapping("/thumbnail")
@Api(tags = "썸네일 API")
public class ThumbnailController {
final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private UploadFileService uploadFileService;
@GetMapping("/make/{uploadFileSeq}/{thumbnailType}")
public void index(@PathVariable int uploadFileSeq, @PathVariable ThumbnailType thumbnailType, HttpServletResponse response) {
UploadFile uploadFile = uploadFileService.get(uploadFileSeq);
if (uploadFile == null) {
throw new BaseException(BaseResponseCode.UPLOAD_FILE_IS_NULL);
}
String pathname = uploadFile.getPathname();
File file = new File(pathname);
if (!file.isFile()) {
throw new BaseException(BaseResponseCode.UPLOAD_FILE_IS_NULL);
}
try {
// 본래 파일 이름 + _width_height.확장자
String thumbnailPathname = uploadFile.getPathname().replace(".", "_" + thumbnailType.width() + "_" + thumbnailType.height() + ".");
File thumbnailFile = new File(thumbnailPathname);
if (!thumbnailFile.isFile()) {
Thumbnails.of(pathname).size(thumbnailType.width(), thumbnailType.height()).toFile(thumbnailPathname);
}
response.setContentType(MediaType.IMAGE_PNG_VALUE);
FileCopyUtils.copy(new FileInputStream(thumbnailFile), response.getOutputStream());
logger.info("thumbnailPathname : {}", thumbnailPathname);
} catch (IOException e) {
e.printStackTrace();
logger.error("e", e);
}
}
}
- 결과

'Java-Spring > 자바 스프링부트 활용 웹개발 실무용' 카테고리의 다른 글
[자바 스프링부트 활용 웹개발 실무용] 세션 관리를 Class 구조와 Spring을 활용하여 개발하기 (0) | 2022.09.15 |
---|---|
[자바 스프링부트 활용 웹개발 실무용] 컨트롤러에서 파라미터를 받는 방법들 (0) | 2022.09.02 |
[자바 스프링부트 활용 웹개발 실무용] TypeHandler로 데이터 변환하기 (0) | 2022.08.20 |
[자바 스프링부트 활용 웹개발 실무용] cron으로 로컬, 개발, 운영 설정값 프로퍼티에 따른 스케줄러 사용 (0) | 2022.08.18 |
[자바 스프링부트 활용 웹개발 실무용] @PostConstruct로 로컬, 개발, 운영 설정값 프로퍼티 클래스 관리 (0) | 2022.08.17 |
공통 파일 업로드 구현
- application.properties에 JSP 사용을 위한 prefix와 suffix 설정
# file - jsp
spring.mvc.view.prefix = /WEB-INF/views/
spring.mvc.view.suffix = .jsp
- webapp/WEB-INF/views 폴더를 만들고 index.jsp 파일 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/file/save" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile"/>
<button type="submit">파일업로드</button>
</form>
</body>
</html>
- pom.xml에 JSP 사용을 위한 2가지 라이브러리 추가
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
- 로컬 환경에서 파일이 저장될 경로 설정
uploadFile.path = C:/home/upload/
- 파일 업로드를 위한 UserController 컨트롤러 생성 및 FileController 수정
@Controller
public class UserController {
@GetMapping("/file/save")
public String saveFileJsp() {
// prefix: /WEB-INF/views
// suffix: .jsp
// 풀경로: /WEB-INF/views/index.jsp
return "index";
}
}
@RestController
@RequestMapping("/file")
@Api(tags = "파일 API")
public class FileController {
...
/**
* 업로드 리턴
* @return
*/
@PostMapping("/save")
@ApiOperation(value = "업로드", notes = "")
public BaseResponse<Boolean> save(@RequestParam("uploadFile") MultipartFile multipartFile) {
logger.debug("multipartFile : {}", multipartFile);
// 파일 업로드 필수 체크
if (multipartFile == null || multipartFile.isEmpty()) {
throw new BaseException(BaseResponseCode.DATA_IS_NULL);
}
// 파일이 저장될 경로
String uploadFilePath = config.getUploadFilePath();
logger.debug("uploadFilePath : {}", uploadFilePath);
// 확장자
String prefix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1, multipartFile.getOriginalFilename().length());
// 파일 이름
String filename = UUID.randomUUID().toString() + "." + prefix;
logger.info("filename : {}", filename);
// 저장될 파일 상위경로의 폴더가 없다면 생성
File folder = new File(uploadFilePath);
if (!folder.isDirectory()) {
folder.mkdirs();
}
String pathname = uploadFilePath + filename;
// 파일 생성
File dest = new File(pathname);
try {
multipartFile.transferTo(dest);
} catch (IOException e) {
e.printStackTrace();
logger.error("e", e);
}
return new BaseResponse<Boolean>(true);
}
}
- 결과
C:/home/upload 폴더에 파일이 저장됨

파일 업로드 정보 DB 저장 및 리소스 접근 설정
- Upload.xml 생성 후 파일 업로드(등록)를 위한 insert 쿼리 작성
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.examplespring.mvc.repository.UploadFileRepository">
<insert id="save" parameterType="com.example.examplespring.mvc.parameter.UploadFileParameter">
INSERT INTO T_UPLOAD_FILE
(
PATHNAME,
FILENAME,
ORIGINAL_FILENAME,
SIZE,
CONTENT_TYPE,
RESOURCE_PATHNAME,
REG_DATE
)
VALUES
(
#{pathname},
#{filename},
#{originalFilename},
#{size},
#{contentType},
#{resourcePathname},
NOW()
}
</insert>
</mapper>
- 파일 등록을 위한 UploadFileParameter, UploadFileRepository, UploadFileService 클래스 생성
@Data
public class UploadFileParameter {
private String pathname;
private String filename;
private String originalFilename;
private int size;
private String contentType;
private String resourcePathname;
}
/**
* 업로드 파일 Repository
* @author gagyeong
*/
@Repository
public interface UploadFileRepository {
void save(UploadFileParameter uploadFile);
}
/**
* 업로드 파일 서비스
* @author gagyeong
*/
@Service
public class UploadFileService {
@Autowired
private UploadFileRepository uploadFileRepository;
/**
* 등록 처리
* @param parameter
*/
public void save(UploadFileParameter parameter) {
uploadFileRepository.save(parameter);
}
}
- 리소스 접근 설정을 위해 파일 resourePath 추가 후 GlobalConfig, WebConfiguration 클래스 수정
uploadFile.resourcePath = /upload/
public class GlobalConfig {
Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ApplicationContext context;
@Autowired
private ResourceLoader resourceLoader;
private String uploadFilePath;
private String uploadResourcePath;
private String schedulerCronExample;
private boolean local;
private boolean dev;
private boolean prod;
@PostConstruct
public void init() {
logger.info("init");
String[] activeProfiles = context.getEnvironment().getActiveProfiles(); // 프로필(local, prod, dev)에 따라 프로퍼티 파일을 가져옴
String activeProfile = "local"; // 기본값
if (ObjectUtils.isNotEmpty(activeProfiles)) {
activeProfile = activeProfiles[0];
}
String resourcePath = String.format("classpath:globals/global-%s.properties", activeProfile);
try {
Resource resource = resourceLoader.getResource(resourcePath);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
// 프로퍼티 파일에 있는 uploadFile.path가 변수에 저장됨
this.uploadFilePath = properties.getProperty("uploadFile.path");
this.uploadResourcePath = properties.getProperty("uploadFile.resourcePath");
this.schedulerCronExample = properties.getProperty("scheduler.cron.example1");
// local로 서버가 올라올 경우 /home/upload
this.local = activeProfile.equals("local");
// dev로 서버가 올라올 경우 /app/upload
this.dev = activeProfile.equals("dev");
// prod로 서버가 올라올 경우 /root/upload
this.prod = activeProfile.equals("prod");
} catch (Exception e) {
logger.error("e", e);
}
}
public String getUploadFilePath() {
return uploadFilePath;
}
public String getUploadResourcePath() {
return uploadResourcePath;
}
...
}
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
...
// 브라우저에서 접근 가능 (URL로 업로드 파일 보기 가능)
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 업로드 파일 static resource 접근 경로
String resourcePattern = config().getUploadResourcePath() + "**";
// 로컬 (윈도우 환경)
if (config().isLocal()) {
registry.addResourceHandler(resourcePattern).addResourceLocations("file:///" + config().getUploadFilePath());
} else {
// 리눅스 도는 유닉스 환경
registry.addResourceHandler(resourcePattern).addResourceLocations("file:" + config().getUploadFilePath());
}
}
}
- DB 저장을 위해 FileController 클래스 수정
/**
* 파일 컨트롤러
* @author gagyeong
*/
@RestController
@RequestMapping("/file")
@Api(tags = "파일 API")
public class FileController {
...
/**
* 업로드 리턴
* @return
*/
@PostMapping("/save")
@ApiOperation(value = "업로드", notes = "")
public BaseResponse<Boolean> save(@RequestParam("uploadFile") MultipartFile multipartFile) {
logger.debug("multipartFile : {}", multipartFile);
if (multipartFile == null || multipartFile.isEmpty()) {
throw new BaseException(BaseResponseCode.DATA_IS_NULL);
}
// 날짜폴더를 추가
String currentDate = new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
String uploadFilePath = config.getUploadFilePath() + currentDate + "/";
logger.debug("uploadFilePath : {}", uploadFilePath);
String prefix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1, multipartFile.getOriginalFilename().length());
String filename = UUID.randomUUID().toString() + "." + prefix;
logger.info("filename : {}", filename);
// 저장될 파일 상위경로의 폴더가 없다면 생성
File folder = new File(uploadFilePath);
if (!folder.isDirectory()) {
folder.mkdirs();
}
String pathname = uploadFilePath + filename;
String resourcePathname = config.getUploadResourcePath() + currentDate + "/" + filename;
// 파일 생성
File dest = new File(pathname);
try {
multipartFile.transferTo(dest);
// 파일 업로드된 후 DB에 저장
UploadFileParameter parameter = new UploadFileParameter();
// 컨텐츠 종류
parameter.setContentType(multipartFile.getContentType());
// 원본 파일명
parameter.setOriginalFilename(multipartFile.getOriginalFilename());
// 저장 파일명
parameter.setFilename(filename);
// 실제 파일 저장 경로
parameter.setPathname(pathname);
// static resource 접근 경로
parameter.setResourcePathname(resourcePathname);
uploadFileService.save(parameter);
} catch (IOException e) {
e.printStackTrace();
logger.error("e", e);
}
return new BaseResponse<Boolean>(true);
}
}
- 결과
DB에 파일이 업로드되고, RESOURCE_PATHNAME 컬럼의 값을 주소창에 붙어넣으면 파일 리소스에 접근 가능

썸네일 만들기
- 썸네일 생성을 위해 pom.xml 설정
<!-- 파일 썸네일 생성 -->
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.13</version>
</dependency>
- 파일이 없을 경우를 위한 메시지 설정
public enum BaseResponseCode {
SUCCESS, // 성공
ERROR, // 실패
LOGIN_REQUIRED, // 로그인
DATA_IS_NULL, // NULL
VALIDATE_REQUIRED, // 필수 체크
UPLOAD_FILE_IS_NULL
;
}
UPLOAD_FILE_IS_NULL = There is no file upload information
- UploadFile, ThumbnailType, ThumbnailController 클래스 생성 및
UploadFileService, UploadFileRepository 클래스 수정
/**
* 썸네일 컨트롤러
* @author gagyeong
*/
@RestController
@RequestMapping("/thumbnail")
@Api(tags = "썸네일 API")
public class ThumbnailController {
final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private UploadFileService uploadFileService;
public void index(@PathVariable int uploadFileSeq) {
uploadFileService.get(uploadFileSeq);
try {
Thumbnails.of("original.jpg").size(160, 160).toFile("thumbnail.jpg");
} catch (IOException e) {
}
}
}
/**
* 업로드 파일 서비스
* @author gagyeong
*/
@Service
public class UploadFileService {
@Autowired
private UploadFileRepository uploadFileRepository;
/**
* 등록 처리
* @param parameter
*/
public void save(UploadFileParameter parameter) {
uploadFileRepository.save(parameter);
}
public UploadFile get(int uploadFileSeq) {
return uploadFileRepository.get(uploadFileSeq);
}
}
/**
* 업로드 파일 Repository
* @author gagyeong
*/
@Repository
public interface UploadFileRepository {
void save(UploadFileParameter uploadFile);
UploadFile get(int uploadFileSeq);
}
@Data
public class UploadFile {
private int uploadFileSeq;
private String pathname;
private String filename;
private String originalFilename;
private int size;
private String contentType;
private String resourcePathname;
}
public enum ThumbnailType {
WEB_MAIN(500, 300),
WEB_SUB(150, 70),
;
private int width;
private int height;
ThumbnailType(int width, int height) {
this.width = width;
this.height = height;
}
public int width() {
return width;
}
public int height() {
return height;
}
}
- 썸네일 생성을 위해 파일 정보를 가져오는 select 쿼리 작성
<select id="get" parameterType="int" resultType="com.example.examplespring.mvc.domain.UploadFile">
SELECT
PATHNAME,
FILENAME,
ORIGINAL_FILENAME,
SIZE,
CONTENT_TYPE,
RESOURCE_PATHNAME,
REG_DATE
FROM T_UPLOAD_FILE UF
WHERE UF.UPLOAD_FILE_SEQ = #{uploadFileSeq}
</select>
- 썸네일 타입을 위한 ThumbnailController 클래스 수정
/**
* 썸네일 컨트롤러
* @author gagyeong
*/
@RestController
@RequestMapping("/thumbnail")
@Api(tags = "썸네일 API")
public class ThumbnailController {
final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private UploadFileService uploadFileService;
@GetMapping("/make/{uploadFileSeq}/{thumbnailType}")
public void index(@PathVariable int uploadFileSeq, @PathVariable ThumbnailType thumbnailType, HttpServletResponse response) {
UploadFile uploadFile = uploadFileService.get(uploadFileSeq);
if (uploadFile == null) {
throw new BaseException(BaseResponseCode.UPLOAD_FILE_IS_NULL);
}
String pathname = uploadFile.getPathname();
File file = new File(pathname);
if (!file.isFile()) {
throw new BaseException(BaseResponseCode.UPLOAD_FILE_IS_NULL);
}
try {
// 본래 파일 이름 + _width_height.확장자
String thumbnailPathname = uploadFile.getPathname().replace(".", "_" + thumbnailType.width() + "_" + thumbnailType.height() + ".");
File thumbnailFile = new File(thumbnailPathname);
if (!thumbnailFile.isFile()) {
Thumbnails.of(pathname).size(thumbnailType.width(), thumbnailType.height()).toFile(thumbnailPathname);
}
response.setContentType(MediaType.IMAGE_PNG_VALUE);
FileCopyUtils.copy(new FileInputStream(thumbnailFile), response.getOutputStream());
logger.info("thumbnailPathname : {}", thumbnailPathname);
} catch (IOException e) {
e.printStackTrace();
logger.error("e", e);
}
}
}
- 결과

'Java-Spring > 자바 스프링부트 활용 웹개발 실무용' 카테고리의 다른 글
[자바 스프링부트 활용 웹개발 실무용] 세션 관리를 Class 구조와 Spring을 활용하여 개발하기 (0) | 2022.09.15 |
---|---|
[자바 스프링부트 활용 웹개발 실무용] 컨트롤러에서 파라미터를 받는 방법들 (0) | 2022.09.02 |
[자바 스프링부트 활용 웹개발 실무용] TypeHandler로 데이터 변환하기 (0) | 2022.08.20 |
[자바 스프링부트 활용 웹개발 실무용] cron으로 로컬, 개발, 운영 설정값 프로퍼티에 따른 스케줄러 사용 (0) | 2022.08.18 |
[자바 스프링부트 활용 웹개발 실무용] @PostConstruct로 로컬, 개발, 운영 설정값 프로퍼티 클래스 관리 (0) | 2022.08.17 |