かずきのBlog

C#やJavaやRubyとメモ書き

目次

Blog 利用状況

ニュース

わんくまBlogが不安定になったため、前に書いてたはてなダイアリーにメインを移動します。
かずきのBlog@Hatena
技術的なネタは、こちらにも、はてなへのリンクという形で掲載しますが、雑多ネタははてなダイアリーだけに掲載することが多いと思います。
コメント
プログラマ的自己紹介
お気に入りのツール/IDE
プロフィール
経歴
広告
アクセサリ

書庫

日記カテゴリ

[NetBeans][Java]Visual Web JSFにもRailsのflashみたいなのが欲しい

Ruby on Railsに、flashというデータ入れる場所がある。

flash[:name] = "ほげたろう" # 格納時
name = flash[:name] # 取り出す時

こんな雰囲気で使える代物になってる。
このflashに入れたデータは、次のリクエストまで有効になっている。
なので、sessionみたいに一度入れたら消すまで消えないっていうものよりはお手軽になってる。

sessionにどんどこデータを入れまくって消す処理が無くて最後にはサーバを圧迫して悲しい末路を辿ることが少なくなってる素晴らしい?仕組みです。
因みに、次のリクエストが終わったら絶対消えるのかと言うとそうでもない。keepというメソッドを呼び出すことで、その次のリクエストまで持ち越すことが可能になってる。

flash.keep(:name) # 次のリクエストまで持ち越しておくれ

次のリクエストまで持ち越して欲しくない場合は明示的にdiscardというメソッドを呼ぶと次のリクエストでは消したりもできる。

flash.discard(:name)

Visual Web JSFで開発するときもコレホシイ!!ということで似たようなのを作ってみた。
まず、Webに依存しない部分でデータを保持する仕組みとデータのライフサイクルを管理するクラスを作る。

package com.wankuma.kazuki.vwjsf.flash;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * flashみたいなデータ保持をするクラス。
 * refleshをリクエストの最後に呼ぶ使い方を想定してる。
 * @author Kazuki
 */
public class FlashData implements Serializable {
    // 前のリクエストで設定された値をとっておくMap
    private Map<String, Object> prevCache = createMap();
    // 現在のリクエストで設定された値をとっておくMap
    private Map<String, Object> currentCache = createMap();


    /**
     * nameをキーにしてvalueを登録する。
     * @param name
     * @param value
     */
    public synchronized void put(String name, Object value) {
        currentCache.put(name, value);
    }

    /**
     * nameで指定した値を取得する。
     * 存在しない場合は、nullを返す。
     * @param name
     * @return
     */
    public synchronized Object get(String name) {
        if (currentCache.containsKey(name)) {
            return currentCache.get(name);
        }
        return prevCache.get(name);
    }

    /**
     * nameで指定した値を次のリクエストでも使えるようにする。
     * @param name
     */
    public synchronized void keep(String name) {
        put(name, get(name));
    }

    /**
     * nameで指定した値を、次のリクエストで消えるようにする。
     * @param name
     */
    public synchronized void discard(String name) {
        Object value = currentCache.get(name);
        if (value != null) {
            currentCache.remove(name);
            prevCache.put(name, value);
        }
    }

    /**
     * 前のリクエストのデータを消す。
     */
    synchronized void reflesh() {
        prevCache.clear();
        prevCache = currentCache;
        currentCache = createMap();
    }

    /**
     * SynchronizedなMapを生成する。
     * @return
     */
    Map<String, Object> createMap() {
        return Collections.synchronizedMap(new HashMap<String, Object>());
    }
}

若干synchronizedしすぎかな?と思わないでも無いけど、とりあえずこんなもんで。
putとgetでデータの追加と取得が出来るようになっている。
内部では、前のリクエストのときに追加されたデータを保持するprevCacheと、現在のリクエストで追加されたデータを保持するcurrentCacheという2つのマップを持っている。

keepでは、データを取得して再度セットすることで、現在のリクエストで追加されたデータという扱いに強制的に持っていくことで、次のリクエストでも有効になるようにしている。
逆にdiscardでは、前のリクエストで追加されたデータの領域に無理やりデータを移動させている。
これで、次のリクエストではサヨウナラという感じになってる。

refleshというメソッドで、前のリクエストのデータを消している。

次にWebに依存する部分。Sessionに上で作ったFlashDataを保持するようにしている。

package com.wankuma.kazuki.vwjsf.flash;

import java.util.Map;
import javax.faces.context.FacesContext;

/**
 * セッションでFlashDataを保持する人。
 * @author Kazuki
 */
public class Flash {
    // セッション上にFlashDataを保持するときに使うKey
    private static final String SESSION_KEY = Flash.class.getName() + "_SESSION_KEY";

    // インスタンス化禁止
    private Flash() {}
    
