Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Java将PDF编码为Base64,用PL/SQL解码:不';行不通_Java_Sql_Plsql_Base64_Oracle Apex - Fatal编程技术网

用Java将PDF编码为Base64,用PL/SQL解码:不';行不通

用Java将PDF编码为Base64,用PL/SQL解码:不';行不通,java,sql,plsql,base64,oracle-apex,Java,Sql,Plsql,Base64,Oracle Apex,所以,我正在从事一个web服务项目 基本上可以归结为: PL/SQL端上传一个PDF文件,然后Base64对该文件进行编码,然后将其发送到我的REST Web服务 JavaWebService接收该文件。我在做任何其他事情之前保存了这个文件(只是为了测试):正如预期的那样,该文件已损坏(它是Base64字符串,这是正常的) Java webservice Base64解码该文件,然后继续对该文件执行任何需要执行的操作。在解码之后,我再次保存了文件,它再次按照预期工作,我能够打开并阅读PDF PL

所以,我正在从事一个web服务项目

基本上可以归结为:

  • PL/SQL端上传一个PDF文件,然后Base64对该文件进行编码,然后将其发送到我的REST Web服务
  • JavaWebService接收该文件。我在做任何其他事情之前保存了这个文件(只是为了测试):正如预期的那样,该文件已损坏(它是Base64字符串,这是正常的)
  • Java webservice Base64解码该文件,然后继续对该文件执行任何需要执行的操作。在解码之后,我再次保存了文件,它再次按照预期工作,我能够打开并阅读PDF
  • PL/SQL现在请求重新下载该文件。我对文件重新编码并将其发送回请求者。我在编码后保存文件,正如预期的那样(它再次被Base64编码):它不工作(损坏)
  • PL/SQL接收文件,Base64解码文件并尝试打开它。。。Bam,已损坏,无法读取文件
  • 通信之间可能有问题:它是用Java编码的Base64,用PL/SQL解码的Base64。您可能会怀疑这并没有什么区别,因为它使用的是标准(我想Base64是标准的,对吧?)

    我们尝试了两种选择:在我用Java重新编码PDF之后,我再次尝试重新解码并保存它;这个文件是正确的,我能够阅读PDF。因此,我们假设Java中的编码是正确的。我们还尝试了PL/SQL中的这个——上传一个BLOB,编码到Base64,解码它,下载和打开。这也行得通。因此,我们假设PL/SQL中的编码和解码部分也可以工作

    奇怪的是,我可以用PL/SQL对文件进行Base64编码,然后用Java对其进行解码,然后保存并读取它。只有当我用Java对文件重新编码并尝试用PL/SQL对其进行解码时,才会出错。所以在我看来,PL/SQL-Java中使用的标准之间不可能真的存在问题,因为第一步也会失败

    我们正在使用Java中的commons库(
    org.apache.commons.codec.binary.Base64
    )。在PL/SQL中,我们尝试使用UTL包、自定义方法、Java存储过程以及Apex_webservice(
    Apex_web_service.blob2clobbase64(p_blob)
    Apex_web_service.clobbase642blob(p_clob)
    )。它们都给出相同的结果

    我们的想法正在慢慢枯竭。有没有人有其他更好的主意

    谢谢

    ---编辑---

    以下是文件在PL/SQL中的解码方式:

    FUNCTION encode_base64 (p_blob_in IN BLOB) 
        RETURN CLOB IS
            v_clob             CLOB;
            v_result           CLOB;
            v_offset           INTEGER;
            v_chunk_size       BINARY_INTEGER := (48 / 4) * 3;
            v_buffer_varchar   VARCHAR2 (48);
            v_buffer_raw       RAW (48);
        BEGIN
            IF p_blob_in IS NULL THEN
                RETURN NULL;
            END IF;
            DBMS_LOB.createtemporary (v_clob, TRUE);
            v_offset := 1;
            FOR i IN 1 .. CEIL (DBMS_LOB.getlength (p_blob_in) / v_chunk_size) LOOP
                DBMS_LOB.read (p_blob_in, v_chunk_size, v_offset, v_buffer_raw);
                v_buffer_raw := UTL_ENCODE.base64_encode (v_buffer_raw);
                v_buffer_varchar := UTL_RAW.cast_to_varchar2 (v_buffer_raw);
                DBMS_LOB.writeappend (v_clob, LENGTH (v_buffer_varchar), v_buffer_varchar);
                v_offset := v_offset + v_chunk_size;
            END LOOP;
            v_result := v_clob;
            DBMS_LOB.freetemporary (v_clob);
            RETURN v_result;
    END encode_base64;
    
    以下是文件在Java中的编码方式:

    byte[] content = /*Here is my content in bytes. Before encoding, when I save, this is correct*/
    Base64.encodeBase64String(content);
    
    ---编辑2---

    我不小心在上面的PL/SQL中添加了解码部分。这里是PL/SQL中的编码部分

    function decode_base64(p_clob_in in clob) return blob is
        v_blob blob;
        v_result blob;
        v_offset integer;
        v_buffer_size binary_integer := 48;
        v_buffer_varchar varchar2(48);
        v_buffer_raw raw(48);
        begin
            if p_clob_in is null then
                return null;
            end if;
            dbms_lob.createtemporary(v_blob, true);
            v_offset := 1;
            for i in 1 .. ceil(dbms_lob.getlength(p_clob_in) / v_buffer_size) loop
                dbms_lob.read(p_clob_in, v_buffer_size, v_offset, v_buffer_varchar);
                v_buffer_raw := utl_raw.cast_to_raw(v_buffer_varchar);
                v_buffer_raw := utl_encode.base64_decode(v_buffer_raw);
                dbms_lob.writeappend(v_blob, utl_raw.length(v_buffer_raw), v_buffer_raw);
                v_offset := v_offset + v_buffer_size;
            end loop;
            v_result := v_blob;
            dbms_lob.freetemporary(v_blob);
            return v_result;
    end decode_base64;
    

    这类问题大多来自于小事情

    发生了什么事?我将Base64字符串发送回XML中。在PL/SQL中,我们先将该字符串提取到clob中,然后再将其解码回blob

    我们打印并检查了字符串。。。这是正确的

    当我们试图检查从PL/SQL发送的clob与从PL/SQL返回的clob之间的差异时,我们发现了一些char(10)和char(13)换行符。肉眼看不见,但会使clob(和解码的blob)损坏。一个翻译功能把这些都拿出来了,现在它就像一个符咒


    谢谢你的帮助

    您确定在两端都使用“相同”的Base64表示(特别是填充)?问题似乎来自PL/SQL中的解码部分。你能分享一下吗?(您不使用二进制数据传输和BLOB还有什么特别的原因吗?@fge-我们已经试着检查过了;我知道在Java中commons使用76作为块大小,而在PL/SQL中我们使用48。据我所知,这不会有什么不同,对吗?@VincentMalgrat,我添加了我在Java和PL/SQL中使用的代码。至于二进制数据传输,公司有一条规定,我们应该对其进行编码以保证其“安全”。当在传输过程中不编码解码,只发送普通字节时,它是有效的,但“这还不够好”。大多数这类问题来自于小事情。。。发生了什么事?我将Base64字符串发送回XML中。在PL/SQL中,我们先将该字符串提取到clob中,然后再将其解码回blob。我们打印并检查了字符串。。。这是正确的。当我们试图检查从PL/SQL发送的clob与从PL/SQL返回的clob之间的差异时,我们发现了一些char(10)和char(13)换行符。肉眼看不见,但会使clob(和解码的blob)损坏。一个translate函数将这些内容提取出来,现在它可以作为一个符咒使用。因此,您可以在XML中获取base64字符串,然后将其提取到CLOB。你能直接提取成一团吗?我怀疑CLOB可能“有帮助地”将它认为是行尾字符的字符从Unix转换为DOS样式,反之亦然。只是一个想法。共享和享受。问题是我们需要在从XML中提取CLOB之后立即使用它,以便能够对其进行Base64解码(返回到BLOB)。decode函数假定IN参数为CLOB,OUT参数为BLOB。因此,在我看来,这将是一个变通办法(我承认,现在的翻译也是一个变通办法)提供了一个例子吗?