关闭

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

标签: jsfimport服务器netbeansnullbinding
1700人阅读 评论(0) 收藏 举报
分类:

在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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:50111次
    • 积分:714
    • 等级:
    • 排名:千里之外
    • 原创:20篇
    • 转载:1篇
    • 译文:0篇
    • 评论:25条
    文章分类
    最新评论