How to change the file name during the download process - java

I have a file named "MyFile.doc" on my server and a jsp in the same instance. There is a redirection in the jsp like : response.sendRedirect("MyFile.doc");. When a user comes to my jsp file, I want to give the file as "MyFile_XYZT.doc". In short, it should be downloaded with an ID created dynamically.
I've searched and found something about Content-Disposition method.
Any ideas ?

I've searched and found something about Content-Disposition method.
Right, that's how you tell the browser what you'd like it to do with the response, including optionally giving a suggested filename for a download.
I don't think there's any one-liner here, though. You either need to configure your server to return MyFile.doc with the relevant Content-Disposition header or, if you want to control the name with code in your JSP, you'll have to send the response yourself using setHeader to set the Content-Disposition header. E.g.:
response.setHeader("Content-Disposition", "attachment; filename=\"MyFile_XYZT.doc\"");
...and then opening the file, reading its contents, and sending those in the response. It's not a lot of code (probably four or five lines), but it's not a one-liner.

Related

Servlet: Image upload with content type as image/jpeg

I am using sapui5 control UploadCollection to upload set of images and servlet to process the post request.
Problem 1: I have slightest idea how to parse the content to get images in doPost.
Problem 2: For the UploadCollection, it's not advisable to change the content type by modifying the header parameters. So, i'd need to get those images in servlet without multipart as content type.
I have seen dozens of examples, all having multipart as content type. I need a solution where content type from browser comes as image/*. Hints or code snippets would do.
I am not sure which examples you have seen. Normally the UploadCollection never uses multipart. You can check the code of the UploadCollection here and see that the FileUploaders are always built with useMultipart: false.
Also, if you check the examples from the Explored app, you will see that the content type is image/png or whatever type of file you select (on Chrome):
I am not really sure what is the behaviour on IE 8 / 9, where things are a little different (uploads through AJAX is not supported).
The multipart content type is controlled by the useMultipart property of the FileUploader. If you need to play around with this value, you will need to replace the default upload button from the UploadCollection. To do this, simply make the default upload button invisible (using the uploadButtonInvisible property) and add your own FileUploader in the toolbar of the UploadCollection.
Related to the Servlet question: it depends what you want to do with the Image. You can get the InputStream from the request
and then use it for whatever you need it. The input stream will contain the image itself (if the content is not multi-part that is).

Java Servlet: how to escape the pound character when setting response header?

My Java servlet includes the following line:
response.addHeader("Content-Disposition", "filename=myFile.pdf");
I need to include a named destination defined in the PDF file as part of the file name. Ideally, I could use the following:
response.addHeader("Content-Disposition", "filename=myFile.pdf#Chapter3");
but when I run it, the url in the browser shows /path/to/myFile.pdf%23Chapter3 instead of the desired /path/to/myFile.pdf#Chapter3.
How to escape the # in "filename=myFile#Chapter3"? Escaping with \ gives a compile-time error. Escaping with &035; doesn't work either.
RFC 2616 defines that "the Content-Disposition response-header field has been proposed as a means for the origin server to suggest a default filename if the user requests that the content is saved to a file" so I don't think you can do what you intend to through your servlet. Maybe you will have better luck with some script in the pdf : you could imagine parsing its own name to dynamically set it at the right anchor at opening.

getContentType method returning always 'application/force-download'

I have an URL to file which I can download. It looks like this:
http://<server>/recruitment-mantis/plugin.php?page=BugSynchronizer/getfile&fileID=139&filehash=3e7a52a242f90c23539a17f6db094d86
How to get content type of this file? I have to admin that in this case simple:
URL url = new URL(stringUrl);
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
String urlContent = urlConnection.getContentType();
returning me application/force-download content type in every file (no matter is jpg or pdf file).
I want to do this cause I want to set extension of downloaded file (which can be various). How to 'get around' of this application/force-download content type? Thanks in advance for your help.
Check urlConnection.getHeaderField("Content-Disposition") for a filename. Usually that header is used for attachments in multipart content, but it doesn't hurt to check.
If that header is not present, you can save the URL to a temporary file, and use probeContentType to get a meaningful MIME type:
Path tempFile = Files.createTempFile(null, null);
try (InputStream urlStream = urlConnection.getInputStream()) {
Files.copy(urlStream, tempFile, StandardCopyOption.REPLACE_EXISTING);
}
String mimeType = Files.probeContentType(tempFile);
Be aware that probeContentType may return null if it can't determine the type of the file.
How to 'get around' of this application/force-download content type?
I had the same problem with my uploaded content-type. Although you can trust the content-type from the URL, I chose to go looking for a content-type utilities to determine the content from the byte content.
After trying 5 or so implementations I decided to reinvent the wheel and released my SimpleMagic package which makes use of the magic(5) Unix content-type files to implement the same functionality as the Unix file(1) command. It uses either internal config files or can read /etc/magic, /usr/share/file/magic, or other magic(5) files and determine file content from File, InputStream, or byte[].
Location of the github sources, javadocs, and some documentation are available from the home page.
With SimpleMagic, you do something like the following:
ContentInfoUtil util = new ContentInfoUtil();
ContentInfo info = util.findMatch(byteArray);
It works from the contents of the data (File, InputStream, or byte[]), not the file name.
I guess this content type is set from the server your are downloading from. Some server use these kind of content type to force browsers to download the file instead of trying to open it. For example when my server return content type "application/pdf" chrome will try to open it as pdf, but when the server returns "application/force-download" the browser will save it to disk, because he has no clue what to do with this.
So you need to change the server to return the correct content type or better try some other heuristic to get the correct file type, because the server can always lie to you by setting it to jpg but giving you an exe.
I see with Java 7 you can try this method:
http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#probeContentType%28java.nio.file.Path%29

Displaying image from byte array in browser

I have a simple TCP serversocket that will GET a byte array. This GET comes from when entering a website on this server that contains an img src link to a gif image, the requests looks like this:
GET /myHome.htm HTTP/1.1
GET /house.gif HTTP/1.1
Now the byte array is done like this:
byte[] fileByte = Files.readAllBytes(filePath);
To print the website which contains this image I do this:
out.writeBytes(new String(fileByte));
out:
DataOutputStream out= new DataOutputStream(socketClient.getOutputStream());
Now to make the image display I think I have to use something else then
out.writeBytes()
but I do not know for sure. Anybody knows how to make the image display? Right now the image just dont show at all.
First, make sure your GIF file is not corrupted. (Happened to me before, too).
If that is the case, try this code for sending the GIF file:
byte[] fileByte = Files.readAllBytes(filePath);
writer.writeBytes("HTTP/1.1 200 OK\r\n");
writer.writeBytes("Content-Type: image/gif\r\n");
writer.writeBytes("Content-Length: "+fileByte.length+"\r\n");
writer.writeBytes("\r\n");
writer.write(fileByte, 0, fileByte.length);
And then try to navigate to "house.gif" directly instead of "myHome.htm". Let me know in the comments what this does.
Previous answer attempts:
I think I may have misunderstood your question. Let me try with a different answer:
You are not sure how to figure out on the server when to return the HTML file myHome.htm and when to return house.gif?
I think for this you need to simply parse out the requested URL. Just check whether it contains "house.gif" or not. Then, depending on this, you either return the HTML file as you described above, or you send the .gif file, making sure that you use
writer.write(fileByte, 0, fileByte.length);
to send the binary data and that you set a reply header of
Content-Type: image/gif
In both cases (for the HTML file and the GIF file), though, you should prepend the data you are sending with correct HTTP response headers. Don't take the page-title the wrong way, but this site might help: http://net.tutsplus.com/tutorials/other/http-headers-for-dummies/
And just to make sure: Your server will be receiving TWO independent requests. The first one will ask for the HTML file, the second one will ask for the GIF file. So you send either one or the other. So, there's no "special way" to send the GIF instead of the HTML file. You use the same clientSocket. But it's a different connection.
Previous answer(s):
I think you might be missing the mime-type of your returned data. Try adding the following HTTP header to your reply:
Content-Type: image/gif
Actually... Are you sending a correct HTTP reply at all (including headers, specifically Content-Length)? If not, shoot me a comment and I'll post the code that you need for this.
If, for some reason, you cannot set the content-type header to let the browser know that you are sending it an image, you might be able to load the binary data on the client with an XMLHttpRequest into a JavaScript function rather than specifying it as the source Url of an img tag. Then you can use JavaScript to encode the binary data into a dataURI (http://en.wikipedia.org/wiki/Data_URI_scheme) with the correct mime type and set that as the source of the image.
Actually, I just noticed something in your code:
new String(fileByte)
might interpret the fileBytes as unicode characters rather than binary. Then, when you write this to the writer, it might screw it up as probably not all data in the image are valid unicode. Try replacing the line with this:
writer.write(fileByte, 0, fileByte.length);
Maybe this is all you need to do to fix it???

JSP: Get MIME Type on File Upload

I'm doing a file upload, and I want to get the Mime type from the uploaded file.
I was trying to use the request.getContentType(), but when I call:
String contentType = req.getContentType();
It will return:
multipart/form-data; boundary=---------------------------310662768914663
How can I get the correct value?
Thanks in advance
It sounds like as if you're homegrowing a multipart/form-data parser. I wouldn't recommend to do that. Rather use a decent one like Apache Commons FileUpload. For uploaded files, it offers a FileItem#getContentType() to extract the client-specified content type, if any.
String contentType = item.getContentType();
If it returns null (just because the client didn't specify it), then you can take benefit of ServletContext#getMimeType() based on the file name.
String filename = FilenameUtils.getName(item.getName());
String contentType = getServletContext().getMimeType(filename);
This will be resolved based on <mime-mapping> entries in servletcontainer's default web.xml (in case of for example Tomcat, it's present in /conf/web.xml) and also on the web.xml of your webapp, if any, which can expand/override the servletcontainer's default mappings.
You however need to keep in mind that the value of the multipart content type is fully controlled by the client and also that the client-provided file extension does not necessarily need to represent the actual file content. For instance, the client could just edit the file extension. Be careful when using this information in business logic.
Related:
How to upload files in JSP/Servlet?
How to check whether an uploaded file is an image?
just use:
public String ServletContext.getMimeType(String file)
You could use MimetypesFileTypeMap
String contentType = new MimetypesFileTypeMap().getContentType(fileName)); // gets mime type
However, you would encounter the overhead of editing the mime.types file, if the file type is not already listed. (Sorry, I take that back, as you could add instances to the map programmatically and that would be the first place that it checks)

Categories

Resources