Edzy_Java

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

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

            方案:

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

            解決方法做成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中防刷新的控件 同時在客戶端和服務(wù)端保存一樣的值,

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

             */

            public class HtmlRefresh extends UIComponentBase...{

            private boolean m_refreshState;

            private boolean m_isRefresh;

            /** *//**

            * 當(dāng)前請求是否是刷新

            * @return true 是;false 不是;

            */

            public boolean IsRefresh()...{

            return m_isRefresh;

            }

            /** *//**

            * 返回對應(yīng)的渲染器,這里沒有單獨的渲染器,所以返回null

            */

            public String getFamily()...{

            return null;

            }

            //

            /** *//**

            * 保存視圖

            */

            public Object saveState(FacesContext context)...{

            Object values[] = new Object[2];

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

            // 保存客戶端的值

            values[1] = !m_refreshState;

            // 服務(wù)器的值保存到session中

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

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

            session.setAttribute("ServerRefresh",m_refreshState);

            return values;

            }

            /** *//**

            * 恢復(fù)視圖

            */

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

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

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

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

            // 取服務(wù)器端值

            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技術(shù)
          主站蜘蛛池模板: 湾仔区| 辽宁省| 浙江省| 万源市| 方城县| 大城县| 广平县| 台前县| 武山县| 吐鲁番市| 桐柏县| 石景山区| 大港区| 开江县| 濮阳县| 上饶市| 鹤岗市| 准格尔旗| 乌审旗| 石楼县| 醴陵市| 乌拉特中旗| 长沙县| 同心县| 龙游县| 盐源县| 枞阳县| 景泰县| 历史| 禹州市| 县级市| 民丰县| 诸暨市| 浦县| 丹棱县| 从化市| 遂平县| 荔浦县| 平潭县| 鱼台县| 长沙县|