2014-03-13 4 views
0

그래서 웹 서비스 프로젝트를 진행하고 있습니다. 다음 내 REST의 웹 서비스로 전송,Java에서 Base64로 PDF 인코딩하기, PL/SQL에서 디코딩 : 작동하지 않습니다.

  1. PL/SQL 측이 PDF 파일이 파일 다음 Base64로 인코딩 업로드 :

    기본적으로, 아래로 비등.

  2. Java webservice가 파일을 수신합니다. 나는이 파일을 다른 것을하기 전에 (테스트 용으로) 저장한다 : 예상대로 파일이 손상되었다 (Base64 문자열, 이것은 정상이다).
  3. Java webservice 파일을 Base64로 해독 한 다음 파일과 관련된 작업을 수행합니다. 이 디코딩 후에 파일을 다시 한 번 저장하면 예상대로 작동하고 PDF를 열어 읽을 수 있습니다.
  4. 이제 PL/SQL은 파일을 다시 다운로드하도록 요청합니다. 파일을 다시 인코딩하여 요청자에게 다시 보냅니다. 인코딩 후 파일을 저장하고 예상대로 (다시 Base64로 인코딩 됨) : 작동하지 않습니다 (손상됨).
  5. PL/SQL은 파일을 받으면 Base64- 파일을 디코드하고 파일을 열려고합니다. Bam, 손상되어 파일을 읽을 수 없습니다.

아마도 통신 사이에 뭔가 문제가있을 것입니다. Java에서 Base64로 인코딩되었고, PL/SQL에서 Base64로 인코딩되었습니다. 표준을 사용하고 있기 때문에 차이가 없다고 생각할 수 있습니다 (Base64가 표준이라고 생각합니다).

우리는 Java에서 PDF를 다시 인코딩 한 후 다시 한 번 다시 디코딩하여 저장하려고합니다. 이 파일은 정확하며 PDF를 읽을 수 있습니다. 그래서 우리는 자바에서 인코딩이 정확하다고 가정합니다. PL/SQL에서 BLOB를 업로드하고, Base64로 인코딩하고, 다시 디코딩하고, 다운로드하고 열고 엽니 다. 이것은 또한 작동합니다. 그래서 우리는 PL/SQL의 인코딩 및 디코딩 부분도 작동한다고 가정합니다.

이상한 점은 Base64로 파일을 PL/SQL로 인코딩 한 다음 Java로 디코딩 한 다음 저장하고 읽을 수 있다는 것입니다. Java로 파일을 다시 인코딩하고 PL/SQL에서 디코딩하려고하면 잘못됩니다. PL/SQL - Java에서 사용되는 표준 간에는 문제가 될 수없는 것처럼 들립니다. 첫 번째 단계도 실패 할 것이기 때문입니다.

우리는 Java (org.apache.commons.codec.binary.Base64)의 commons 라이브러리를 사용하고 있습니다. PL/SQL에서 Apex_webservice (apex_web_service.blob2clobbase64(p_blob)apex_web_service.clobbase642blob(p_clob))뿐만 아니라 Java 저장 프로 시저뿐만 아니라 사용자 정의 메소드뿐만 아니라 UTL 패키지를 사용해 보았습니다. 그들은 모두 같은 결과를줍니다.

천천히 아이디어가 부족합니다. 또 다른 좋은 생각을 가진 사람이 있습니까?

감사합니다.

--- 편집 ---

이 파일은 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; 

이 파일은 자바에서 인코딩하는 방법입니다

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

--- EDIT 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; 
+0

양쪽 모두 "동일한"Base64 표현을 사용 하시겠습니까 (특히 패딩)? – fge

+0

PL/SQL의 디코딩 부분에서 문제가 발생한 것으로 보입니다. 그것들을 공유 할 수 있습니까? (또한 바이너리 데이터 전송 및 BLOB를 사용하지 않는 특별한 이유가 있습니까?) –

+0

@fge - 우리는이를 확인하려고했습니다. Java에서 commons는 청크 크기로 76을 사용하는 반면, PL/SQL에서는 48을 사용하고 있음을 압니다. 제가 알기로는 차이를 만들어서는 안된다는 것입니다. – testuser

답변

1

은 ...

그래서 무슨 일? Base64-String을 XML 내부로 보냅니다. PL/SQL에서 문자열을 하나의 clob로 추출한 다음 다시 blob로 디코딩합니다.

문자열을 확인하고 인쇄했는지 확인했습니다. 올바른 것입니다.

우리가 PL/SQL에서 PL/SQL에서 우리가 PL/SQL로 돌아 오는 clob과 보내는 차이점을 확인하려고했을 때, 우리는 몇 가지 char (10) & char (13) - 본질적으로 linebreaks를 발견했습니다. 눈에는 보이지 않지만 clob (및 디코딩 된 BLOB)은 손상됩니다. 번역 기능이 그것들을 가져 왔고 지금은 매력으로 작동합니다.

모든 도움에 감사드립니다!

+0

그래서 base64 문자열을 XML 안에 넣은 다음 CLOB에 추출합니다. 추출물을 직접 BLOB에 넣을 수 있습니까? 필자는 CLOB이 유닉스에서 줄 끝 문자로 간주하는 것을 "유용하게"변환하거나 그 반대 일 수 있다고 생각합니다. 그냥 생각. 공유하고 즐기십시오. –

+0

문제는 XML에서 Base-decode (다시 BLOB) 할 수 있도록 CLOB을 XML에서 추출한 직후에 필요하다는 것입니다. 디코드 기능은 IN 매개 변수가 CLOB이고 OUT 매개 변수가 BLOB 인 것으로 가정합니다. 그래서 그것은 저에게 해결 방법이 될 것 같습니다 (나는 번역이 이제는 해결 방법이기도하다). – testuser

+0

예제를 제공합니까? –

관련 문제