简体   繁体   中英

JAX-RS file downloads, multiple content types

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.

HTTP跟踪结果

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 .

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM