Develop

[Tika] 파일 업로드시 확장자 확인하기 본문

웹 개발/Spring

[Tika] 파일 업로드시 확장자 확인하기

개발 기록 2024. 6. 21. 23:11

 

파일업로드를 구현하는 도중

파일의 이름에서 확장자를 가져와서 확인하는 방법이 아닌

apache tika 로 파일의 확장자를 확인하는 방법을 알게되었다

 

Tika는 파일의 내용을 확인해서 확장자를 확인하기 때문에

파일 이름만 바꿔서 다른 확장자 파일을 업로드 하려는 것을 방지할 수 있다

 

물론 클라이언트 측에서 JS를 이용해 확장자를 확인하고 

서버에서 Tika로 한번 더 확인한다

 


 

먼저 Service단 코드이다

 

여러개의 파일을 받을 수 있도록 해놨기에 

매개변수가 MultipartFile이 아닌 MultipartFile[] 이고 for문을 사용했다

 

/**
 * 파일 확인 및 저장
 */
@Overrid
public String uploadFile(MultipartFile[] file) throws Exception {

    try {
            if(file != null){

                SOMap fileInfo = new SOMap();

                // 저장경로
                String filePath = "C:/upload/";
                // 저장경로 파일 없으면 생성
                File dir = new File(filePath);
                if(!dir.isDirectory()){
                    dir.mkdir();
                }

                // 허용되는 확장자
                List<String> extensionList = new ArrayList<String>();
                extensionList.add("image/jpg");
                extensionList.add("image/jpeg");
                extensionList.add("image/png");

                // 파일 생성
                for(MultipartFile a : file){

                // UUID, 파일이름, 확장자
                String uuid = UUID.randomUUID().toString();
                String orgname =  FilenameUtils.getBaseName(a.getOriginalFilename());
                String extension = FilenameUtils.getExtension(a.getOriginalFilename());

                fileInfo.put("uuid", uuid);
                fileInfo.put("orgname", orgname);
                fileInfo.put("extension", extension);

                // 확장자 확인 (jpg, jpeg, png)
                InputStream inputStream = a.getInputStream();
                String type = "";
                Tika tika = new Tika();
                type = tika.detect(inputStream);

                if(tika != null){

                    for(String ex : extensionList){
                        if(extension.toUpperCase().equals(ex.toUpperCase())){ // 이미지 파일이면

                        // fileNm = uuid + _ + 파일이름  + . + 확장자
                        String fileNm = uuid + "_" + orgname + "." + extension;

                            // 파일 생성
                            File uploadFile = new File(filePath, fileNm);
                            boolean saveSts = saveFile(a, uploadFile);

                            if(!saveSts) {
                                return "파일 저장 도중 오류가 발생하였습니다.";
                            }

                            uploadFileDao.insertFileInfo(fileInfo);

                        }else{
                            return "첨부가 불가능한 파일입니다.";
                        }
                    }
                }
            }
        }
    } catch (Exception e) {
        // try/catch 구문으로 감싸면 익셉션에서 롤백 강제 해야함.
        e.printStackTrace();
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }
    return "true";
}

 

 

아래의 코드는 파일을 저장하기 위한 코드이다 

( = 개발환경이 로컬일 경우 내 컴퓨터에 저장한다는 뜻)

/**
 * 파일 저장
 * @param multipartFile 파일
 * @param file 저장할 파일
 */
@Override
public boolean saveFile(MultipartFile multipartFile, File file) throws Exception {
    boolean flag = true;
    FileOutputStream fos = null;
    try{
        fos = new FileOutputStream(file);
        fos.write(multipartFile.getBytes());
    }catch (IOException e){
        flag = false;
        logger.error("save file ::::: 쓰기오류 ::::: "+e.getMessage());
    }catch (Exception e){
        flag = false;
        logger.error("save file ::::: ERROR ::::: "+e.getMessage());
    }finally {
        if(fos!=null){
            try{ fos.close(); }catch (IOException e){
                logger.info("save file ::::: CLOSE ::::: "+e.getMessage());
            }
        }
    }
    return flag;
}

 

 


 

파일의 이름에서 확장자를 확인하는 방법은 두가지가 있다

 

1. substring을 이용하여 마지막 . 문자뒤의 문자열을 가져오기

 

for(MultipartFile a : file){

    // 파일이름, 확장자
    // a.getOriginalFilename() : test.png
    
    // 파일 이름에서 마지막 '.' 문자 전까지 문자열 가져오기
    String orgname =  a.getOriginalFilename().substring(0,a.getOriginalFilename().lastIndexOf('.')); // test
    // 파일 이름에서 마지막 '.' 문자 뒤부터 가져오기
    String extension = a.getOriginalFilename().substring(a.getOriginalFilename().lastIndexOf(".") + 1); // png
}

 

 

2. FilenameUtils 사용하기

import org.apache.commons.io.FilenameUtils;

for(MultipartFile a : file){
    
    // a.a.getOriginalFilename() : test.png
    
    String orgname =  FilenameUtils.getBaseName(a.getOriginalFilename()); // test
    String extension = FilenameUtils.getExtension(a.getOriginalFilename()); // png
}

 


 

확장자의 종류는 매우 많기 때문에 

안되는 확장자보다는 첨부 가능한 확장자인지 확인 하는 것이 좋다고 한다