ダウンロードCGI、Javaサンプル - データのダウンロード方法
作成:2005-10-25、更新:2009-11-11
au独自のデータのダウンロード仕様とサンプル。
データのダウンロード方法
- auの古い機種では、着メロや待ち受け画像のダウンロードの方法が少し特殊です。
- CRCの付加
まず、データファイルにEZweb独自のCRC値を付加します。
一般的なCRC16やCRC32と違います。
詳しくは、公式サイトを参照。
この処理によって、データファイルの一番最後にCRC計算値が2バイト付加されます。
したがって、ファイルサイズが2バイト増えます。
CRC値がついてないデータは、ダウンロードできません。
- ダウンロードCGIを用意する
EZweb独自のダウンロード方式を使ったプログラムを用意し、データをダウンロードします。
このダウンロード方式は、データを少しずつダウンロードさせるようになってます。
端末が1回に受信を要求するデータのサイズ(バイト数)は、端末により異なります。
- 上記の方法は、Aタグを使ってダウンロードCGIにリンクをはり、データのダウンロードを行います。
だたし、端末によってはこの方式でなくても単にAタグでデータファイルに直接リンクを張るだけでダウンロードできるものもあります。
これらの仕様については、公式サイトにも書いてあります。
- しかし、着うた対応機種(WAP2.0)以降は、着メロなどのデータは基本的にOBJECTタグを使ってダウンロードできるので、この仕様は今はあまり使用されないかもしれません。
ただし、画像や一部のデータはOBJECTタグを使ってダウンロードできません。
- その他の情報は、携帯サイト作成を参照。
データのダウンロード用のタグ
- ダウンロード用プログラムに対してのリンクの張り方です。
-
HDMLの場合(全データ共通)
<A TASK="gosub"
LABEL="Get"
METHOD="post"
DEST="device:data/dnld?url=http://www.sample.com/download.cgi&name=$fname&size=$fsize&disposition=$devtype">
ダウンロード</A>
name:データファイルのパス(必須)
size:データファイルのファイルサイズ(必須)
disposition:データファイルのデータタイプ(必須)。下記参照。
title:データのタイトル(任意)。何も書かなければ、データに埋め込まれた題名。携帯電話により動作が異なります。
-
HTMLの場合(全データ共通)
<a href="device:data/dnld?url=http://www.inunote.com/download.cgi&name=$fname&size=$fsize&disposition=$devtype">
ダウンロード</a>
上の書き方の場合、データのダウンロード後に強制的にトップページなどに戻ってしまう場合があります。
<wml:anchor>
<wml:spawn href="device:data/dnld?url=http://www.inunote.com/download.cgi&name=$fname&size=$fsize&disposition=$devtype"/>
ダウンロード</wml:anchor>
と書くと、ダウンロード完了後、ダウンロード元のページに戻ります。
- disposition
dispositionについては、MIMEタイプ、dispositionを参照。
データダウンロードのサンプルソース
- サンプルソースの出力は、HDML。
HTMLに書き換えても動作します。
- データをダウンロード後、ソース中に書いたページが表示されるものと、携帯独自の画面が表示されるものがあり、
携帯電話により異なります。
- Perlの場合
#!/usr/bin/perl
$str = $ENV{'QUERY_STRING'};
@pairs = split(/&/,$str);
foreach $pair (@pairs){
($name,$value) = split(/=/,$pair);
$value =~ tr/+/ /;
$value =~ s/%(..)/pack("C",hex($1))/eg;
$cgi{$name} = $value;
}
$namex = $cgi{'name'};
$offsetx = $cgi{'offset'};
$countx = $cgi{'count'};
&fileDownload;
sub fileDownload{
if($offsetx >= 0 && $countx > 0){
open(FD, '<'."$namex");
binmode FD;
seek(FD, $offsetx, 0);
read(FD, $buf, $countx);
close FD;
# HEADER
print "Content-type: application/x-up-download" ,"\n";
print "Content-length: $countx", "\n";
print "\n";
print $buf;
}
#elsif($offsetx == 0 && $countx == 0){
#If &receipt was appended to the download request,
#the device will request a buffer of size count=0
#to indicate completion; so, return an "empty"
#download header
#
#print "Content-type: application/x-up-download", "\n";
#print "Content-length: 0", "\n";
#print "\n";
#}
elsif($offsetx == -1 && $countx == -1){
print "Content-type: text/x-hdml;charset=Shift_JIS\n\n";
print "<HDML VERSION=3.0 TTL=0>";
print "<DISPLAY>";
# print "<ACTION TYPE=ACCEPT TASK=GO DEST=sound.hdml LABEL=戻る>";
print "<ACTION TYPE=accept TASK=return LABEL=戻る>";
print "<IMG ICON=scroll>再生<BR>";
print "ダウンロード成功";
print "<BR>";
# print "<A TYPE=ACCEPT TASK=GOSUB DEST=sound.hdml LABEL=戻る>戻る</A>";
print "</DISPLAY>";
print "</HDML>";
}
elsif($offsetx == -1 && $countx == -2){
print "Content-type: text/x-hdml;charset=Shift_JIS\n\n";
print "<HDML VERSION=3.0 TTL=0>";
print "<DISPLAY>";
print "<ACTION TYPE=accept TASK=return LABEL=戻る>";
print "ダウンロード失敗";
print "<BR>";
# print "<A TYPE=ACCEPT TASK=GOSUB DEST=sound.hdml LABEL=戻る>戻る</A>";
print "</DISPLAY>";
print "</HDML>";
}
else{
print "Content-type: text/x-hdml;charset=Shift_JIS\n\n";
print "<HDML VERSION=3.0 TTL=0>";
print "<DISPLAY>";
print "<ACTION TYPE=accept TASK=return LABEL=戻る>";
print "ファイルが存在しません";
print "<BR>";
# print "<A TYPE=ACCEPT TASK=GOSUB DEST=sound.hdml LABEL=戻る>戻る</A>";
print "</DISPLAY>";
print "</HDML>";
}
}
- Javaの場合(JSP、サーブレットなど)
String nameSt = null;
String offsetSt = null;
String countSt = null;
int offsetx = 0;
int countx = 0;
nameSt = request.getParameter("name");
offsetSt = request.getParameter("offset");
countSt = request.getParameter("count");
offsetx = Integer.parseInt(offsetSt);
countx = Integer.parseInt(countSt);
if(offsetx >= 0 && countx > 0){
try{
//ファイルがあるパスを指定する。
//ファイル名だけを受け取っても、ディレクトリ+ファイル名を受け取ってもOK。
/*
String strBuff = "";
FileReader fr = new FileReader("/htdocs/data/"+nameSt);
char buf[] = new char[countx];
fr.skip(offsetx);
fr.read(buf, 0, buf.length);
strBuff = new String(buf);
fr.close();
*/
String strBuff = "";
String serverDir = "/htdocs/data/"+nameSt;
InputStream in = new FileInputStream(serverDir);
byte[] buf = new byte[countx];
in.skip(offsetx);
in.read(buf);
strBuff = new String(buf, "8859_1");
in.close();
response.setContentType("application/x-up-download");
response.setContentLength(countx);
out.print(strBuff);
}catch(Exception e){
System.out.println(e);
}
}else if(offsetx == 0 && countx == 0){
response.setContentType("application/x-up-download");
response.setContentLength(0);
//out.print("\n");
}else if(offsetx == -1 && countx == -1){
response.setContentType("text/x-hdml;charset=Shift_JIS");
out.println("<HDML VERSION=3.0 TTL=0>");
out.println("<DISPLAY>");
out.println("<ACTION TYPE=accept TASK=return LABEL=戻る>");
out.println("<IMG ICON=scroll>再生<BR>");
out.println("ダウンロード完了");
out.println("<BR>");
out.println("</DISPLAY>");
out.println("</HDML>");
}else if(offsetx == -1 && countx == -2){
response.setContentType("text/x-hdml;charset=Shift_JIS");
out.println("<HDML VERSION=3.0 TTL=0>");
out.println("<DISPLAY>");
out.println("<ACTION TYPE=accept TASK=return LABEL=戻る>");
out.println("ダウンロード失敗");
out.println("<BR>");
out.println("</DISPLAY>");
out.println("</HDML>");
}else{
response.setContentType("text/x-hdml;charset=Shift_JIS");
out.println("<HDML VERSION=3.0 TTL=0>");
out.println("<DISPLAY>");
out.println("<ACTION TYPE=accept TASK=return LABEL=戻る>");
out.println("ファイルが存在しません");
out.println("<BR>");
out.println("</DISPLAY>");
out.println("</HDML>");
}