在JSF中防止页面刷新重复提交


在WEB开发中都会碰见这样的情况,就是用户在进行了一项操作后按F5刷新页面会重复提交页面的问题。

先了解下浏览器按F5会发生什么事,在按下F5后浏览器并不是简单的刷新页面,而是模拟上一次的请求一模一样的再向服务器请求一次,加入上一次的请求是向服务器请求保存数据,那按F5后就会再一次请求保存数据,这样就等于重复提交了一次保存数据,如果我们系统中不做判断的话,很容易在用户不小心按F5后再一次把数据保存进数据库了。

方案:
因为按F5是完全模拟上次的请求再请求一次,可以说发送的数据和上次请求的是一样的,就想到可以在客户端和服务器端各保存一个标识状态,然后在请求中比较2个表示状态就好了。

我把我的解决方法做成1个组件,这样就可以在所有需要使用的页面上使用该组件了,下面就直接看组件的代码吧
(如何编写组件这里就先不说)。

package  com.byd.jsfcomponents.Refresh;

import  java.io.IOException;
import  javax.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;
    }

        
    
// <editor-fold defaultstate="collapsed" desc="保存恢复视图">
    /**
     *  保存视图
     
*/

    
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;
    }

    
// </editor-fold>
}



在页面中使用如下:

<%@ taglib uri="http://www.byd.com.cn/component" prefix="byd" %>
<byd:HtmlRefresh id="HtmlRefresh1" binding="#{Page1.htmlRefresh1}" />

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;
    }

开发环境:NetBeans5.5.1 + netbeans-visualweb-5_5-windows-zh_CN.exe

附原代码: 点击下载
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值