欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaWeb中HttpSession中表單的重復(fù)提交示例

 更新時(shí)間:2017年03月01日 13:59:25   作者:http://blog.csdn.net/qq_24942951/article/details/58606050  
這篇文章主要介紹了JavaWeb中HttpSession中表單的重復(fù)提交,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下

表單的重復(fù)提交

  • 重復(fù)提交的情況:

①. 在表單提交到一個(gè) Servlet,而 Servlet 又通過(guò)請(qǐng)求轉(zhuǎn)發(fā)的方式響應(yīng)了一個(gè) JSP(HTML)頁(yè)面,此時(shí)地址欄還保留著 Servlet 的那個(gè)路徑,在響應(yīng)頁(yè)面點(diǎn)擊 “刷新”。

②. 在響應(yīng)頁(yè)面沒(méi)有到達(dá)時(shí),重復(fù)點(diǎn)擊 “提交按鈕”

③. 點(diǎn)擊返回,再點(diǎn)擊提交

  • 不是重復(fù)提交的情況:點(diǎn)擊 “返回”,“刷新” 原表單頁(yè)面,再點(diǎn)擊提交。
  • 如何避免表單的重復(fù)提交:在表單中做一個(gè)標(biāo)記,提交到 Servlet 時(shí),檢查標(biāo)記是否存在且和預(yù)定義的標(biāo)記一樣,若一致,則受理請(qǐng)求,并銷(xiāo)毀標(biāo)記,若不一致或沒(méi)有標(biāo)記,則直接響應(yīng)提示信息:“重復(fù)提交”

①僅提供一個(gè)隱藏域不行:<input type="hidden" name="token" value="lsy">

②把標(biāo)記放在 Request 中 , 行不通,表單頁(yè)面刷新后,request 已經(jīng)被銷(xiāo)毀,再提交表單是一個(gè)新的 request 的。

③把標(biāo)記放在 Session 中,可以

1. 在原表單頁(yè)面,生成一個(gè)隨機(jī)值 token
2. 在原表單頁(yè)面,把 token 值放入 session 屬性中

3. 在原表單頁(yè)面,把 token 值放入到隱藏域

4. 在目標(biāo)的 Servlet 中:獲取 session 和隱藏域中的 token 值

比較兩個(gè)值是否一致,受理請(qǐng)求,且把 session 域中的 token 屬性清除,若不一致,則直接響應(yīng)提示頁(yè)面:“重復(fù)提交”

我們可以通過(guò) Struts1 中寫(xiě)好的類(lèi) TokenProcessor 來(lái)重構(gòu)代碼, 面向組件編程

