使用JSON通过REST API发送PDF数据

9
我制作了一个Web服务,使用mutlipart / formdata向客户端发送多个PDF作为响应,但是事实上,其中一个客户端是Salesforce,它不支持mutlipart / formdata。 他们想要一个JSON响应,就像- {“filename”:xyzname, “fileContent”:fileContent } 我尝试使用apache编解码库将数据编码为Base64,但是客户端上的PDF似乎已损坏,我无法使用acrobat打开它。 请查看下面的代码-
import org.apache.commons.io.FileUtils;
//------Server side ----------------
@POST
@Consumes(MULTIPART_FORM_DATA)  
@Produces(MediaType.APPLICATION_JSON)
@Path("somepath")
public Response someMethod(someparam)   throws Exception
{
....
JSONArray filesJson = new JSONArray();
String base64EncodedData =      Base64.encodeBase64URLSafeString(loadFileAsBytesArray(tempfile));
JSONObject fileJSON = new JSONObject();
fileJSON.put("fileName",somename);
fileJSON.put("fileContent", base64EncodedData);
filesJson.put(fileJSON);
.. so on ppopulate jsonArray...
//sending reponse
responseBuilder =    Response.ok().entity(filesJson.toString()).type(MediaType.APPLICATION_JSON_TYPE)    ;
response = responseBuilder.build();   
}

//------------Client side--------------

Response clientResponse = webTarget.request()
            .post(Entity.entity(entity,MediaType.MULTIPART_FORM_DATA));
String response = clientResponse.readEntity((String.class));
JSONArray fileList = new JSONArray(response);
for(int count= 0 ;count< fileList.length();count++)
{
JSONObject fileJson = fileList.getJSONObject(count);        
byte[] decodedBytes = Base64.decodeBase64(fileJson.get("fileContent").toString());
outputFile = new File("somelocation/" + fileJson.get("fileName").toString()   + ".pdf");                    
FileUtils.writeByteArraysToFile(outputFile,        fileJson.get("fileContent").toString().getBytes());
}

-------------------------------
请给予建议。
4个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
3
是的,问题出在客户端。 解码时应该使用:
byte[] decodedBytes = Base64.decodeBase64(fileJson.getString("fileContent"));
相比于
byte[] decodedBytes = Base64.decodeBase64(fileJson.get("fileContent").toString());

由于编码后的数据.toString()会产生一些其他结果

同时将encodeBase64URLSafeString替换为encodeBase64String,这是一个非常简单的解决方案 :)


2
我们正在做同样的事情,基本上将PDF作为JSON发送到Android/iOS和Web客户端(因此涉及Java和Swift)。 JSON对象:
public class Attachment implements Serializable {
    private String name;
    private String content;
    private Type contentType; // enum: PDF, RTF, CSV, ...

    // Getters and Setters
}

然后从字节数组 content 中以以下方式设置:

public Attachment createAttachment(byte[] content, String name, Type contentType) {
    Attachment attachment = new Attachment();
    attachment.setContentType(contentType);
    attachment.setName(name);
    attachment.setContent(new String(Base64.getMimeEncoder().encode(content), StandardCharsets.UTF_8));
}

在客户端Java中,我们需要先创建自己的文件类型对象,然后再映射到java.io.File:

public OurFile getAsFile(String content, String name, Type contentType) {
    OurFile file = new OurFile();
    file.setContentType(contentType);
    file.setName(name);
    file.setContent(Base64.getMimeDecoder().decode(content.getBytes(StandardCharsets.UTF_8)));
    return file;
  }
最后:
public class OurFile {
    //...
    public File getFile() {
        if (content == null) {
          return null;
        }
        try {
          File tempDir = Files.createTempDir();
          File tmpFile = new File(tempDir, name + contentType.getFileEnding());
          tempDir.deleteOnExit();
          FileUtils.copyInputStreamToFile(new ByteArrayInputStream(content), tmpFile);
          return tmpFile;
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
     }

1
在我的PHP REST应用程序中: 1. 将数据编码为base64格式$data = base64_encode($data)并发送到REST。 2. 在写入文件之前,我解码$data = base64_decode($data)。 3. 因此,当文件下载时,它已经处于正确的格式。

0

我建议从使用“Safe”更改为只使用“string”。所以更改: encodeBase64URLSafeString(...) 为: encodeBase64String(...)

原因是“safe”版本实际上在加密之前更改内容以保留URL - 我完全不确定这对PDF会产生什么影响,但怀疑这是您问题的根源。

如果这对您没有用,我建议在服务器上(或单独的测试应用程序上)直接进行加密/解密并比较结果,同时尝试解决问题。这样,您可以看到您正在执行的操作是否有效,但不必每次都经历整个“启动服务器,启动客户端,连接...”过程,这将加快调试速度。


谢谢回复。1. 我尝试了encodeBase64String,但没有成功。2. 我会在Eclipse中构建一些本地代码来测试,而不是客户端/ API。 - rasty

所以我尝试在本地进行编码和解码,它可以正常工作,因此问题可能是rest api传输数据的方式。

File inputFile = new File("some pdf"); String base64EncodedData = Base64.encodeBase64String(loadFileAsBytesArray(partiaFile)); //decode data File decodedFile = new File("some other pdf"); byte[] decodedBytes = Base64.decodeBase64(base64EncodedData); writeByteArraysToFile(decodedFile, decodedBytes);
- rasty
肯定的 - 那就是客户端。 如果你可以使用Postman调用Web服务,尝试这样做,然后使用Linux coreutils将结果字符串解码到文件中,然后尝试使用PDF查看器打开。这将告诉您它是否是REST编码还是客户端处理方式的问题。很抱歉我不能提供更直接的帮助,这是一个有趣的问题。 - The_GM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,