Reputation: 696
Let me provide some context first. I am working on a system that integrates with Microsoft SharePoint 2010, well not really SharePoint as a system but the virtual representation of it's filesystem, document libraries, etc... Users upload files to SharePoint, and my system monitors these files and indexes them into a search engine (including file content). User can interact with this system by means of REST interfaces.
I have created a REST interface to fetch a file for the user corresponding a certain entry in my search engine. This uses the absolute network path as its identifier. An example would be //corporateserver//library1/filex.docx
. Due to the same origin policy however I can not load this file client side. Therefore I am trying to transmit it via the server.
I had some success using JAX-RS to transmit data, however, I am getting stuck at the following:
The file the user wishes to download can be of mutliple content types, most of them will be microsoft office formats. I had a look through the list of registered MIME types and came across application/msword
or application/vnd.ms-powerpoint
My question: is there a content type that would include Microsoft Office files? If not, how could one proceed to match the correct content types with a file that is being requested. What would happen if one would server a word file with content type text/plain
?
Any help on the subject would be greatly appreciated.
EDIT
The code I use to transmit data:
package com.fujitsu.consensus.rest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import org.apache.commons.io.IOUtils;
import org.codehaus.jettison.json.JSONException;
@Path("/fetcher")
public class FetcherService {
@GET
@Path("/fetch")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response fetchFile(@QueryParam("path") String path)
throws JSONException, IOException {
final File file = new File(path);
System.out.println(path);
StreamingOutput stream = new StreamingOutput() {
@Override
public void write(OutputStream output) throws IOException {
try {
output.write(IOUtils.toByteArray(new FileInputStream(file)));
} catch (Exception e) {
e.printStackTrace();
}
}
};
return Response.ok(stream, MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "inline; filename=\"" + file.getName() + "\"")
.build();
}
}
JavaScript code:
$.ajax({
url: "../rest/fetcher/fetch",
type: "GET", //send it through get method
data:{path:obj.id},
success: function(response) {
console.log(response);},
error: function(xhr) {//Do Something to handle error}
});
The response I get on client side:
EDIT 2
I've added a HTTP trace as proof that the headers and data are in fact being transmitted, the download dialogue however is not shown.
The Content-Disposition
header does not appear to be working with either inline or attachment.
Upvotes: 2
Views: 14387
Reputation: 696
Fixed it, used the content-type: application/octet-stream. I also added the header mentioned above:
return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"")
.build();
my error was thinking that after an ajax call the file would download in the same window. changed my client side code to do the request in another window using :
window.open(resturl);
the reaction was that the browser would open a new window, download the file into the download tray and return to the webpage in which you clicked download whilst closing the download tab. (in about 0.2 seconds).
Upvotes: 1
Reputation: 130877
You could use application/octet-stream
as content type and do the following to download files:
@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response downloadFile(String fileName) {
File file = ... // Find your file
return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"")
.build();
}
Since you are using JavaScript to download files, have a look here and here.
Upvotes: 15