InternetExplorer7(IE7)におけるファイルアップロード時の挙動

2010/04/29 11:53

Input type = file 属性の入力フォームにローカルパスや共有フォルダのパス以外の、相対パスなどの文字列を入力し、submit しても Web サーバーにリクエストが送信されない現象についてのMicrosoft公式回答は以下。

http://support.microsoft.com/kb/890981/ja

結論から言うと、xp sp2移行のOSでは入力項目に相対パスや不正なパスが入力された場合には、ファイルの送信ができない仕様ということ。

Tags:

develop

JavaScript冗長回避、性能改善の常套手段 - 初心者向け

2010/04/28 08:21

プログラミングにおける冗長回避、性能改善において力を発揮するコーディング手法を以下に記載します。

オブジェクト指向のコンパイル言語プログラムを書く人にとっては、性能面も踏まえ、作法として当たり前の事なのですが、

JavaScriptはウェブデザインと言う分野においてデザイナ/プログラマーの垣根なく使われる言語なので、コーディング作法や性能まで考えてプログラミングされていることが少ない気がします。

処理が短く簡易であるから良いものの、性能が全く出ていないであろうソースを沢山みます。

document.getElementById("id").~
document.getElementById("id").~
document.getElementById("id").~

なんて書いてプロパティセットしていくのはあまりに冗長ですし、毎回DOMでアクセスする分性能がでません。

var e = document.getElementById("id");
e.~
e.~

とすることを推奨します。

これによって、DOMでのアクセスは最初の1回のみになります。更にeとかくだけでよいのでコーディングの冗長さも断然減りますしね。

 

そして、document.getElementByIdなんて何度も使うことになると思います。こういった場合は、あらゆる有名なフレームワークでも実装されていますが、

var $ = function(id) {
    return document.getElementById(id);
}

なんていうオブジェクトを共通ライブラリで用意しておけば、

var e = $(id);
e.~
e.~

と書くことができます。

document.getElementById("id").~
document.getElementById("id").~
document.getElementById("id").~

var e = $(id);
e.~
e.~

になりました。如何でしょうか?

JavaScriptによるdrag&drop(ドラッグドロップ)

2010/04/27 05:19

JavaScriptによるドラッグアンドドロップは結構人気がありますが、全てのブラウザでまともに機能するソースはウェブ検索ではあまり出てこない様なので、以下に記載しておきます。

ご自由にコピーしてお使い下さい。

呼び出し方法は dragDrop.attach('ドラッグドロップ機能を付加したいエレメント'); です。

/*--ここから--*/

var dragDrop = {
    element:
        null
    ,
    mouseOffset:
        null
    ,
    mouseCoords:
        function(evt){
            if(evt.pageX || evt.pageY){
                return {x:evt.pageX, y:evt.pageY};
            }
            return {
                x:evt.clientX + document.body.scrollLeft - document.body.clientLeft,
                y:evt.clientY + document.body.scrollTop  - document.body.clientTop
            };
    }
    ,
    getMouseOffset:
        function(e, evt){
            var ev = evt || window.event;
            var ePos = dragDrop.getPosition(e);
            var mousePos = dragDrop.mouseCoords(ev);
            return {x:mousePos.x - ePos.x, y:mousePos.y - ePos.y};
    }
    ,
    getPosition:
        function(e){
            var elm = e;
            var left = 0;
            var top = 0;
            while (elm.offsetParent){
                left += elm.offsetLeft;
                top += elm.offsetTop;
                elm = elm.offsetParent;
            }
            left += elm.offsetLeft;
            top += elm.offsetTop;
            return {x:left, y:top};
    }
    ,
    mouseMove:
        function(evt){
            ev = evt || window.event;
            var mousePos = dragDrop.mouseCoords(ev);
            var e = dragDrop.element;
            if(e){
                e.style.position = 'absolute';
                e.style.top = mousePos.y - dragDrop.mouseOffset.y + "px";
                e.style.left = mousePos.x - dragDrop.mouseOffset.x + "px";
                return false;
            }
    }
    ,
    mouseUp:
        function(){
            dragDrop.element = null;
    }
    ,
    attach:
        function(e){
            if (!e) {
                return;
            }
            e.onmousedown = function(evt){
                dragDrop.element = this;
                dragDrop.mouseOffset = dragDrop.getMouseOffset(this, evt);
                return false;
            }
    }
}
document.onmousemove = dragDrop.mouseMove;
document.onmouseup = dragDrop.mouseUp;

/*--ここまで--*/

