« PL/SQL de File Upload / Download #4 | トップページ | Mac De Oracle : PL/SQL de Collection #5 »

2007年6月 6日 (水) / Author : Hiroshi Sekiguchi.

PL/SQL de File Upload / Download #5



Kate Bush - The Whole Story - Experiment IV Kate Bush - The Whole Story - Experiment IV


PL/SQL de File Upload / Download の最終回。

さて、前回は、日本語ファイル名のファイルをダウンロードするとFirefoxやMozilla以外のブラウザでは文字化け等が発生するというところまでだった。

また、IE6では、Content-Disposition: attachment; filenameを指定する方法であれば文字化けを回避できるということも確認した。

ただ、Mac De Oracleでは一番大切な Safari。そのSafariでは常に文字化けしていた。残念!〜〜で終わらせないのがMac De Oracle.

調べた結果、文字エンコードをUTF-8で統一すれば回避できるのでは? という考えに至り、即実行!



OTN-J の Code Tipsでも公開されました。(2007/6/16更新)
http://otn.oracle.co.jp/otn_pl/otn_tool/code_detail?n_code_id=2235
http://otn.oracle.co.jp/otn_pl/otn_tool/code_detail?n_code_id=2236


下記手順で mod_plsqlのファイルアップロード/ダウンロード環境を再構築した。

  1. データベースキャラクタセットをAL32UTF8で新たなデータベースを作成する。JA16SJISTILDEからAL32UTF8へデータベースキャラクタセットを変更することはできないため、新たにデータベースを作成することになる。
  2. dads.confのPlsqlNLSLanguageをJAPANESE_JAPAN.JA16SJISTILDEからJAPANESE_JAPAN.AL32UTF8へ変更する。
  3. ストアドプロシージャで生成するHTMLのcharsetをShift_JISからUTF-8へ変更する。
  4. utl_url.escapeプロシージャでURLエンコードする際の文字コードをShift_JISからAL32UTF8へ変更する。

1.データベースの作成

DBCA (Database Configuration Assistant)を利用し、データベースキャラクタセット:AL32UTF8のデータベースをサクッと作成しちゃいます。時間のかかるのはこの部分だけですね。
既に、データベースキャラクタセットがAL32UTF8であればこのステップはスキップしてください。

2.dads.confの変更

PlsqlNLSLanguageをJAPANESE_JAPAN.JA16SJISTILDEからJAPANESE_JAPAN.AL32UTF8へ変更します。
# ============================================================================ 
# mod_plsql DAD Configuration File
# ============================================================================
# 1. Please refer to dads.README for a description of this file
# ============================================================================

# Note: This file should typically be included in your plsql.conf file with
# the "include" directive.

# Hint: You can look at some sample DADs in the dads.README file

# ============================================================================
<Location /plsql_de_fileupload>
SetHandler pls_handler
Order deny,allow
Allow from all
AllowOverride None
PlsqlDatabaseUsername scott
PlsqlDatabasePassword tiger
PlsqlDatabaseConnectString 192.168.1.19:1521:amazon
PlsqlAuthenticationMode Basic
PlsqlDefaultPage scott.fileUploadForm
PlsqlDocumentTablename scott.discusDocTable
PlsqlDocumentPath docs
PlsqlDocumentProcedure scott.fileDownloader
PlsqlNLSLanguage JAPANESE_JAPAN.AL32UTF8
</Location>

3.プロシージャの変更
(1)ファイルを最大5件同時にアップロードするフォームを表示するプロシージャの変更。

charsetをShift_JISからUTF-8へ変更するだけ。
CREATE OR REPLACE PROCEDURE fileUpLoadForm
IS
numOfFiles CONSTANT PLS_INTEGER := 5;
BEGIN
htp.htmlopen;
htp.headopen;
htp.meta('CONTENT-Type',null,'text/html; charset=UTF-8');
htp.title('PL/SQL de File Upload');
htp.headclose;

htp.bodyopen;
htp.centeropen;
htp.print('<div align="center" style="width:500; height:600">');
htp.STRONG(
cattributes=> 'style="font-size:24px; color:#ff0000; '
|| 'text-shadow:1px 2px 3px #7f7f7f"',
ctext=> 'PL/SQL de ファイルアップロード'
);
htp.prn('<br><br>');
htp.formopen(
cenctype=>'multipart/form-data',
curl=>'action',cmethod=>'POST'
);

FOR i IN 1..numOfFiles LOOP
htp.prn(
'<p><span style="text-shadow:1px 2px 3px #7f7f7f">ファイルの選択:</span>'
);
htp.formfile(cname=>'file');
htp.br;
END LOOP;
htp.prn('<br><br><p>');
htp.formsubmit(cattributes=>'align=right',cvalue=>'アップロード');

htp.formclose;
htp.print('</div>');
htp.centerclose;
htp.bodyclose;
htp.htmlclose;
END;
/


(2)<FORM>要素のaction属性に指定するプロシージャの変更

