【问题标题】:Receiving a PDF response from server with retrofit通过改造接收来自服务器的 PDF 响应
【发布时间】:2015-06-10 22:18:34
【问题描述】:

我有一个生成 PDF 文档的视图。它在浏览器(桌面)上运行良好,但我的最终目标是通过 android 应用程序提供它。

现在我正在使用改造库来处理我的请求/响应(仅 json)。

我的问题是我需要传递 Callback<> 以处理/接收 PDF 数据然后将其保存到磁盘的数据类型?

【问题讨论】:

  • Retrofit 是为与 Web 服务通信而设计的。如果您的 URL 只是一个文档(例如 PDF),我会使用其他东西来下载它(例如 OkHttp、HttpURLConnection)。
  • CommonsWear 是对的,但是您可以尝试通过编写自定义转换器来调整它,该转换器将返回 TypedByteArray 看到这个,稍加修改就可以实现它:stackoverflow.com/questions/28165438/…
  • @NikolaDespotoski 好的,这几乎就是我想要的。我认为我不需要将其解析为 TypedByteArray,但我会进行测试。另一个问题是如何将其设置为自定义转换器?我知道有一个名为 setConverter 的方法,它接受转换器的实例,但是您链接的代码没有显示空构造函数。那么我该如何设置呢?
  • @vyscond 你用setConverter() 方法在RestAdapter.Builder 中设置它。
  • @NikolaDespotoski 是的,但是从 GsonConvert 扩展使我的自定义转换器类不接收空构造函数。所以需要传递一个(至少)一个 Gson 对象。我像这样传递RestAdapter.Build.setConverter(new MyConverter(new Gson()))... 但是当我发送请求时服务器没有接收到。

标签: android http pdf retrofit


【解决方案1】:

对于所有想以人类方式做到这一点的人来说,这是我的工作流程:

1 - 生成 PDF 文件后抓取字节并将其转换为 base64 字符串。

我可以使用 pyfpdf lib 并使用 Django 作为后端的 python 轻松地做到这一点:

import base64

def my_view(request):
    pdf = MyCustomPDF()
    pdf.add_page()
    pdf.set_margins(12,3,3)
    pdf.render() # PDF is ready to be saved
    b = pdf.output('output.pdf','B') # got the PDF as a byte array
    return JsonResponse(
        {  
            "name" : "my_doc.pdf",
            "content64" : base64.b64encode(b).decode('utf8')
        }
    )

记住这个例子可以用其他后端/库来完成!

2 - 在您的 Android 项目上,在您要用于接收 PDF 响应/回调的模型上设置一个 string 字段。所以我们的 PDF 会像这样到达。

{  
    "name" : "my_doc.pdf",
    "content64" : "aGVsbG8gd29ybGQ="
}

所以在 Java 上我们可以设置自定义 POJO

class PDF{
    private String name;
    private String content64;

    // (...)
}

3 - base64 将是一个简单的字符串!要以字节形式获取真实文件,只需编写这样的例程

class PDF{
    private String name;
    private String content64;

    // (...)

    public byte[] content64AsByteArray(){ // Helps you convert string to byte formats :B
        return Base64.decode(content64,Base64.DEFAULT);
    }

    public String save(String path) {

        try {

            String path = Environment.getExternalStorageDirectory() + "/" + path;

            File f1 = new File(path);

            OutputStream out = null;
            out = new FileOutputStream(path + "/" + this.name);
            out.write(this.content64AsByteArray());
            out.close();


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return this.path; // I like to return it because i can use it to start a "open file" intent
    }
}

4 - 改装后的接收回调将是这样的

pdfCallback = new Callback<PDF>() {

    @Override public void success(PDF pdf, Response response) {

        if (response.getStatus() == 200) {

            String pathToPDF = pdf.save() // save PDF

        }

    }

    @Override public void failure(RetrofitError error) {
        (...)
    }
}

MyAPI.callbacks.getPDF( (...), pdfCallback);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多