Android 从改装后的服务器接收PDF响应

Android 从改装后的服务器接收PDF响应,android,http,pdf,retrofit,Android,Http,Pdf,Retrofit,我有一个生成PDF文档的视图。它在浏览器(桌面)上运行良好,但我的最终目标是通过android应用程序交付它 现在我正在使用改型库来处理我的请求/响应(仅json) 我的问题是,我需要通过回调传递数据类型,以处理/接收PDF数据,然后将其保存到磁盘上?对于所有想通过人工方式实现这一点的人,这里是我的工作流程: 1-生成PDF文件后,获取字节并将其转换为base64字符串 我可以通过python使用lib和Django作为后端轻松做到这一点: import base64 def my_view(

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

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


我的问题是,我需要通过
回调传递数据类型,以处理/接收PDF数据,然后将其保存到磁盘上?

对于所有想通过人工方式实现这一点的人,这里是我的工作流程:

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

我可以通过python使用lib和Django作为后端轻松做到这一点:

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')
        }
    )
请记住,此示例可以使用其他后端/lib完成

2-在您的Android项目上,在您想要接收PDF响应/回调的模型上设置一个字符串字段。因此,我们的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);
pdfCallback=new Callback(){
@覆盖公共无效成功(PDF,响应){
if(response.getStatus()==200){
字符串pathToPDF=pdf.save()//保存pdf
}
}
@覆盖公共无效失败(改型错误){
(...)
}
}
MyAPI.callbacks.getPDF((…),pdfCallback);

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