【问题标题】:Sending pdf data through rest api inside json通过json里面的rest api发送pdf数据
【发布时间】:2016-10-11 16:58:51
【问题描述】:

我已经创建了一个 Web 服务,它使用 mutlipart/formdata 向客户端发送多个 pdf 作为响应,但碰巧其中一个客户端是 salesforce,它不支持 mutlipart/formdata。

他们想要一个 json 作为响应,例如 - {“文件名”:xyzname, “文件内容”:文件内容 }

我尝试使用 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());
}

-------------------------------

请多多指教。

【问题讨论】:

    标签: java rest pdf base64 salesforce


    【解决方案1】:

    我们也在做同样的事情,基本上将 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
    }
    

    然后从 byte[] 内容中设置如下:

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

    Client Side 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);
            }
         }
    

    【讨论】:

      【解决方案2】:

      是的,所以问题出在客户身上。

      解码时我们应该使用

      byte[] decodedBytes = Base64.decodeBase64(fileJson.getString("fileContent"));
      

      而不是

      byte[] decodedBytes = Base64.decodeBase64(fileJson.get("fileContent").toString());
      

      由于编码的 data.toString() 产生了一些想法

      还将 encodeBase64URLSafeString 替换为 encodeBase64String 嗯,一个非常简单的解决方案:)

      【讨论】:

        【解决方案3】:

        在我使用 PHP 的 REST 应用程序中:

        1. 将 base64 $data = base64_encode($data) 编码的数据发送到 REST。

        2. 在写入文件之前,我解码$data = base64_decode($data)

        3. 因此,当文件下载时,它已经是正确的格式

        【讨论】:

          【解决方案4】:

          我会从使用“安全”更改为仅使用“字符串”。所以改变: encodeBase64URLSafeString(...) 到: encodeBase64String(...)

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

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

          【讨论】:

          • 感谢回复。 1. 我确实尝试了 encodeBase64String,但没有成功。 2.我会在eclipse中构建一些本地代码来测试这个而不是client/api
          • 所以我确实尝试在本地进行编码和解码,它可以工作,所以问题可能是 rest api 传输数据的方式。-------- -----------------文件 inputFile = new File("一些 pdf");字符串 base64EncodedData = Base64.encodeBase64String(loadFileAsBytesArray(partiaFile)); //解码数据文件 decodedFile = new File("some other pdf"); byte[] decodeBytes = Base64.decodeBase64(base64EncodedData); writeByteArraysToFile(decodedFile, decodedBytes);
          • 绝对是那个或客户。如果您可以使用 Postman 调用 Web 服务,请尝试使用 linux coreutils 将生成的字符串解码到文件中,然后尝试使用 PDF 查看器打开。这将告诉您是其余的 REST 编码还是客户端处理它的方式。对不起,我不是更直接的帮助,这是一个有趣的问题。
          猜你喜欢
          • 1970-01-01
          • 2019-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-12
          • 2017-09-05
          • 2019-04-15
          • 2016-07-19
          相关资源
          最近更新 更多