charsetをShift_JISからUTF-8へ変更するだけ。
CREATE OR REPLACE PROCEDURE action
(
file IN owa_util.vc_arr
) IS
vOpe# number(10);
BEGIN
htp.htmlopen;
htp.meta('CONTENT-TYPE',null,'text/html; charset=UTF-8');
htp.headopen;
htp.title('PL/SQL de File Upload (Action)');
htp.headclose;
htp.bodyopen;
htp.header(1,'アップロード・ステータス');
htp.print('以下のアップロードが終了しました。<br><br>');
htp.prn('<span style="color:#ff0000; text-shadow:1px 2px 3px #7f7f7f">');
FOR i IN file.FIRST..file.LAST LOOP
IF FILE(i) IS NOT NULL THEN
htp.print('-&gt; ' || file(i) || '<br>');
END IF;
END LOOP;
htp.print('</span>');

-- 同一操作でアップロードしたファイルへ、同一操作番号を設定する。
SELECT upload_operation#.nextval INTO vOpe# FROM dual;
FOR i IN file.FIRST..file.LAST LOOP
UPDATE DISCUSDOCTABLE SET operation# = vOpe# WHERE name=file(i);
END LOOP;

htp.bodyclose;
htp.htmlclose;
END;
/


(3)ダウンロード可能なファイルリストを表示するプロシージャの変更。

charsetをShift_JISからUTF-8へ変更、utl_url.escapeでURLエンコードする際の文字コードをShift_JISからAL32UTF8へ変更。
CREATE OR REPLACE PROCEDURE fileList
IS
BEGIN
htp.htmlopen;
htp.headopen;
htp.meta('CONTENT-Type',null,'text/html; charset=UTF-8');
htp.title('PL/SQL de File upload - ダウンロード可能なファイル一覧');
htp.headclose;
htp.bodyopen;
htp.print(
'<span style="text-shadow:1px 2px 3px #7f7f7f; font-size: 22px">'
|| 'ダウンロードファイル一覧</span><br><br>'
);
FOR doc IN (SELECT name FROM discusDocTable) LOOP
htp.anchor('docs/' || utl_url.escape(doc.name, false, 'AL32UTF8'), 'docs/' || doc.name);
htp.br;
END LOOP;
htp.bodyclose;
htp.htmlclose;
END;
/

(4)ファイルのダウンロード時にmod_plsqlから呼び出されるプロシージャの変更。

charsetをShift_JISからUTF-8へ変更。
CREATE OR REPLACE PROCEDURE fileDownloader
IS
vFilePath VARCHAR2(256);
BEGIN
vFilePath := SUBSTR(owa_util.get_cgi_env('PATH_INFO'), 2);
wpg_docload.download_file(vFilePath);
EXCEPTION
WHEN OTHERS THEN
htp.htmlopen;
htp.headopen;
htp.meta('Ccntent-Type',null,'text/html; charset=UTF-8');
htp.headclose;
htp.bodyopen;
htp.print('ダウンロードファイル:' || vFilePath);
htp.print('<strong style="color:#ff0000">' || sqlerrm() || '</strong>');
htp.bodyclose;
htp.htmlclose;
END fileDownloader;
/


最後に、各プラットフォーム、各ブラウザでダウンロードしているスクリーンショットを。
MacOSX
Safari:
Macosx_safari

Firefox:
Macosx_firefox

Opera9.2:
Macosx_opera92

Linux(TurboLinux8 , CentOS4.4)
Firefox:
Centos44_firefox

SeaMonkey:
Centos44_seamonkey103

Mozilla1.4.2(TurboLinux8):
Turbolinux_mozilla142

Windows XP Professional
IE6:
Windows_ie6

FIrefox:
Windows_firefox


結果として、データベースからHTMLまでの文字エンコードを UTF-8 に統一することで、Firefox以外のブラウザで発生していた文字化けを回避することができるということになる。   (^▽^)v

追記、Oracle10gでは、(おそらく Oracle11g以降も)、新規に作成するデータベースのキャラクタセットは、Unicodeが推奨されているので、データベース作成時のキャラクタセットは、AL32UTF8にしておいたほうがいいだろうね。

以下、マニュアルより引用


データベース・キャラクタ・セットとしてのUnicodeの選択

すべての新規システム配置にUnicodeを使用することをお薦めします。レガシー・システムも最終的にはUnicodeに移行することをお薦めします。現在システムをUnicodeで配置すると、利便性、互換性および拡張性の面で多くの利点があります。Oracle Databaseの包括的なサポートにより、Unicodeの利点を活かしながら高パフォーマンス・システムを高速かつ容易に配置できます。現時点で多言語データをサポートする必要がない場合、またはUnicodeが必要ない場合でも、長期的には新規システムに最適な選択となる可能性が高く、結局は時間を短縮してコストを節減し、競争上の優位性を得ることになります。Unicodeの詳細は、第6章「Unicodeを使用した多言語データベースのサポート」を参照してください。


ついでに、グローバリゼージョンガイドの6 Unicodeを使用した多言語データベースのサポートあたりも熟読して最終的にどの文字コードやエンコーディングにするか判断するべし。

| |

トラックバック


この記事へのトラックバック一覧です: PL/SQL de File Upload / Download #5:

コメント

コメントを書く