Edzy_Java

            BlogJava :: 首頁 ::  ::  ::  :: 管理 ::
            58 隨筆 :: 12 文章 :: 11 評論 :: 0 Trackbacks
          在WEB開發中都會碰見這樣的情況,就是用戶在進行了一項操作后按F5刷新頁面會重復提交頁面的問題。

            先了解下瀏覽器按F5會發生什么事,在按下F5后瀏覽器并不是簡單的刷新頁面,而是模擬上一次的請求一模一樣的再向服務器請求一次,加入上一次的請求是向服務器請求保存數據,那按F5后就會再一次請求保存數據,這樣就等于重復提交了一次保存數據,如果我們系統中不做判斷的話,很容易在用戶不小心按F5后再一次把數據保存進數據庫了。

            方案:

            因為按F5是完全模擬上次的請求再請求一次,可以說發送的數據和上次請求的是一樣的,就想到可以在客戶端和服務器端各保存一個標識狀態,然后在請求中比較2個表示狀態就好了。

            解決方法做成1個組件,這樣就可以在所有需要使用的頁面上使用該組件了,下面就直接看組件的代碼吧

            package com.byd.jsfcomponents.Refresh;

            import java.io.IOException;

            import jaax.faces.component.UIComponentBase;

            import javax.faces.context.ExternalContext;

            import javax.faces.context.FacesContext;

            import javax.faces.context.ResponseWriter;

            import javax.servlet.http.HttpSession;

            /** *//**

             * JSF中防刷新的控件 同時在客戶端和服務端保存一樣的值,

             * 每次請求都改變2個的值(和以前的值相反),如果是刷新,取到的客戶端的值將服務端的值不一樣。

             */

            public class HtmlRefresh extends UIComponentBase...{

            private boolean m_refreshState;

            private boolean m_isRefresh;

            /** *//**

            * 當前請求是否是刷新

            * @return true 是;false 不是;

            */

            public boolean IsRefresh()...{

            return m_isRefresh;

            }

            /** *//**

            * 返回對應的渲染器,這里沒有單獨的渲染器,所以返回null

            */

            public String getFamily()...{

            return null;

            }

            //

            /** *//**

            * 保存視圖

            */

            public Object saveState(FacesContext context)...{

            Object values[] = new Object[2];

            values[0] = super.saveState(context); // 系統自己的State

            // 保存客戶端的值

            values[1] = !m_refreshState;

            // 服務器的值保存到session中

            ExternalContext exContext = FacesContext.getCurrentInstance().getExternalContext();

            HttpSession session = (HttpSession)exContext.getSession(true);

            session.setAttribute("ServerRefresh",m_refreshState);

            return values;

            }

            /** *//**

            * 恢復視圖

            */

            public void restoreState(FacesContext context, Object state)...{

            Object values[] = (Object[]) state;

            super.restoreState(context, values[0]);

            this.m_refreshState = (Boolean)values[1];

            // 取服務器端值

            ExternalContext exContext = FacesContext.getCurrentInstance().getExternalContext();

            HttpSession session = (HttpSession)exContext.getSession(true);

            Boolean _bRefresh = false;

            if(session.getAttribute("ServerRefresh") != null)...{

            _bRefresh = Boolean.valueOf(session.getAttribute("ServerRefresh").toString());

            }

            m_isRefresh = m_refreshState == _bRefresh;

            }

            //

            }

            在頁面中使用如下:

            JAVABEAN代碼:

            private HtmlRefresh htmlRefresh1 = new HtmlRefresh();

            public HtmlRefresh getHtmlRefresh1() {

            return htmlRefresh1;

            }

            public void setHtmlRefresh1(HtmlRefresh htmlRefresh1) {

            this.htmlRefresh1 = htmlRefresh1;

            }

            public String button1_action() {

            // 先判斷是否刷新

            if(htmlRefresh1.IsRefresh()){

            this.label1.setText("請別刷新提交");

            }else{

            this.label1.setText("正常提交");

            }

            return null;

            }
          posted on 2007-12-18 09:31 lbfeng 閱讀(487) 評論(0)  編輯  收藏 所屬分類: JSP&Servlet技術
          主站蜘蛛池模板: 南丰县| 宣化县| 尼玛县| 中宁县| 喀喇沁旗| 留坝县| 平山县| 萨嘎县| 德格县| 山东省| 甘肃省| 格尔木市| 定安县| 吉首市| 乌审旗| 汉寿县| 清水河县| 驻马店市| 达日县| 青冈县| 登封市| 温泉县| 宜兰市| 梅河口市| 庄浪县| 黑河市| 无为县| 美姑县| 通海县| 六盘水市| 内丘县| 顺平县| 三河市| 浙江省| 襄垣县| 当雄县| 堆龙德庆县| 都兰县| 十堰市| 红桥区| 凤庆县|