Identifying the Content-Type of a file for HttpURLConnection

  • Thread starter Public Network Services
  • Start date
P

Public Network Services

Hi...

I am playing with HttpURLConnection to upload files to a remote server
and cannot seem to figure out a consistent way of identifying the
Content-Type of a file to be uploaded. I assumed that "application/
octet-stream" would be a generic type to supply, but apparently this
is not the case.

More specifically, I can read a file into a byte array (fileBytes) and
open an HttpConnection to a destination URL (url), but setting the
Content-Type property does not work. The code I use is:

HttpURLConnection connection = url.openConnection();
connection.setRequestProperty("Content-Length",
String.valueOf(fileBytes.length));
connection.setRequestProperty("Content-Type", "application/octet-
stream");

If, immediately after the above, I do a

connection.getContentType()

I get a null value (or an Exception saying that the connection is
already connected)!

Eventually, my file gets uploaded through the
connection.getOutputStream(), by simply doing

DataOutputStream output = new
DataOutputStream(connection.getOutputStream());
output.write(fileContents);

but its Content-Type not being properly set causes the server to not
recognize it (e.g., if it is an MP3 file, it does not get the
speakerphone icon that MP3 files get in the serverÅ› web interface,
when uploaded via that interface, through a browser).

Obviously, this is a solved problem given the multitude of properly
working Java-based web clients, so I 'd really aprpeciate
someone pointing me to the correct solution.

In other words, my questions are:

(a) How can I (automatically) identify the Content-Type of a file in
Java?
(b) How can I properly set that Content-Type in an HttpURLConnection?

Many thanks!
 
A

Arne Vajhøj

I am playing with HttpURLConnection to upload files to a remote server
and cannot seem to figure out a consistent way of identifying the
Content-Type of a file to be uploaded. I assumed that "application/
octet-stream" would be a generic type to supply, but apparently this
is not the case.

More specifically, I can read a file into a byte array (fileBytes) and
open an HttpConnection to a destination URL (url), but setting the
Content-Type property does not work. The code I use is:

HttpURLConnection connection = url.openConnection();
connection.setRequestProperty("Content-Length",
String.valueOf(fileBytes.length));
connection.setRequestProperty("Content-Type", "application/octet-
stream");

If, immediately after the above, I do a

connection.getContentType()

I get a null value (or an Exception saying that the connection is
already connected)!

Eventually, my file gets uploaded through the
connection.getOutputStream(), by simply doing

DataOutputStream output = new
DataOutputStream(connection.getOutputStream());
output.write(fileContents);

but its Content-Type not being properly set causes the server to not
recognize it (e.g., if it is an MP3 file, it does not get the
speakerphone icon that MP3 files get in the serverÅ› web interface,
when uploaded via that interface, through a browser).

Obviously, this is a solved problem given the multitude of properly
working Java-based web clients, so I 'd really aprpeciate
someone pointing me to the correct solution.

In other words, my questions are:

(a) How can I (automatically) identify the Content-Type of a file in
Java?
(b) How can I properly set that Content-Type in an HttpURLConnection?

application/octet-stream is fine.

You need to specify method as POST.

You should not use DataOutputStream just OutputStream is fine.

And most important you need to know whether the receiver expects
a raw POST or a form submit with a field of type FILE.

Those are not send identical!

Arne
 
P

PNS

application/octet-stream is fine.

You need to specify method as POST.

You should not use DataOutputStream just OutputStream is fine.

And most important you need to know whether the receiver expects
a raw POST or a form submit with a field of type FILE.

Those are not send identical!

Arne


Hi...

I do specify setRequestMethod("POST").

You are right about OutputStream, using DataOutputStream only for
writing as I did makes no difference, as the latterÅ› write() method is
inherited from the former. Knowing that OutputStream is an abstract
class had rather instictively turned me to another, more "concrete"
stream class.

Also, I use application/octet and uploading works, but, as I said in
my original post, the file type is wrong. This does not happen if I
manually set the specific content type for a file (e.g., audio/mpeg
for MP3), so it all boils down to identifying the file type (at least
for the particular server application I send to).

One would expect that calling the standard Java
connection.getFileNameMap().getContentTypeFor(filename)) would return
the proper type, but it returns null, at least for teh Linux OS I am
running.

I didn't check about the raw vs. form distinction but apparently the
server is fine with raw, since it works.

That still leaves me looking for a "standard Java" way to identify the
content type of a file. :)
 
A

Arne Vajhøj

I do specify setRequestMethod("POST").

You are right about OutputStream, using DataOutputStream only for
writing as I did makes no difference, as the latterÅ› write() method is
inherited from the former. Knowing that OutputStream is an abstract
class had rather instictively turned me to another, more "concrete"
stream class.

Also, I use application/octet and uploading works, but, as I said in
my original post, the file type is wrong. This does not happen if I
manually set the specific content type for a file (e.g., audio/mpeg
for MP3), so it all boils down to identifying the file type (at least
for the particular server application I send to).

One would expect that calling the standard Java
connection.getFileNameMap().getContentTypeFor(filename)) would return
the proper type, but it returns null, at least for teh Linux OS I am
running.

