반응형

postgresql에는 Oracle의 BLOB 형타입이 없다. 바이너리 데이터를 다룰려면 BYTEA 형타입을 사용해야 함.

 

1. TEXT 타입에 base64 데이터 다운로드

public static void downloadFile(HttpServletResponse response, FileVO file) {

		String fileName = file.getFile_name();
		String base64String = file.getFile_text();
		
		// Base64 인코딩된 데이터에서 "data:image/jpeg;base64," 부분을 제거
        String base64Data = base64String.substring(base64String.indexOf(",") + 1);

        // Base64 문자열을 바이너리 데이터로 디코딩
        byte[] binaryData = Base64.getDecoder().decode(base64Data);
        
        try {
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName,"UTF-8") + "\"");
            OutputStream outputStream = response.getOutputStream();
            outputStream.write(binaryData);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
}

 

2. BYTEA 타입에 바이너리 데이터 다운로드

public static void downloadFile(HttpServletResponse response, FileVO file) {

		String fileName = file.getFile_name();
        byte[] binaryData = file.getFile_contents();
        
        try {
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName,"UTF-8") + "\"");
            OutputStream outputStream = response.getOutputStream();
            outputStream.write(binaryData);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
}

 

+) VO

public class FileVO {
    private byte[] file_contents;
    private String file_text;

	~~
    
}

 

++) JPA Entity에서 bytea 타입 쓸 경우 

@Entity
@Table(name="tops_file_test")
@Getter @Setter
public class FileEntity {

    @Id
    private String FILE_ID;

    @Column(name = "file_name")
    private String file_name;

    @Type(type="org.hibernate.type.BinaryType")
    @Column(name = "file_contents", columnDefinition="bytea")
    private byte[] file_contents;

}

 

 

*파일 업로드는 MDN 참고해서 result 값을 insert 시키면 된다.

 

<핵심>

new FileReader();

fr.result 

readAsDataURL();

// Given this HTMLInputElement of type="file":
// <input id="image" type="file" accept="image/*">

function reader(file, callback) {
  const fr = new FileReader();
  fr.onload = () => callback(null, fr.result);
  fr.onerror = (err) => callback(err);
  fr.readAsDataURL(file);
}

document.querySelector("#image").addEventListener("change", (evt) => {
  // No files, do nothing.
  if (!evt.target.files) {
    return;
  }
  reader(evt.target.files[0], (err, res) => {
    console.log(res); // Base64 `data:image/...` String result.
  });
});

https://developer.mozilla.org/en-US/docs/Web/API/FileReader/result


서버에 저장된 FILE들을 바이너리 데이터로 변환하여 DB 저장

모두 SEELCT해서 for문 돌리면서 실 파일 데이터를 바이너리 데이터로 변환하여 DB에 저장

(위의 다운로드 코드로 DB SELECT해서 바이너리 데이터를 다운처리 가능)

 

나는 DB 용량 때문에 서버 경로에 저장하는게 괜찮다고 생각하지만 ,, 요구사항이 이렇다!

@RequestMapping("/fileTest")
    public void fileTest (HttpServletResponse response){
        String filePath = "C:/file_test/";

        for (FileEntity file : fileRepository.findAll()) {
            byte[] bytes = FileUtil.FileToData(filePath+file.getFILE_ID());
            file.setFile_contents(bytes);

            fileRepository.save(file);
        }

       // FileUtil.downloadFile(response, bytes);
    }
public static byte[] FileToData(String filePath) {
        byte[] fileBytes = null;
        try {
            InputStream inputStream = new FileInputStream(new File(filePath));

            fileBytes = inputStream.readAllBytes();

            System.out.println("File saved to database.");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileBytes;
    }
반응형