Reputation: 387
I am using scala and play framework to create an API server. On one of my API calls, I upload a JSON and after some meddling on the server, I send back an XML. This XML should then be downloaded as a text file and I figured it was easiest if I directly start a download in the backend and don't just create the file in the front-end.
I have successfully created the XML I wanted using the scala.xml
package and I do have now a node
object, that when printed looks strikingly like the XML I am looking for.
Scala's scala.xml.XML
object has a method, aptly called save
that allows me to make a file out of the XML. I could use that to create my XML, but that means that I have to save it on the hard drive, which is its own can of worms. But I am kind of dead in the water in how to save the file in RAM. Can anyone help me out here?
EDIT 1:
To clarify, on the front-end side I am calling this API with axios. At my user's computer, there should be a downloading dialogue opening, asking my user where to save the file which might be called foo.xml
. As I understand it, I need to transform my XML into a file stream. I can do this easily by just saving it on the hard drive and use java.nio
on it, but I was hoping there was a way to avoid the write on the hard drive just to read it back into a file stream and then delete it routine.
Upvotes: 0
Views: 94
Reputation: 387
So, for everyone with a similar issue. It seems to be a much easier to change the data in the frontend and force the download.
I returned the data just as Matthias A. Eckhart suggested. And in the frontend I fed the data in this little function:
function download(filename, text) {
const element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
This solution was found here: https://stackoverflow.com/a/18197341/9094259
Credits to Matěj Pokorný
Upvotes: 0
Reputation: 5156
As far as I understood, you want to serve your clients an XML, i.e., sending an HTTP response with Content-Type: application/xml
.
If this is what you want to do, then just pass your scala.xml.NodeSeq
as an argument to your Ok
call in the respective Action
. As stated in the documentation, the Play Framework will automatically set the correct Content-Type
in the response. There's no need to save the XML to a file beforehand, as you can directly send the XML as a response.
For example:
class MyController extends Controller {
def processXml = Action { implicit request =>
// Process XML
val myXml: NodeSeq = getXml()
Ok(myXml)
}
}
Upvotes: 1