package com.lsy.javaweb;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class TokenProcessor {
  private static final String TOKEN_KEY = "TOKEN_KEY";
  private static final String TRANSACTION_TOKEN_KEY = "TRANSACTION_TOKEN_KEY";
  /**
   * The singleton instance of this class.
   */
  private static TokenProcessor instance = new TokenProcessor();
  /**
   * The timestamp used most recently to generate a token value.
   */
  private long previous;
  /**
   * Protected constructor for TokenProcessor. Use
   * TokenProcessor.getInstance() to obtain a reference to the processor.
   */
  protected TokenProcessor() {
    super();
  }
  /**
   * Retrieves the singleton instance of this class.
   */
  public static TokenProcessor getInstance() {
    return instance;
  }
  /**
   * <p>
   * Return <code>true</code> if there is a transaction token stored in the
   * user's current session, and the value submitted as a request parameter
   * with this action matches it. Returns <code>false</code> under any of the
   * following circumstances:
   * </p>
   *
   * <ul>
   *
   * <li>No session associated with this request</li>
   *
   * <li>No transaction token saved in the session</li>
   *
   * <li>No transaction token included as a request parameter</li>
   *
   * <li>The included transaction token value does not match the transaction
   * token in the user's session</li>
   *
   * </ul>
   *
   * @param request
   *      The servlet request we are processing
   */
  public synchronized boolean isTokenValid(HttpServletRequest request) {
    return this.isTokenValid(request, false);
  }
  /**
   * Return <code>true</code> if there is a transaction token stored in the
   * user's current session, and the value submitted as a request parameter
   * with this action matches it. Returns <code>false</code>
   *
   * <ul>
   *
   * <li>No session associated with this request</li>
   * <li>No transaction token saved in the session</li>
   *
   * <li>No transaction token included as a request parameter</li>
   *
   * <li>The included transaction token value does not match the transaction
   * token in the user's session</li>
   *
   * </ul>
   *
   * @param request
   *      The servlet request we are processing
   * @param reset
   *      Should we reset the token after checking it?
   */
  public synchronized boolean isTokenValid(HttpServletRequest request, boolean reset) {
    // Retrieve the current session for this request
    HttpSession session = request.getSession(false);
    if (session == null) {
      return false;
    }
    // Retrieve the transaction token from this session, and
    // reset it if requested
    String saved = (String) session.getAttribute(TRANSACTION_TOKEN_KEY);
    if (saved == null) {
      return false;
    }
    if (reset) {
      this.resetToken(request);
    }
    // Retrieve the transaction token included in this request
    String token = request.getParameter(TOKEN_KEY);
    if (token == null) {
      return false;
    }
    return saved.equals(token);
  }
  /**
   * Reset the saved transaction token in the user's session. This indicates
   * that transactional token checking will not be needed on the next request
   * that is submitted.
   *
   * @param request
   *      The servlet request we are processing
   */
  public synchronized void resetToken(HttpServletRequest request) {
    HttpSession session = request.getSession(false);
    if (session == null) {
      return;
    }
    session.removeAttribute(TRANSACTION_TOKEN_KEY);
  }
  /**
   * Save a new transaction token in the user's current session, creating a
   * new session if necessary.
   *
   * @param request
   *      The servlet request we are processing
   */
  public synchronized String saveToken(HttpServletRequest request) {
    HttpSession session = request.getSession();
    String token = generateToken(request);
    if (token != null) {
      session.setAttribute(TRANSACTION_TOKEN_KEY, token);
    }
    return token;
  }
  /**
   * Generate a new transaction token, to be used for enforcing a single
   * request for a particular transaction.
   *
   * @param request
   *      The request we are processing
   */
  public synchronized String generateToken(HttpServletRequest request) {
    HttpSession session = request.getSession();
    return generateToken(session.getId());
  }
  /**
   * Generate a new transaction token, to be used for enforcing a single
   * request for a particular transaction.
   *
   * @param id
   *      a unique Identifier for the session or other context in which
   *      this token is to be used.
   */
  public synchronized String generateToken(String id) {
    try {
      long current = System.currentTimeMillis();
      if (current == previous) {
        current++;
      }
      previous = current;
      byte[] now = new Long(current).toString().getBytes();
      MessageDigest md = MessageDigest.getInstance("MD5");
      md.update(id.getBytes());
      md.update(now);
      return toHex(md.digest());
    } catch (NoSuchAlgorithmException e) {
      return null;
    }
  }
  /**
   * Convert a byte array to a String of hexadecimal digits and return it.
   *
   * @param buffer
   *      The byte array to be converted
   */
  private String toHex(byte[] buffer) {
    StringBuffer sb = new StringBuffer(buffer.length * 2);
    for (int i = 0; i < buffer.length; i++) {
      sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));
      sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
    }
    return sb.toString();
  }
}

