Dog
Dog

Reputation: 2906

How to download a file as a blob/byte in Java/Spring

I have a Spring Boot app that allows a user to upload files (such as .doc or jpegs) and saves them to an H2 database. While I'm able to save and retrieve the files from the database, and save the data as a byte, I am not able to allow the user to download the file to their machine.

Existing solutions I have found online, such as this one

either do not account for the Blob being saved as a byte or involve complex sql queries that don't seem to fit into the context of my app or controller action.

How can I download the blob to the user's machine after retrieving it from the H2 database?

The current controller action I have is triggered from an href:

    @GetMapping("/download")
    public String downloadFile() {
        List<Files> files = fileMapper.getFiles();
        Files newFile = files.get(0);
        byte[] downloadedFile = newFile.getFileData();
        return "home";
    }

I also have my repo here:

https://github.com/jwolfe890/superDuperDrive1

Upvotes: 0

Views: 13159

Answers (2)

Sann Tran
Sann Tran

Reputation: 179

You can import Resource from org.springframework.core.io.Resource and create InputStreamResource from your file, should looks like this:

    public ResponseEntity<Resource> downloadFile() {
            byte[] bytes = yourMethodToGetByteBlobFromDB(....);            
            InputStreamResource resource = new InputStreamResource(new ByteArrayInputStream(bytes));
            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Disposition", String.format("attachment; filename=your_file_name"));    
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(bytes.length)
                    .contentType("application/octet-stream")
                    .body(resource);
    }

Upvotes: 2

Sridhar Patnaik
Sridhar Patnaik

Reputation: 1118

Below code works perfectly for me.

Download logic in service class

public ResponseEntity<Resource> downloadFile(String fileId) throws Exception 
    {
        try
        {
            DBFile dbFile = dbFileStorageService.getFile(fileId);
            return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(dbFile.getFileType()))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + dbFile.getFileName() + "\"")
                .body(new ByteArrayResource(dbFile.getData()));
        }   
        catch(Exception e)
        {
            throw new Exception("Error downloading file");
        }
    }

DB File Storeage service

public DBFile getFile(String fileId) throws Exception {
        return dbFileRepository.findById(fileId)
                .orElseThrow(() -> new Exception("File not found with id " + fileId));
    }

DB File Repo

@Repository
public interface DBFileRepository extends JpaRepository<DBFile, String> {

}

Entity Class for DB file

@Entity
@Table(name = "files")
public class DBFile {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    private String fileName;

    private String fileType;

    @Lob
    private byte[] data;
//getter and setter

}

Upvotes: 2

Related Questions