feat: 파일 관련 공통 기능 추가

dev
Lim Jonguk 3 years ago
parent ff8b9bfd30
commit 983b188343

@ -0,0 +1,19 @@
package com.xit.biz.cmm.service;
import com.xit.biz.ctgy.entity.MinInfoBoard680;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Nonnull;
import java.util.List;
/**
* @author Lim, Jong Uk (minuk926)
* @since 2021-07-16
*/
public interface ICmmFileService {
MinInfoBoard680 findFiles(Long inCode);
List<MinInfoBoard680> saveFiles(@Nonnull MinInfoBoard680 minInfoBoard680, MultipartFile[] files);
void removePublicBoardFile(Long inCode);
}

@ -0,0 +1,177 @@
package com.xit.biz.cmm.service.impl;
import com.xit.biz.cmm.service.ICmmFileService;
import com.xit.biz.ctgy.CtgyConstants;
import com.xit.biz.ctgy.entity.MinInfoBoard680;
import com.xit.biz.ctgy.repository.IPublicBoardRepository;
import com.xit.core.constant.ErrorCode;
import com.xit.core.exception.CustomBaseException;
import com.xit.core.support.jpa.JpaUtil;
import com.xit.core.util.AssertUtils;
import com.xit.core.util.Checks;
import com.xit.core.util.DateUtil;
import io.jsonwebtoken.lang.Assert;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Slf4j
@Service
@RequiredArgsConstructor
public class CmmFileService implements ICmmFileService {
@Value("${file.cmm.upload.root:c:/data/file/upload}")
private String rootPath;
@Value("${file.cmm.upload.path:/kangnamSIM/simUpFile/}")
private String uploadPath;
@Value("${file.cmm.upload.url}")
private String serviceUrl;
@Value("${file.cmm.upload.allow.ext:}")
private String allowExt;
@Value("${file.cmm.upload.max.size:1024}")
private long maxSize;
private final IPublicBoardRepository repository;
@Override
public MinInfoBoard680 findFiles(Long inCode) {
Assert.notNull(inCode, "대상 게시글[inCode]을 선택해 주세요.");
return repository.findById(inCode).orElse(null);
}
/**
*
* CmmFileMst.fileMstId null, not null
* DB
*
* @param entity MinInfoBoard680
* @param files MultipartFile[]
* @return CmmFileMst
*/
@Override
@Transactional
public List<MinInfoBoard680> saveFiles(@Nonnull MinInfoBoard680 entity, MultipartFile[] files) {
List<MinInfoBoard680> entityList = new ArrayList<>();
if(files != null && files.length > 0){
String makePath = File.separator + DateUtil.getToday("");
// 파일 경로 : upload root 제외
String urlPath = this.uploadPath + makePath;
// 물리적인 파일 저장 위치
String fileUploadPath = this.rootPath + urlPath;
File file = new File(fileUploadPath);
if(!file.exists()) file.mkdirs();
for(MultipartFile mf : files) {
if (!mf.isEmpty()) {
String orgFileName = "";
try {
orgFileName = StringUtils.cleanPath(Objects.requireNonNull(mf.getOriginalFilename()));
MinInfoBoard680 savedEntity = null;
// 파일 저장 && 전송
if(Checks.isEmpty(entity.getInCode()))
savedEntity = new MinInfoBoard680();
else
savedEntity = repository.findById(entity.getInCode()).orElseGet(MinInfoBoard680::new);
savedEntity.setInFilename(orgFileName);
savedEntity.setInFilesize(mf.getSize());
savedEntity.setInFileurl(serviceUrl + urlPath);
setEntity(savedEntity, entity);
JpaUtil.saveIfNullId(entity.getInCode(), repository, savedEntity);
entityList.add(savedEntity);
mf.transferTo(new File(fileUploadPath + File.separator + orgFileName));
// inputStream을 가져와
// copyOfLocation (저장위치)로 파일을 쓴다.
// copy의 옵션은 기존에 존재하면 REPLACE(대체한다), 오버라이딩 한다
//Files.copy(multipartFile.getInputStream(), copyOfLocation, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
String errMsg = String.format("File Upload Error :: %s", orgFileName);
//TODO : 에러처리
//return RestError.of(String.format("File Upload Error :: %s", orgFileName));
AssertUtils.isTrue(false, String.format("File Upload Error :: %s", orgFileName));
}
}
}
}else{
MinInfoBoard680 savedEntity = null;
if(Checks.isEmpty(entity.getInCode()))
savedEntity = new MinInfoBoard680();
else
savedEntity = repository.findById(entity.getInCode()).orElseGet(MinInfoBoard680::new);
setEntity(savedEntity, entity);
JpaUtil.saveIfNullId(entity.getInCode(), repository, savedEntity);
}
return entityList;
}
@Override
@Transactional
public void removePublicBoardFile(Long inCode) {
MinInfoBoard680 savedEntity = repository.findById(inCode).orElseThrow(() -> new CustomBaseException(ErrorCode.NOT_FOUND));
repository.delete(savedEntity);
// 정보 삭제후 파일 삭제 : 에러 발생시 skip
if(Checks.isNotEmpty(savedEntity.getInFilename())){
String absFile = rootPath + savedEntity.getInFileurl().split(serviceUrl)[1]+File.separator + savedEntity.getInFilename();
try {
File file = new File(absFile);
if (Checks.isNotEmpty(file) && file.exists()) file.delete();
}catch(Exception e){
//
}
}
}
private void setEntity(MinInfoBoard680 savedEntity, MinInfoBoard680 entity){
savedEntity.setInBgubun(CtgyConstants.PublicBoard.GUBUN.getCode());
savedEntity.setInDept(entity.getInDept());
savedEntity.setInTitle(entity.getInTitle());
savedEntity.setInContents(entity.getInContents());
if(Checks.isEmpty(entity.getInCode())) {
savedEntity.setInCode(repository.getInCodeByInBgubun());
savedEntity.setInContentno(savedEntity.getInCode());
}
}
}
/*
// File.seperator 는 OS종속적이다.
// Spring에서 제공하는 cleanPath()를 통해서 ../ 내부 점들에 대해서 사용을 억제한다
Path copyOfLocation = Paths.get(uploadDir + File.separator + StringUtils.cleanPath(multipartFile.getOriginalFilename()));
try {
// inputStream을 가져와서
// copyOfLocation (저장위치)로 파일을 쓴다.
// copy의 옵션은 기존에 존재하면 REPLACE(대체한다), 오버라이딩 한다
Files.copy(multipartFile.getInputStream(), copyOfLocation, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
throw new FileStorageException("Could not store file : " + multipartFile.getOriginalFilename());
}
*/

@ -1,9 +1,7 @@
package com.xit.biz.ctgy.controller;
import com.xit.biz.ctgy.dto.GnRecallScDto;
import com.xit.biz.ctgy.dto.MinInfoBoard680Dto;
import com.xit.biz.ctgy.dto.struct.GnRecallScMapstruct;
import com.xit.biz.ctgy.entity.MinInfoBoard680;
import com.xit.biz.ctgy.service.IResidentService;
import com.xit.core.api.IRestResponse;
import com.xit.core.api.RestResponse;

Loading…
Cancel
Save