I didn't check about the raw vs. form distinction but apparently the
server is fine with raw, since it works.

That still leaves me looking for a "standard Java" way to identify the
content type of a file. :)

Now I don't understand what the problem is.

You upload file abc.xyz to the server as application/octet-stream.

The receiving script get the file and stores the file with
the correct name.

What do you need?

Arne
 
D

Dimitris

Now I don't understand what the problem is.

You upload file abc.xyz to the server as application/octet-stream.

The receiving script get the file and stores the file with
the correct name.

What do you need?

Arne

Hi...

As I already explained, I need a solution to a two-fold problem, a
theoretical and a practical one.

(1) Theoretical. Given a file (name and/or its contents), which is the
"standard" Java way for defining the Content-Type to use in HTTP? This
is such a trivial case, that there should be a quick and easy way of
doing it. For example, as I already said, given a URLConnection
variable, apparently one should be able to get the Content-Type by
just calling connection.getFileNameMap().getContentTypeFor(filename)).
In my case (Java 6 over CentOS 5.5), I get a null value, which is
really weird, given that the filename extension is .mp3! If we were to
just set "application/octet-stream" everywhere, then what is the need
for all the other MIME types? Clearly, there is a need, so
"application/octet-stream" is not the one-size-fits-all solution.

(2) Practical. The server application I send, has a web-based client.
If I upload an mp3 file using that client, I can see the file listed
with a nice speakerphone icon next to it, a clear sign that the server
understands what it got. If I send the same file from my application,
using an "audio/mpeg" Content-Type which I manually set, the same nice
speakerphone appears in the web client. However, if I don't have an
automated way to determine the proper Content-Type and thus use
"application/octet-stream" instead, the file is copied to the server
and I can download and play it just fine, but instead of the
speakerphone I get a question mark icon in the web client. Obviously,
the server is not fully happy with "application/octet-stream".

Looking around I 've found numerous proprietary ways of solving the
above (theoretical) issue, but I would rather use a pure Java one.
That's all! :)
 
A

Arne Vajhøj

As I already explained, I need a solution to a two-fold problem, a
theoretical and a practical one.

(1) Theoretical. Given a file (name and/or its contents), which is the
"standard" Java way for defining the Content-Type to use in HTTP? This
is such a trivial case, that there should be a quick and easy way of
doing it. For example, as I already said, given a URLConnection
variable, apparently one should be able to get the Content-Type by
just calling connection.getFileNameMap().getContentTypeFor(filename)).
In my case (Java 6 over CentOS 5.5), I get a null value, which is
really weird, given that the filename extension is .mp3! If we were to
just set "application/octet-stream" everywhere, then what is the need
for all the other MIME types? Clearly, there is a need, so
"application/octet-stream" is not the one-size-fits-all solution.

There are no 100% safe way to associate file extensions with MIME types.

It is a guessing game.

The documentation explains where Java gets its guesses from:

<quote>
Loads filename map (a mimetable) from a data file. It will first
try to load the user-specific table, defined by
"content.types.user.table" property. If that fails, it tries to load the
default built-in table at lib/content-types.properties under java home.
(2) Practical. The server application I send, has a web-based client.
If I upload an mp3 file using that client, I can see the file listed
with a nice speakerphone icon next to it, a clear sign that the server
understands what it got. If I send the same file from my application,
using an "audio/mpeg" Content-Type which I manually set, the same nice
speakerphone appears in the web client. However, if I don't have an
automated way to determine the proper Content-Type and thus use
"application/octet-stream" instead, the file is copied to the server
and I can download and play it just fine, but instead of the
speakerphone I get a question mark icon in the web client. Obviously,
the server is not fully happy with "application/octet-stream".

If the server is a normal web server serving static content
then it does nor matter.

Your upload program and the receiving script transfers filename
and the bytes of the file to the servers file system byte by byte.

Then the web server uses its own map over file extensions to
display it.

But that is browser-web server-file system. The MIME type you
specify has nothing to do with it.

If the server is running an app that has a database with filenames,
MIME types etc. then it does matter what you send.

In that case you should look in the documentation for the
server to understand what you need to send.

Arne
 
S

Steven Simpson

More specifically, I can read a file into a byte array (fileBytes) and
open an HttpConnection to a destination URL (url), but setting the
Content-Type property does not work. The code I use is:

HttpURLConnection connection = url.openConnection();
connection.setRequestProperty("Content-Length",
String.valueOf(fileBytes.length));
connection.setRequestProperty("Content-Type", "application/octet-
stream");

You've set the content type of the request.
If, immediately after the above, I do a

connection.getContentType()

getContentType() gets the content type of the response, not the
request. Do you expect it to return application/octet-stream?
I get a null value (or an Exception saying that the connection is
already connected)!

A null would likely indicate that the response has no content. Not sure
how you get an exception from it - are you sure it's not coming from
setRequestProperty, indicating that the request has already been
transmitted, so the call is too late?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,701
Latest member
XavierQ83

Latest Threads

Top