2

Brief Story: I have a Servlet which receives a request (getContentType() = audio/x-wav) that I can't read. I need to read this wave and save it on the server side.

Detailed Story: I know nothing about Flex, javascript, PHP and Python, I want to record (from the client side "Browser") a wave file and send it to the server to save it (for further ASR processing).

After some searching I found a library called Wami-Recorder (uses flex and java scrip) which I already used, but it didn't give me any java server side example, it also lacks the documentation so I decided to get my hands dirty to get it working. it contains a server side python and PHP example (I will list the PHP one):

<?php    
# Save the audio to a URL-accessible directory for playback.    
parse_str($_SERVER['QUERY_STRING'], $params);    
$name = isset($params['name']) ? $params['name'] : 'output.wav';    
$content = file_get_contents('php://input');    
$fh = fopen($name, 'w') or die("can't open file");    
fwrite($fh, $content);    
fclose($fh);    
?>    

A final note is that I am sure if I created a socket server and directed the request to it, I will be able to get the media easily, but I want everything to be handled by the Servlets.

Ahmed Hassanien
  • 527
  • 5
  • 18
  • 1
    This is in essence already answered in http://stackoverflow.com/questions/2422468/how-to-upload-files-to-server-using-jsp-servlet/2424824#2424824 Is that indeed the same question as you're basically asking? The file type does actually not matter at all when dealing with file uploads. – BalusC Jan 08 '13 at 02:36
  • May be you are right and I didn't dig enough I will try it and report you. – Ahmed Hassanien Jan 08 '13 at 02:53
  • @BalusC it did not work by either ways (Apache Commons Or Web 3.0) as I mentioned before in my question the content type is a wav file not a form data. `the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is audio/x-wav` – Ahmed Hassanien Jan 12 '13 at 15:37
  • Well, it seems that you've to homebrew it. Perhaps the whole request body already represents the whole file? If so, then you should theoretically already be set by just getting it by `request.getInputStream()`. That's also basically what PHP's `php://input` returns. Give it a try. Write it to some `FileOutputStream` and test it. – BalusC Jan 12 '13 at 15:40
  • @BalusC `request.getInputStream().available()` returns 0. I feel like because the stream is only read one time and the container already read it to parse the request. – Ahmed Hassanien Jan 12 '13 at 15:46
  • The `InputStream#available()` doesn't return the total length of the input stream at all. Please carefully read the javadoc and never use it until you really understand what it returns. The `request.getInputStream()` may indeed return nothing when you've used any of the `request.getParameterXxx()` method beforehand which will indeed implicitly parse the request body to extract the parameters. If those parameters are supplied in the request query string, then you should use `request.getQueryString()` instead and parse the parameters yourself. – BalusC Jan 12 '13 at 15:56
  • @BalusC Finally :) read `InputStream`, saved it and the wave is finally on server. Can you post the following code as an answer because you solved it (to vote it up), and for others to benefit. `protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { InputStream filecontent = request.getInputStream(); FileOutputStream fos = new FileOutputStream("file.wav"); int read; byte[] content = new byte[1024]; while ((length = filecontent.read(content)) > 0) { fos.write(content); } fos.close(); }` – Ahmed Hassanien Jan 12 '13 at 17:20
  • @BalusC BTW the `QueryString` equal null but I do not care. And thank you very much for the great help. I really appreciated it :) – Ahmed Hassanien Jan 12 '13 at 17:30

1 Answers1

2

Basically, the Java servlet equivalent of the following line of PHP, which is the key line in the code,

$content = file_get_contents('php://input');    

is

InputStream input = request.getInputStream();

This returns basically the sole HTTP request body. You can write it to an arbitrary OutputStream the usual Java way. For example, a new FileOutputStream("/some.wav").

You should only realize that the HTTP request body can be read only once and also that it would implicitly be parsed when you invoke any of the request.getParameterXxx() methods. So if you're interested in the parameters in the request URI query string as well, then you should instead use

String queryString = request.getQueryString();

and parse it further yourself (i.e. split on &, then split on =, then URLDecode the name and value).

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555