Search code examples
mongodbgrailsrx-javareactivex

Downloading a file in grails using JavaRx / rx-mongodb


I am trying to download a file in Grails 3.2.1. I have a org.bson.types.Binary Type called "file" saved in mongo-db. The size of the files stored are in kb so no need for GridFS.

I can access the byte[] using the getData() helper that org.bson.types.Binary provides. Using standard mongo-db drivers I can achieve this with the following:-

class DownloadController {

  def stream() {
     def fileDB = FileDB.get(params.id)
     if(fileDB) {
        response.setContentType(fileDB.contentType)
        response.setHeader("Content-disposition",  "filename=${fileDB.id}.wav")
        response.outputStream << fileDB.file.getData()
     } else {
        //handle error
     }
  }


}

With Mongo Rx Drivers and more specifically RxJava. How do I download a file from a Observer subscribe? Grails provides a RxController which provides helpers for rx.render and rx.respond, however I cannot get my head around the response. TBH, I am trying to get my head around ReactiveX! This is what I have so far:-

class DownloadController implements RxController {

   def stream() {

        FileDB.get((Serializable) params.id).subscribe({ fileDB fileDB->
            //How do I handle this??
            response.setContentType(fileDB.contentType)
            response.setHeader("Content-disposition", "filename=${fileDB.id}.wav")
            response.outputStream << fileDB.file.getData()
        })

   }

}

Any advice would also be much appreciated.


Solution

  • This should work. It uses the render method (see http://mrhaki.blogspot.com.es/2013/09/grails-goodness-render-binary-output.html). If it doesn't please report an issue:

    def stream() {
    
        FileDB.get((Serializable) params.id).subscribe({ fileDB fileDB->
            rx.render(fileName:"${fileDB.id}.wav", 
                      file:fileDB.file.getData(),
                      contentType:fileDB.contentType)
        })
    
    }