    /**
     * セッション上からFlashDataを取得する。(無い場合は作る)
     * @return
     */
    synchronized static FlashData getFlashData() {
        Map<String, Object> sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
        FlashData flashData = (FlashData) sessionMap.get(SESSION_KEY);
        if (flashData == null) {
            flashData = new FlashData();
            sessionMap.put(SESSION_KEY, flashData);
        }
        return flashData;
    }
    
    /**
     * FlashDataへデータを設定する
     * @param name
     * @param value
     */
    public static void put(String name, Object value) {
        getFlashData().put(name, value);
    }
    
    /**
     * FlashDataからデータを型指定で取得する。
     * @param <T>
     * @param name
     * @param clazz
     * @return
     */
    public static <T> T get(String name, Class<T> clazz) {
        return (T) get(name);
    }
    
    /**
     * FlashDataからデータを取得する
     * @param key
     * @return
     */
    public static Object get(String name) {
        return getFlashData().get(name);
    }
    
    /**
     * nameで指定した値を次のリクエストに持ち越すように指定する。
     * @param name
     */
    public static void keep(String name) {
        getFlashData().keep(name);
    }
    
    /**
     * nameで指定した値を次のリクエストで破棄するように指定する。
     * @param name
     */
    public static void discard(String name) {
        getFlashData().discard(name);
    }
}

そして、リクエストの最後にrefleshを呼ぶための人を準備する。PhaseListenerのRENDER_RESPONSEのafterのタイミングでrefleshを呼ぶようにした。

package com.wankuma.kazuki.vwjsf.flash;

import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

/**
 * flashのデータをリクエストの最後でリフレッシュする。
 * @author Kazuki
 */
public class FlashContextListener implements PhaseListener {

    public void afterPhase(PhaseEvent event) {
        // RENDER_RESPONSEの後(最後の最後)で、リフレッシュする。
        Flash.getFlashData().reflesh();
    }

    public void beforePhase(PhaseEvent event) {
    }

    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }
}

最後に、このPhaseListenerを登録するためにMETA-INFにfaces-config.xmlを作る。

<?xml version='1.0' encoding='UTF-8'?>

<faces-config version="1.2" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
    <lifecycle>
        <phase-listener>com.wankuma.kazuki.vwjsf.flash.FlashContextListener</phase-listener>
    </lifecycle>
</faces-config>

これをjarに固めて、Visual Web JSFのプロジェクト(まぁVisualWebである必要は無い)のライブラリに追加する。
テスト用にFlashTestという名前でVisual Web JSFのプロジェクトを作る。いつも通りPage1やApplicationBean1やSessionBean1やRequestBean1を削除する。
そして、上で作ったjarをプロジェクトに追加する。

んで新規にPageを2つ追加する。名前は何も考えずにPage1とPage2にした。Page1をスタートページにして、下のように画面を作る。
image image

ページナビゲーションは下のような感じ。
image

Page1のTextFieldのtextプロパティをPage1のinputMessageプロパティにバインドする。
そしてbutton1のactionで下のようにFlashにデータを入れてPage2に遷移する。

    public String button1_action() {
        // Flashにデータを入れてPage2へ
        Flash.put("Page1.inputMessage", inputMessage);
        return "page2";
    }

Page2にもinputMessageというプロパティを用意して、上から二番目のStaticText(abcと表示されてるやつ)のtextプロパティとバインドしておく。
そして、Page2のinitメソッドでFlashからinputMessageプロパティに値を代入するようにした。

        // FlashからPage1で設定したデータを取得する
        inputMessage = Flash.get("Page1.inputMessage", String.class);

3つあるボタンでは、上から何もしないボタン、Flashにkeepを指示するボタン、Page1に戻るボタンになっている。

    public String button1_action() {
        // do nothing
        return null;
    }
    
    public String button2_action() {
        Flash.keep("Page1.inputMessage");
        return null;
    }
    
    public String button3_action() {
        // Page1へ戻る
        return "page1";
    }

これで、Page1で入力したテキストが、Page2に表示されるようになっているはず。
Flashは、入力した次のリクエストまで有効なのでPage2の何もしないボタンを2回押すとテキストが消えるはず。
Flash.keepするボタンだと何度押してもテキストが表示され続けるはず!!ということで実行!

何もしないボタンを押した場合の実行結果
imageimageimageimage
予想通り、何もしないボタンを2回押すと入力したテキストが消えた。

Keepボタンを押した場合の実行結果
imageimageimageimage
こちらも予想通り、何度ボタンを押しても消えない。
いい感じにできてると思うけどどうだろうか?

投稿日時 : 2008年5月31日 21:03

Feedback

# [NetBeans][Java]RoRのflashみたいなもの その2 2008/06/01 11:02 かずきのBlog

[NetBeans][Java]RoRのflashみたいなもの その2

# sacs lancel 2012/10/17 22:01 http://www.saclancelpascher2013.com

You are my intake, I possess few blogs and occasionally run out from brand :). "Never mistake motion for action." by Ernest Hemingway.

