그래서 웹 서비스 프로젝트를 진행하고 있습니다. 다음 내 REST의 웹 서비스로 전송,Java에서 Base64로 PDF 인코딩하기, PL/SQL에서 디코딩 : 작동하지 않습니다.
- PL/SQL 측이 PDF 파일이 파일 다음 Base64로 인코딩 업로드 :
기본적으로, 아래로 비등.
- Java webservice가 파일을 수신합니다. 나는이 파일을 다른 것을하기 전에 (테스트 용으로) 저장한다 : 예상대로 파일이 손상되었다 (Base64 문자열, 이것은 정상이다).
- Java webservice 파일을 Base64로 해독 한 다음 파일과 관련된 작업을 수행합니다. 이 디코딩 후에 파일을 다시 한 번 저장하면 예상대로 작동하고 PDF를 열어 읽을 수 있습니다.
- 이제 PL/SQL은 파일을 다시 다운로드하도록 요청합니다. 파일을 다시 인코딩하여 요청자에게 다시 보냅니다. 인코딩 후 파일을 저장하고 예상대로 (다시 Base64로 인코딩 됨) : 작동하지 않습니다 (손상됨).
- 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;
양쪽 모두 "동일한"Base64 표현을 사용 하시겠습니까 (특히 패딩)? – fge
PL/SQL의 디코딩 부분에서 문제가 발생한 것으로 보입니다. 그것들을 공유 할 수 있습니까? (또한 바이너리 데이터 전송 및 BLOB를 사용하지 않는 특별한 이유가 있습니까?) –
@fge - 우리는이를 확인하려고했습니다. Java에서 commons는 청크 크기로 76을 사용하는 반면, PL/SQL에서는 48을 사용하고 있음을 압니다. 제가 알기로는 차이를 만들어서는 안된다는 것입니다. – testuser