※ ドラッグアンドドロップ対象のエレメントの親がdocumentではなく、親要素のエレメントであった場合、getPositionのwhile文をコメントアウトして下さい。

struts2でファイルアップロード(FileUpload Interceptorの設定、初期値、制限)

2010/04/24 01:39

struts2のファイルアップロード用インターセプターに関して、基本的には英語だが以下にまとめられている。

http://struts.apache.org/2.0.14/docs/file-upload.html

・struts2のFileUpload Interceptorのアップロード可能なファイルサイズ制限は、デフォルトでは2MBに設定されている。また、この値は個々ではなく複数アップロードした場合はその合計値

propertiesファイルで以下を設定することによりオーバーライド可能。

struts.multipart.maxSize=任意の数値(Byte)
※ struts.xmlに以下を追加する方法もある。
<constant name="struts.multipart.maxSize" value="任意の数値(Byte)" />

因みに最大サイズの制限を無くすには"-1"を指定する。FileUploadBase.javaのソースコードをみて頂ければ仕様がわかると思う。

また、FileUpload Intercepterで曲者なのが、org.apache.commons.fileupload.FileUploadBaseにデフォルトでハードコードされているエラーメッセージだ。無理やりAction周りでリプレイスする荒業もあるが、そんなことはしちゃ駄目だ。

このInterceptorはmultipartのリクエストを処理する段階で呼ばれる(かなり早い段階で呼ばれる)為、MultiPartRequestで行われるparseメソッド呼び出し対象クラスを自前のものに変更する。

propertiesファイルで以下を設定することにより呼び出しクラスを変更可能。デフォルトのクラスを継承したクラスに変更し、メソッドをオーバーライドしよう。

struts.multipart.parser=自前で用意したクラスのFQCN

といった具合です。

更に、一時ファイルの保存ディレクトリを変更する場合は

struts.multipart.saveDir=保存先ディレクトリ

を記述します。

 

フォームから値を取得する方法は

・File [fileName]  -- ファイルオブジェクト
・String [fileName]ContentType -- コンテンツタイプ
・String [fileName]FileName -- アップロードフォームのファイル名

のメンバ変数とセッターゲッターを用意すると、各々自動でバインドされます。
※ 別にFileオブジェクトだけでも可能。[fileName]部分は任意。

正規のドキュメントが英語のものしかない為情報が少ないですが(しかも本家にも書かれていないこともある)、struts2って素晴らしいですね。

大体は変なことをしなくても拡張可能な様に実装されていると思われます。

でもすごく気に入らない実装もあった気がするんだよなぁ。。忘れちゃったけど。

struts2において、フォームの値を入れ子構造の配列で受け取る際の小技

2010/04/23 17:29

Javaのフレームワークstruts2を利用した開発において、

フォームの値をプログラムで取得する際は、getModel()でフォームの値をマッピングした型を返すパターンが多いと思います。

この場合で配列を利用する際は、

【HTML】

--------------------------------------------------------------

<input type="text" name="model[0].name">

<input type="text" name="model[0].link">

<input type="text" name="model[1].name">

<input type="text" name="model[1].link">

<input type="text" name="model[2].name">

<input type="text" name="model[2].link">

--------------------------------------------------------------

【Java】

--------------------------------------------------------------

アクション

・・・

private List<HogeForm> hogeForm = new ArrayList<HogeForm>();

@Element( value = HogeForm.class )

public Object getModel() {

    return hogeForm;

}

・・・

※ HogeFormクラスにはname, linkのメンバ変数を用意

--------------------------------------------------------------

みたいな感じでアノテーション@Element( value = HogeForm.class ) を利用することで、階層を浅くする事ができるのですが、あまり知られていない様です。

現場でよくみかけるのは下記の様なソースです。

【HTML】

--------------------------------------------------------------

<input type="text" name="hogeListForm.form[0].name">

<input type="text" name="hogeListForm.form[0].link">

<input type="text" name="hogeListForm.form[1].name">

<input type="text" name="hogeListForm.form[1].link">

<input type="text" name="hogeListForm.form[2].name">

<input type="text" name="hogeListForm.form[2].link">

--------------------------------------------------------------

【Java】

--------------------------------------------------------------

アクション

・・・

private HogeListForm hogeListForm = new HogeListForm();

public Object getModel() {

    return hogeListForm;

}

・・・

※   HogeListFormクラスにはFormクラス型のリストのメンバ変数を用意、Formクラスにはname, linkのメンバ変数を用意

--------------------------------------------------------------

是非、アノテーション@Elementを使用してみて下さい。