91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaWeb中HttpSession中表單的重復提交示例

發布時間:2020-08-24 19:31:44 來源:腳本之家 閱讀:139 作者:http://blog.csdn.net 欄目:編程語言

表單的重復提交

  • 重復提交的情況:

①. 在表單提交到一個 Servlet,而 Servlet 又通過請求轉發的方式響應了一個 JSP(HTML)頁面,此時地址欄還保留著 Servlet 的那個路徑,在響應頁面點擊 “刷新”。

②. 在響應頁面沒有到達時,重復點擊 “提交按鈕”

③. 點擊返回,再點擊提交

  • 不是重復提交的情況:點擊 “返回”,“刷新” 原表單頁面,再點擊提交。
  • 如何避免表單的重復提交:在表單中做一個標記,提交到 Servlet 時,檢查標記是否存在且和預定義的標記一樣,若一致,則受理請求,并銷毀標記,若不一致或沒有標記,則直接響應提示信息:“重復提交”

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

②把標記放在 Request 中 , 行不通,表單頁面刷新后,request 已經被銷毀,再提交表單是一個新的 request 的。

③把標記放在 Session 中,可以

1. 在原表單頁面,生成一個隨機值 token
2. 在原表單頁面,把 token 值放入 session 屬性中

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

4. 在目標的 Servlet 中:獲取 session 和隱藏域中的 token 值

比較兩個值是否一致,受理請求,且把 session 域中的 token 屬性清除,若不一致,則直接響應提示頁面:“重復提交”

我們可以通過 Struts1 中寫好的類 TokenProcessor 來重構代碼, 面向組件編程

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中表單的重復提交示例,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

车险| 翁源县| 昭平县| 灵山县| 永德县| 邮箱| 石阡县| 大英县| 漠河县| 枣强县| 溆浦县| 峨边| 罗江县| 陵水| 哈巴河县| 舒城县| 茂名市| 深圳市| 黄平县| 宝兴县| 江口县| 安顺市| 大足县| 冕宁县| 潞西市| 招远市| 临沂市| 垦利县| 翼城县| 青川县| 德兴市| 乌拉特后旗| 建水县| 浏阳市| 元氏县| 仁化县| 汾西县| 洛阳市| 容城县| 临安市| 望城县|