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 閱讀(491) 評論(0)  編輯  收藏 所屬分類: JSP&Servlet技術
          主站蜘蛛池模板: 抚顺县| 礼泉县| 托克逊县| 东台市| 龙南县| 错那县| 城步| 邳州市| 内江市| 湘西| 从江县| 三穗县| 十堰市| 宜章县| 武隆县| 武城县| 龙山县| 虹口区| 秀山| 神农架林区| 曲周县| 乳源| 从江县| 抚顺县| 斗六市| 炎陵县| 滦南县| 常宁市| 北辰区| 桂东县| 呼伦贝尔市| 瓮安县| 漾濞| 武平县| 北碚区| 温宿县| 五寨县| 农安县| 图们市| 扬中市| 满洲里市|