如何在Java/Spring中将文件下载为blob/byte

huangapple go评论60阅读模式
英文:

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.

现有的在线解决方案,比如这个链接,要么没有考虑将Blob保存为字节,要么涉及到复杂的SQL查询,似乎不适合我的应用程序或控制器操作上下文。

从H2数据库中检索数据后,我该如何将Blob下载到用户的机器上?

我当前的控制器操作是从href触发的:

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

我还有我的repo链接:

https://github.com/jwolfe890/superDuperDrive1

英文:

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(&quot;/download&quot;)
    public String downloadFile() {
        List&lt;Files&gt; files = fileMapper.getFiles();
        Files newFile = files.get(0);
        byte[] downloadedFile = newFile.getFileData();
        return &quot;home&quot;;
    }

I also have my repo here:

https://github.com/jwolfe890/superDuperDrive1

答案1

得分: 2

你可以从org.springframework.core.io.Resource导入Resource,然后从你的文件创建InputStreamResource,应该是这样的:

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);
}
英文:

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

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

答案2

得分: 2

以下代码对我来说完全正常运行。

在服务类中的下载逻辑

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文件存储服务类

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

DB文件存储库

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

}

DB文件的实体类

@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

}
英文:

Below code works perfectly for me.

Download logic in service class

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

DB File Storeage service

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

DB File Repo

@Repository
public interface DBFileRepository extends JpaRepository&lt;DBFile, String&gt; {

}

Entity Class for DB file

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

    private String fileName;

    private String fileType;

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

}

huangapple
  • 本文由 发表于 2020年7月28日 10:30:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/63126181.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定