# full welded ball valve 2012/10/18 23:53 http://www.dwkvalve.com/product_cat_list/Full-Weld

Only a smiling visitant here to share the love (:, btw great design. "Treat the other man's faith gently it is all he has to believe with." by Athenus.

# Mens Supra High Tops 2012/12/08 3:51 http://suprafashionshoes.webs.com/

Absolutely written written content, regards for information. "The last time I saw him he was walking down Lover's Lane holding his own hand." by Fred Allen.

# burberry sale 2012/12/16 5:20 http://www.burberryuksale.org/category/burberry-sc

Nobody should see you to ultimately mug you from your basement.

# burberry uk 2012/12/17 8:51 http://www.ukburberryoutlet.info/category/burberry

I really don't know... there's some thing tacky approximately owning Ferrari branded things like this.. unless you additionally own an authentic Ferrari.

# 安いエルメス 2012/12/17 22:06 http://www.hermespairs.info/category/エルメスバーキン

I don't know... there's an item tacky on the subject of owning Ferrari branded things like this.. unless also you own a really Ferrari.

# sac longchamp 2012/12/18 21:38 http://www.longchampfr.info/category/sac-longchamp

I discover everybody may hate in it, but I do not think they glimpse so undesirable.

# sac michael kors 2012/12/18 22:57 http://sac-michael-kors.webnode.fr/blog/

Our pool needs to be fed with those photopages for you to consider well worth becoming system of the "Best Review Collection".

# la vente Burberry 2012/12/19 14:15 http://sacburberrysoldesfr.webnode.fr/actualites

I would like to take a closer look at some of their memorabilia!

# burberry scarf 2012/12/21 9:12 http://burberryoutlet2013sale.webeden.co.uk

We're impressed by the products information using this website. There are a great deal of good solutions here.

# michael kors sac solde 2012/12/22 19:01 http://michael-kors-canada.webnode.fr/news-/

this will be something may very well never possibly read.

# barikind https://baricitinibrx.com
where to buy baricitinib
2021/12/12 16:29 Buksdldj

barikind https://baricitinibrx.com
where to buy baricitinib

# Actual trends of drug. Medicament prescribing information.
https://edonlinefast.com
Read here. Comprehensive side effect and adverse reaction information. 2023/02/17 11:13 EdOnline

Actual trends of drug. Medicament prescribing information.
https://edonlinefast.com
Read here. Comprehensive side effect and adverse reaction information.

# Get warning information here. All trends of medicament.
https://edonlinefast.com
Get warning information here. Get here. 2023/02/18 0:59 EdOnline

Get warning information here. All trends of medicament.
https://edonlinefast.com
Get warning information here. Get here.

# What side effects can this medication cause? Everything information about medication.
https://canadianfast.com/
drug information and news for professionals and consumers. Read information now. 2023/02/19 12:53 CanadaBest

What side effects can this medication cause? Everything information about medication.
https://canadianfast.com/
drug information and news for professionals and consumers. Read information now.

# muscle relaxer over the counter https://overthecounter.pro/# 2023/05/08 23:01 OtcJikoliuj

muscle relaxer over the counter https://overthecounter.pro/#

# buy cheap prednisone https://prednisonepills.pro/# - prednisolone prednisone 2023/06/05 1:37 Prednisone

buy cheap prednisone https://prednisonepills.pro/# - prednisolone prednisone

# ed meds online https://edpill.pro/# - best erectile dysfunction pills 2023/06/27 14:46 EdPills

ed meds online https://edpill.pro/# - best erectile dysfunction pills

# best ed drug https://edpillsotc.store/# - top ed pills 2023/10/08 1:24 EdPills

best ed drug https://edpillsotc.store/# - top ed pills

# doxycycline 50mg https://doxycycline.forum/ doxycycline mono 2023/11/25 13:24 Doxycycline

doxycycline 50mg https://doxycycline.forum/ doxycycline mono

# farmaci senza ricetta elenco https://farmaciait.pro/ farmacia online migliore 2023/12/04 10:20 Farmacia

farmaci senza ricetta elenco https://farmaciait.pro/ farmacia online migliore

# prednisone generic brand name https://prednisone.bid/ prednisone sale 2023/12/27 10:29 Prednisone

prednisone generic brand name https://prednisone.bid/ prednisone sale

# prednisone 20mg capsule https://prednisonepharm.store/ 60 mg prednisone daily 2024/01/20 17:37 Prednisone

prednisone 20mg capsule https://prednisonepharm.store/ 60 mg prednisone daily

# lana rhoades video - https://lanarhoades.fun/ lana rhodes
2024/03/03 1:43 LanaRho

lana rhoades video - https://lanarhoades.fun/ lana rhodes

# gates of olympus oyna demo - https://gatesofolympus.auction/ gates of olympus 1000 demo 2024/03/27 20:46 Olympic

gates of olympus oyna demo - https://gatesofolympus.auction/ gates of olympus 1000 demo

タイトル
名前
Url
コメント