So I am working on this project where I want to store an audio file in a LARGEBLOB on a database, the size of the file is limited to about 10MB, and be able to load the data through a java servlet that allows for playing of the media file.
Most of the sources I have been able to find suggests storing it locally, however, I want to avoid this solution based on the fact that I'd like to rebuild the website somewhere completely different and not have to rely on the folder structure to be the same.
The issues that I am encountering area mainly that the web browser misinterprets the binary data provided by the servlet. It manages to retrieve that it is an audio file of some sort, however; it is unable to determine the type of audio file, which leads me to believe that the servlet is either not providing enough data, or that I am not doing enough to instruct the web browser on how to play the file.
For example, if I have a file audio.mp3 which I have uploaded to the database into a table Tracks and stored in a column TrackFile. Assuming the query of selecting the right song from the table, what data would the servlet need to provide in order for the browser to play the file when accessing the servlet. Currently when I load the servlet, the browser seems to assume that the type is audio/mpeg instead of audio/mp3. The content currently delivered by the servlet also looks something like this:
response.setHeader("Content-Type", this.getServletContext().getMimeType(t.getTrackName() + '.' + t.getFileType()));
response.setHeader("Content-Length", String.valueOf(t.getTrackData().length));
response.setHeader("Content-Disposition", "inline; filename=\"" + t.getTrackName() + '.' + t.getFileType() + "\"");
response.getOutputStream().write(t.getTrackData());
where t is an object which holds all the data which can be retrieved from the database table about a specific track. The method getTrackData() returns a byte[] with contents of the column TrackFile in it. The source of this method is: link, although I adapted it in order to make it work with audio files, although it doesn't.
Are there any obvious things that I should have caught onto based on the fact that I can't get it to play back the file or is what I want to achieve generally impossible so to say?
Related
Eurostat data can be downloaded via a REST API. The response format of the API is a XML file formatted according to the SDMX-ML standard. With SAS, very conveniently, one can access XML files with the libname statement and the XML or XMLv2 engine.
Currently, I am using the xmlv2 engine together with the automap= option to generate an xmlmap to access the data. It works. But the resulting SAS data sets are very unstructured, and for another data set to be downloaded the data structure might change. Also the request might depend on the DSD-file that Eurostat provides for each database item within a different XML file.
Here comes the code:
%let path = /your/working/directory/;
filename map "&path.map.txt";
filename resp "&path.resp.txt";
proc http
URL="http://ec.europa.eu/eurostat/SDMX/diss-web/rest/data/cdh_e_fos/..PC.FOS1.BE/?startperiod=2005&endPeriod=2011"
METHOD="GET"
OUT=resp;
run;quit;
libname resp XMLv2 automap=REPLACE xmlmap=map;
proc datasets;
copy out=WORK in=resp;
run;quit;
With the code above, you can view all downloaded data in your WORK library. Its a mess.
To download another time series change parameters of the URL according to Eurostat's description.
So here is my question
Is there a way to easily generate a xmlmap from a call to the DSD file so that the data are stored in a well structured way?
As the SDMX-ML standard is widely used in public institutions such as the ECB, Eurostat, OECD... I am wondering if somebody has implemented requests to the databases, already. I know about the tool from Banca Italia which uses a javaObject. However, I was wondering if there might be a solution without the javaObject.
EDIT
I solved the issue itself by zipping the XML up and sending it out as application/zip. Still, the question remains why it does not work in plain XML.
I'm currently trying to let users of our website download an xml-file with so called "late responses", in case the automatic processing fails and their requests need to be looked at by a person. The site is basically just a simple GUI over a soap-webservice for the non-technical-inclined, but thats not that important for the issue.
When there are late responses, the site shows the total number and offers to download them, I'm currently archieving this via
// XML-content is aggregated and written to response outputstream
response.setCharacterEncoding("UTF-8");
response.setContentType(MediaType.APPLICATION_XML_VALUE);
response.setHeader("Content-Disposition", "attachment; filename=" + "ergebnisprot_" + new DateTime().toString("ddMMyyyyHHmmSS") + ".xml");
response.flushBuffer();
This works well if only about one to five responses are aggregated. The browser gets a download-popup and everything goes the way it is supposed to go.
But with larger files, depending on the individual size, but usually from about 10 responses upward, this popup does not appear. Instead, the browser renders the xml itself, which is undesirable, since it's considered of no use to the user to not have the file on his harddrive, or to have to then copy it himself into a file.
Does anyone know why this behaviour happens? Did I miss something in my header configuration?
I need to read several megabytes (raw text strings) out of my GAE Datastore and then write them all to a new PDF file, and then make the PDF file available for the user to download.
I am well aware of the sandbox restrictions that prevent you from writing to the file system. I am wondering if there is a crafty way of creating a PDF in-memory (or a combo of memory and the blobstore) and then storing it somehow so that the client-side (browser) can actually pull it down as a file and save it locally.
This is probably a huge stretch, but my only other option is to farm this task out to a non-GAE server, which I would like to avoid at all cost, even if it takes a lot of extra development on my end. Thanks in advance.
You can definitely achieve your use case using GAE itself. Here are the steps that you should follow at a high level:
Download the excellent iText library, which is a Java library to work with PDFs. First build out your Java code to generate the PDF content. Check out various examples at : http://itextpdf.com/book/toc.php
Since you cannot write to a file directly, you need to generate your PDF content in bytes and then write a Servlet which will act as a Download Servlet. The Servlet will use the Response object to open a stream, manipulate the Mime Headers (filename, filetype) and write the PDF contents to the stream. A browser will automatically present a download option when you do that.
Your Download Servlet will have high level code that looks like this:
public class DownloadPDF extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
//Extract some request parameters, fetch your data and generate your document
String fileName = "<SomeFileName>.pdf";
res.setContentType("application/pdf");
res.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
writePDF(<SomeObjectData>, res.getOutputStream());
}
}
}
Remember the writePDF method above is your own method, where you use iText libraries Document and other classes to generate the data and write it ot the outputstream that you have passed in the second parameter.
While I'm not aware of the PDF generation on Google App Engine and especially in Java, but once you have it you can definitely store it and later serve it.
I suppose the generation of the PDF will take more than 30 seconds so you will have to consider using Task Queue Java API for this process.
After you have the file in memory you can simply write it to the Blobstore and later serve it as a regular blob. In the overview you will find a fully functional example on how to upload, write and serve your binary data (blobs) on Google App Engine.
I found a couple of solutions by googling. Please note that I have not actually tried these libraries, but hopefully they will be of help.
PDFJet (commercial)
Write a Google Drive document and export to PDF
I have never saved and retrieved an image to and from the database before. I wrote down what I guessed would be the process. I would just like to know if this is correct though:
Save image:
Select & Upload image file from jsp (Struts 2) which will save it as a .tmp file.
Convert the .tmp file to a byte[] array (Java Server-Side)
Store the byte[] array as a blob in the database (Java Server-Side)
Get image:
Get the byte[] array from the database (Java Server-Side)
Convert the byte[] array to an image file (Java Server-Side)
Create the file in a location (Java Server-Side)
Use an img tag to display the file (JSP Client-Side)
Delete the file after it's finished being used? (Java Server-Side)
I'm aware of the fact that it is highly recommended to not save & retrieve images to and from the database. I would like to know how to do it anyway.
Thanks
Almost correct.
It's expensive and not so great to create the file on the fly and then delete it.
Yes, you store it as the raw bytes in the database, but the way to retrieve it and display it to a client machine is to implement a web handler that sets the content-type of the response to the appropriate MIME type and then dumps the bytes out to the response stream.
Yes, You get it right.
Save Image :
The decision to save image is very much dependent on further usage. You have one option to save the file on the file system. The location for saved file should be saved into the metadata in the database table.
Get Image:
You do not have to right file data on any temp location. It can be easily rendered from the database only. Just send a request from client and intercept that request in a spacial designed Servlet. This Servlet will read the file metadata and corresponding file, if successful, write the file back on the response stream.
I have a Struts2 jsp page their i am sending one image, Temporary file path is comming to my java class after form submission but i do not know how can to save that path in db by changing it to Blob type.. Please consider this image columns is of blob type in my database table..
Here is the output what am getting in my Javaclass after the form submission:
My image path:
F:\Documents and Settings\software.netbeans\7.0\apache-tomcat-7.0.11_base\work\Catalina\localhost\AIGSA\upload__214d4f3e_136e8b74d9c__7fff_00000021.tmp 105542
filenames:
* Winter.jpg
Code:
for (File u: repImage)
{
System.out.println("*** "+u+"\t"+u.length());
}
int saveToDb= mo.addMembers(memberName, repImage);
How can I send my form Image to this {repImage Name, so that it will be easy to save it so my db
am not sure, but try:
int saveToDb= mo.addMembers( memberName, repImage.getBytes() );
If I understand your question properly, you want to store the binary data in your database. I'd say this is a bad idea in the first place for multiple reasons. A better method would be to reference a relative path that you can then use in your web application or the file system directly. Better yet, just store the reference to the location in Amazon/S3 where you want to save it/use it.
Regardless, to answer your question you would want to use ByteArrayOutputStream.