目次

チュートリアル4(投稿フォーム)

下部の投稿フォームを実装します。 まずは初期化処理を記述します。

tutorial3/logic/AdminHtml.java①
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
    public void init(){
        super.init();
        // モックアップHTMLの内容と異なる内容で初期化したい場合は
        // super.init()の後に変更用の処理を記述して下さい。
        // このメソッドは上記コンストラクタの中から呼ばれます。
        // インスタンス発生はバックグラウンドで非同期に処理していますので
        // HTTPリクエスト発生よりずっと過去に初期化されます。
        // このため、ユーザーのトランザクションに応じた条件分岐を設けても
        // 意図した振る舞いになりません。
 
        org_line = getDeleteListTable().getLineReplica( 1 );
 
        getTitleInput().setTitle( "タイトル" );
        getTextTextarea().setTitle( "本文" );
        getTopImageInput().setTitle( "上部画像" );
        getBottomImageInput().setTitle( "下部画像" );
        Select  select = getCategorySelect();
        select.setTitle( "カテゴリ" );
        select.removeHTMLPart();
        for ( int i = 0; i < Article.CATEGORY.length; i++ ) {
            select.addHTMLPart(
                new SelectItem( Article.CATEGORY[i], Integer.toString( i ) )
            );
        }
        getErrorFont().setVisible( false );
    }

コントロールのタイトル設定、最後のエラーメッセージの非表示化。
それと、中央のループ部分はカテゴリの<SELECT>内容を作成し直しています。
モックアップ HTML にもカテゴリは記述されていましたが、Article クラスとの整合性を保つ目的で Article クラスの内容を使い初期化しています。

次にアップロードされた画像の検証・保存を行うメソッドを作成します。

tutorial3/logic/AdminHtml.java②
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
    private String getFileName( UploadFile uf )
    throws ControlException, PageException {
        uf.checkExtension( "のファイル形式が不正です。", "jpg" );
        //uf.checkContentType( "のファイル形式が不正です。", "image/jpeg" );
        String  name = uf.getValueString();
        if ( name == null ) return null;
        try {
            java.io.File    file = new java.io.File( Article.PATH + name );
            // 予め/tmp/blog/ディレクトリを作成しておいて下さい。
            // 存在しない場合、例外が発生します。
            uf.move( file );
            return file.getPath();
        }
        catch( Exception e ) {
            throw new PageException( e );
        }
    }

投稿された時のチェックルーチンを作成します。

tutorial3/logic/AdminHtml.java③
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
    public Forward inputMain( RequestParameter req, Forward fw ) throws PageException {
        // fwにはモックアップと同じ遷移先が設定されています。
        // 別の遷移先としたい場合は、新しくForwardインスタンスを生成して
        // リターンして下さい。
 
        if ( getDeleteInput().isClicked() ) {
            Tag[]   tag = getTargetTags();
            for ( int i = 0; i < tag.length; i++ ) {
                CheckBox    box = (CheckBox)tag[i];
                if ( box.isChecked() ) {
                    Article.db.remove( (Article)box.getUserData() );
                }
            }
            makeList();
        }
        else if ( getPostInput().isClicked() ) {
            Article article = null;
            try {
                Control.checkNull( "が未入力です。", getTitleInput(), getTextTextarea() );
                String[]    category = getCategorySelect().getValueStrings();
                if ( category.length == 0 ) {
                    throw new ControlException( "が未入力です。", getCategorySelect() );
                }
                article = new Article( getTitleInput().getValueString(), getTextTextarea().getValueString(), category );
                article.image[0] = getFileName( getTopImageInput() );
                article.image[1] = getFileName( getBottomImageInput() );
                // 正しいデータなので登録する。
                Article.db.add( 0, article );
                makeList();
                // 入力項目は初期化する
                getTitleInput().setValueString( null );
                getTextTextarea().setValueString( null );
                getCategorySelect().setValueString( null );
                getErrorFont().setVisible( false );
            }
            catch( ControlException e ) {
                Tag error = getErrorFont();
                error.setVisible( true );
                error.setValueString( e.getControl().getTitle() + e.getMessage() );
                getTopImageInput().delete();
                getBottomImageInput().delete();
            }
        }
        return fw;
    }

例外処理

このままですと、以下の場合に /tmp/blog/ に不要な画像ファイルが残存してしまいます。

/tmp/blog/ 下の画像を削除するメソッドも準備します。

tutorial3/logic/AdminHtml.java④
1:
2:
3:
4:
5:
6:
7:
    private void deleteImage( Article article ) {
        if ( article == null )  return;
        for ( int i = 0; i < article.image.length; i++ ) {
            if ( article.image[i] == null ) continue;
            new java.io.File( article.image[i] ).delete();
        }
    }

また、このメソッドの呼び出し部分も作成します。

tutorial3/logic/AdminHtml.java⑥
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
    public Forward inputMain( RequestParameter req, Forward fw ) throws PageException {
        // fwにはモックアップと同じ遷移先が設定されています。
        // 別の遷移先としたい場合は、新しくForwardインスタンスを生成して
        // リターンして下さい。
 
        if ( getDeleteInput().isClicked() ) {
            Tag[]   tag = getTargetTags();
            for ( int i = 0; i < tag.length; i++ ) {
                CheckBox    box = (CheckBox)tag[i];
                if ( box.isChecked() ) {
                    Article.db.remove( (Article)box.getUserData() );
                    deleteImage( (Article)box.getUserData() );
                }
            }
            makeList();
        }
        else if ( getPostInput().isClicked() ) {
            Article article = null;
            try {
                Control.checkNull( "が未入力です。", getTitleInput(), getTextTextarea() );
                String[]    category = getCategorySelect().getValueStrings();
                if ( category.length == 0 ) {
                    throw new ControlException( "が未入力です。", getCategorySelect() );
                }
                article = new Article( getTitleInput().getValueString(), getTextTextarea().getValueString(), category );
                article.image[0] = getFileName( getTopImageInput() );
                article.image[1] = getFileName( getBottomImageInput() );
                // 正しいデータなので登録する。
                Article.db.add( 0, article );
                makeList();
                // 入力項目は初期化する
                getTitleInput().setValueString( null );
                getTextTextarea().setValueString( null );
                getCategorySelect().setValueString( null );
                getErrorFont().setVisible( false );
            }
            catch( ControlException e ) {
                Tag error = getErrorFont();
                error.setVisible( true );
                error.setValueString( e.getControl().getTitle() + e.getMessage() );
                getTopImageInput().delete();
                getBottomImageInput().delete();
                deleteImage( article );
            }
        }
        return fw;
    }

アップロード制限

補足ですが、SuperPageには以下のメソッドがあります。

tutorial3/SuperPage.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
    /**
     * アップロードファイルの最大バイト数。
     * @return 負数なら無制限に受け付けます。
     */
    public int getUploadMaxBytes() {
        // アップロードに制限をかける場合は下記を修正するか、
        // 各ページでオーバーライドして下さい。
        return 1024 * 1024 * 2;
    }

実運用では、ディスク容量とアクセス数を鑑みて制限をかけておいた方が安全でしょう。

チュートリアル5(ブログ画面)