JAX-RS文件下载,多种内容类型

时间:2015-11-05 10:48:57

标签: java jax-rs mime-types same-origin-policy

首先让我提供一些背景信息。我正在开发一个与Microsoft SharePoint 2010集成的系统,不是真正的SharePoint作为系统,而是它的文件系统,文档库等的虚拟表示...用户将文件上载到SharePoint,我的系统监视这些文件并对它们编制索引进入搜索引擎(包括文件内容)。用户可以通过REST接口与该系统进行交互。

我创建了一个REST接口来为用户提取相应于我搜索引擎中某个条目的文件。这使用绝对网络路径作为其标识符。一个例子是//corporateserver//library1/filex.docx。由于原始策略相同,但我无法加载此文件客户端。因此,我试图通过服务器传输它。

我使用JAX-RS传输数据取得了一些成功,但是,我遇到了以下问题:

用户希望下载的文件可以是多种内容类型,其中大部分都是微软办公室格式。我查看了已注册的MIME类型列表,并遇到了application/mswordapplication/vnd.ms-powerpoint

我的问题:是否有包含Microsoft Office文件的内容类型?如果没有,那么如何继续将正确的内容类型与正在请求的文件进行匹配。如果要为内容类型为text/plain的word文件提供服务,会发生什么?

对此主题的任何帮助将不胜感激。

修改

我用来传输数据的代码:

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代码:

 $.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}
 });

我在客户端得到的回复:

response on client side

编辑2

我添加了一条HTTP跟踪作为标题和数据实际上正在传输的证据,但是未显示下载对话框。

Content-Disposition标题似乎不适用于内联或附件。

HTTP trace result

2 个答案:

答案 0 :(得分:8)

您可以使用application/octet-stream作为内容类型,并执行以下操作来下载文件:

@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();
}

由于您使用JavaScript下载文件,请查看herehere

答案 1 :(得分:1)

修正了它,使用了content-type:application / octet-stream。我还添加了上面提到的标题:

 return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM)
        .header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"")
        .build();

我的错误认为在ajax调用之后文件将在同一窗口中下载。更改了我的客户端代码,使用以下命令在另一个窗口中执行请求:

window.open(resturl);

反应是浏览器将打开一个新窗口,将文件下载到下载托盘并返回到您关闭下载选项卡时单击下载的网页。 (约0.2秒)。