以上所述是小編給大家介紹的JavaWeb中HttpSession中表單的重復(fù)提交示例,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • springboot之自動(dòng)裝配全過(guò)程

    springboot之自動(dòng)裝配全過(guò)程

    這篇文章主要介紹了springboot之自動(dòng)裝配全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • SpringCloud Alibaba微服務(wù)實(shí)戰(zhàn)之遠(yuǎn)程Feign請(qǐng)求頭丟失問(wèn)題解決方案

    SpringCloud Alibaba微服務(wù)實(shí)戰(zhàn)之遠(yuǎn)程Feign請(qǐng)求頭丟失問(wèn)題解決方案

    這篇文章主要介紹了SpringCloud Alibaba微服務(wù)實(shí)戰(zhàn)之遠(yuǎn)程Feign請(qǐng)求頭丟失問(wèn)題,對(duì)SpringCloud Alibaba Feign請(qǐng)求頭問(wèn)題感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • Springboot整合activemq的方法步驟

    Springboot整合activemq的方法步驟

    這篇文章主要介紹了Springboot整合activemq的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • SpringBoot項(xiàng)目中jar發(fā)布獲取jar包所在目錄路徑的最佳方法

    SpringBoot項(xiàng)目中jar發(fā)布獲取jar包所在目錄路徑的最佳方法

    在開(kāi)發(fā)過(guò)程中,我們經(jīng)常要遇到上傳圖片、word、pdf等功能,但是當(dāng)我們把項(xiàng)目打包發(fā)布到服務(wù)器上時(shí),對(duì)應(yīng)的很多存儲(chǔ)路徑的方法就會(huì)失效,下面這篇文章主要給大家介紹了關(guān)于SpringBoot項(xiàng)目中jar發(fā)布獲取jar包所在目錄路徑的相關(guān)資料
    2022-07-07
  • SpringBoot @ExceptionHandler與@ControllerAdvice異常處理詳解

    SpringBoot @ExceptionHandler與@ControllerAdvice異常處理詳解

    在Spring Boot應(yīng)用的開(kāi)發(fā)中,不管是對(duì)底層數(shù)據(jù)庫(kù)操作,對(duì)業(yè)務(wù)層操作,還是對(duì)控制層操作,都會(huì)不可避免的遇到各種可預(yù)知的,不可預(yù)知的異常需要處理,如果每個(gè)處理過(guò)程都單獨(dú)處理異常,那么系統(tǒng)的代碼耦合度會(huì)很高,工作量大且不好統(tǒng)一,以后維護(hù)的工作量也很大
    2022-10-10
  • Java實(shí)現(xiàn)文件變化監(jiān)聽(tīng)代碼實(shí)例

    Java實(shí)現(xiàn)文件變化監(jiān)聽(tīng)代碼實(shí)例

    這篇文章主要介紹了Java實(shí)現(xiàn)文件變化監(jiān)聽(tīng)代碼實(shí)例,通過(guò)定時(shí)任務(wù),輪訓(xùn)查詢(xún)文件的最后修改時(shí)間,與上一次進(jìn)行對(duì)比,如果發(fā)生變化,則說(shuō)明文件已經(jīng)修改,進(jìn)行重新加載或?qū)?yīng)的業(yè)務(wù)邏輯處理,需要的朋友可以參考下
    2024-01-01
  • 關(guān)于String轉(zhuǎn)Json的幾種方式

    關(guān)于String轉(zhuǎn)Json的幾種方式

    這篇文章主要介紹了關(guān)于String轉(zhuǎn)Json的幾種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 必須了解的高階JAVA枚舉特性!

    必須了解的高階JAVA枚舉特性!

    這篇文章主要介紹了必須了解的高階JAVA枚舉特性!幫助大家更好的理解和學(xué)習(xí)Java枚舉的相關(guān)知識(shí),感興趣的朋友可以了解下
    2021-01-01
  • JSON反序列化Long變Integer或Double的問(wèn)題及解決

    JSON反序列化Long變Integer或Double的問(wèn)題及解決

    這篇文章主要介紹了JSON反序列化Long變Integer或Double的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Maven實(shí)戰(zhàn)之搭建Maven私服和鏡像的方法(圖文)

    Maven實(shí)戰(zhàn)之搭建Maven私服和鏡像的方法(圖文)

    本篇文章主要介紹了搭建Maven私服和鏡像的方法(圖文),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12

最新評(píng)論