从Spring @Controller返回具有OutputStream的文件 [英] Return file from Spring @Controller having OutputStream

查看:84
本文介绍了从Spring @Controller返回具有OutputStream的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从Spring控制器返回一个文件.我已经有了可以给我OutputStream的任何实现的API,然后我需要将其发送给用户.

I want to return a file from a Spring controller. I already have API that can give me any implementation of OutputStream and then I need to send it to a user.

所以流程是这样的:

获取输出流-> 服务将该输出流传递给控制器​​-> 控制器必须将其发送给用户

getting outputstream -> service passes this outputstream to controller -> controller has to send it to a user

我认为我需要输入流来做到这一点,并且我还发现了如下所示的Apache Commons api功能:

I think I need inputstream to do it and I have also found Apache Commons api feature that looks like this:

IOUtils.copy(InputStream is, OutputStream os)

但是问题是,它将其转换为另一面->不是从操作系统转换为 is ,而是从 is 转换为操作系统.

but the problem is, it converts it to the other side -> not from os to is, but from is to os.

要明确,因为我看到答案没有正确地解决问题:
我使用Dropbox api并在OutputStream中接收文件,并希望在输入一些URL时将此输出流发送给用户

to be clear, because I see the answers are not hitting right thing:
I use Dropbox api and recieve file in OutputStream and I want this output stream to be sent to user while entering some URL

FileOutputStream outputStream = new FileOutputStream(); //can be any instance of OutputStream
DbxEntry.File downloadedFile = client.getFile("/fileName.mp3", null, outputStream);

这就是为什么我要谈论将 outputstream 转换为 inputstream 的原因,但是却不知道该怎么做.此外,我想有更好的方法来解决这个问题(也许从输出流以某种方式返回字节数组)

Thats why i was talking about converting outputstream to inputstream, but have no idea how to do it. Furthermore, I suppose that there is better way to solve this (maybe return byte array somehow from outputstream)

我试图通过参数将servlet输出流[response.getOutputstream()]传递给从Dropbox下载文件的方法,但那根本没有用

I was trying to pass servlet outputstream [response.getOutputstream()] through parameter to the method that downloads file from dropbox, but it didnt work, at all

我的应用程序的流程"是这样的:@Joeblade

The "flow" of my app is something like this: @Joeblade

  1. 用户输入网址:/download/{file_name}

Spring Controller捕获URL并调用 @Service层以下载文件并将其传递给该控制器:

Spring Controller captures the url and calls the @Service layer to download the file and pass it to that controller:

@RequestMapping(value = "download/{name}", method = RequestMethod.GET)
public void getFileByName(@PathVariable("name") final String name, HttpServletResponse response) throws IOException {
    response.setContentType("audio/mpeg3");
    response.setHeader("Content-Disposition", "attachment; filename=" + name);
    service.callSomeMethodAndRecieveDownloadedFileInSomeForm(name); // <- and this file(InputStream/OutputStream/byte[] array/File object/MultipartFile I dont really know..) has to be sent to the user
}

  • 现在@Service调用 Dropbox API 并通过指定的 file_name 下载文件,并将其全部放入OutputStream,然后将其传递(在某些情况下形式..可能是OutputStream,byte []数组或任何其他对象-我不知道哪个更好地使用)到控制器:

  • Now the @Service calls Dropbox API and downloads the file by specified file_name, and puts it all to the OutputStream, and then passes it (in some form.. maybe OutputStream, byte[] array or any other object - I dont know which is better to use) to the controller:

    public SomeObjectThatContainsFileForExamplePipedInputStream callSomeMethodAndRecieveDownloadedFileInSomeForm(final String name) throws IOException {
        //here any instance of OutputStream - it needs to be passed to client.getFile lower (for now it is PipedOutputStream)
        PipedInputStream inputStream = new PipedInputStream(); // for now
        PipedOutputStream outputStream = new PipedOutputStream(inputStream);
    
    
        //some dropbox client object
        DbxClient client = new DbxClient();
        try {
            //important part - Dropbox API downloads the file from Dropbox servers to the outputstream object passed as the third parameter
            client.getFile("/" + name, null, outputStream);
        } catch (DbxException e){
            e.printStackTrace();
        } finally {
            outputStream.close();
        }
        return inputStream;
    }
    

  • 控制者接收到文件(我完全不知道,就像我上面所说的那样),然后将其传递给用户

  • Controler recieves the file (I dont know, at all, in which form as I said upper) and passes it then to the user

    所以事情是通过调用dropboxClient.getFile()方法来接收下载文件的OutputStream,然后将此包含下载文件的OutputStream发送给用户,该怎么做?

    So the thing is to recieve OutputStream with the downloaded file by calling dropboxClient.getFile() method and then this OutputStream that contains the downloaded file, has to be sent to the user, how to do this?

    推荐答案

    您可以使用ByteArrayOutputStreamByteArrayInputStream.示例:

    // A ByteArrayOutputStream holds the content in memory
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    
    // Do stuff with your OutputStream
    
    // To convert it to a byte[] - simply use
    final byte[] bytes = outputStream.toByteArray();
    
    // To convert bytes to an InputStream, use a ByteArrayInputStream
    ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
    

    您可以对其他个流对执行相同的操作.例如.文件流:

    You can do the same with other stream pairs. E.g. the file streams:

    // Create a FileOutputStream
    FileOutputStream fos = new FileOutputStream("filename.txt");
    
    // Write contents to file
    
    // Always close the stream, preferably in a try-with-resources block
    fos.close();
    
    // The, convert the file contents to an input stream
    final InputStream fileInputStream = new FileInputStream("filename.txt");
    

    而且,当使用Spring MVC时,您肯定可以返回包含文件的byte[].只需确保使用@ResponseBody注释您的回复即可.像这样:

    And, when using Spring MVC you can definitely return a byte[] that contains your file. Just make sure that you annotate your response with @ResponseBody. Something like this:

    @ResponseBody
    @RequestMapping("/myurl/{filename:.*}")
    public byte[] serveFile(@PathVariable("file"} String file) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
        DbxEntry.File downloadedFile = client.getFile("/" + filename, null, outputStream);
        return outputStream.toByteArray();
    } 
    

    这篇关于从Spring @Controller返回具有OutputStream的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