2012-10-04 17 views
6

私はindex.jspページを持っています。ここには、ユーザーがControllerサーブレットを使用してデータベースに格納されたデータを入力するフォームがあります。リフレッシュ中に重複するエントリを防止するにはどうすればよいですか?

データベースにデータを入力した後、そのフォームで同じページ(index.jsp)を表示したいとします。また、ユーザーがデータベースに入力したすべてのエントリを表示する必要があります。

forward()の方法をRequestDispatcherと試してみました。それは正常に動作します(つまり、同じフォームを再度表示し、そのユーザーがJSTLを使用してフォームの下に入力したすべてのデータも表示できます)。

しかし、問題はユーザーがRefresh or F5ボタンを押すたびに、すべての前のデータもデータベースに入力され、すべてのデータが表示されているので、重複するエントリも表示されます。

私はPOST-REDIRECT-GETパターンを使用することを考えましたが、リダイレクトするときにJSTLを使用して表示されないようにするのが問題です。

どうすればよいですか?

答えて

9

(そして、あなたは、もはや私の最初の答えに前に導入さnamesリストを必要とする)私はPOST-REDIRECT-GETパターンを使用するのではと思っていないが、私は、私はそれらのデータが表示されるように得ることはありませんリダイレクトするときに問題がありますJSTLを使用します。

新しいGETリクエストで表示したい情報を特定するには、リクエストパラメータを送信してください。

// ... 
Long id = dataService.save(data); 
// ... 
response.sendRedirect(request.getContextPath() + "/index?editId=" + id); 

、その後/index

@Override 
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    Long editId = Long.valueOf(request.getParameter("editId")); // Handle nullcheck yourself. 
    Data editData = dataService.find(editId); 
    request.setAttribute("editData", editData); // For the edit form. 
    List<Data> allData = dataService.list(); 
    request.setAttribute("allData", allData); // For the table/list of all data. 
    request.getRequestDispatcher("/index.jsp").forward(request, response); 
} 
+0

ありがとうあなたはこれは良い解決策だと私は間違いなくこれを試してみてお知らせします。 – Abubakkar

+0

これは完璧に動作します! – Abubakkar

+0

ようこそ。 – BalusC

5

私はページに目に見えないIDを追加します。データがデータベースに新規である場合(ID =不明)は、IDを挿入して作成し、そのIDでページを更新します。あなたはそれがIDであるかどうかを知ることができます!=不明なので、挿入する必要はありません。データが変更されていない場合は、あなたもアップデートを行う必要はありません...ここで

+0

あなたは、より良い方法を指摘したり提案したりできますか? – Abubakkar

+0

私はサーブレットに慣れていないのですが、恐れています。私が書いたのは、普通の古いJavaとデータベースを使って直面している典型的なシナリオでした。私はあなたがそのアプローチを採用することができると思います。サーブレット・テクノロジーにこれを行う組み込みの機能がいくつかあるかどうかはわかりません。 – Fildor

+1

Fildorの提案はそれを行う方法です。ページのレコードのデータベースIDを非表示フィールドに含めます。ユーザーがまだデータを送信していない場合は、-1または0でなければなりません。データを挿入する要求を処理すると、新しく挿入された行のデータベースIDが取得され、次回にページに追加されます。ユーザーが再度フォームを送信すると、IDを使用して詳細が更新されます(これはユーザーが期待するものです)。あなたのフォームにGETではなくPOSTを使用してください。リフレッシュするとデータが再送信されることをユーザーに警告します。 –

0

<%@page import="java.util.*"%> 
<%@page contentType="text/html" pageEncoding="UTF-8"%> 
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 

<%! 
//This List is just for demonstration purposes 
List<String> names = new ArrayList<String>(); 
%> 
<% 
if(request.getParameter("name")!=null){ 
    names.add(request.getParameter("name")); 
    session.setAttribute("nameList", names); 
    //Here you put your database insert code 

    //Whenever the code execution reaches this line , 
    //then it means that you have a new page submission 
    //and not a refresh or f5 case 

    response.sendRedirect("index.jsp"); 
} 
%> 

<!DOCTYPE html> 
<html> 
    <head> 
    </head> 
    <body> 
     <form action="index.jsp" method="post"> 
      <input type="text" id="name" name="name"/> 
     </form> 
     <p> 
      <table> 
       <c:forEach items="${nameList}" var="element">  
        <tr> 
         <td>Name: <c:out value="${element}"/> </td> 
        </tr> 
       </c:forEach> 
      </table> 
     </p> 
    </body> 
</html> 

トリックはresponse.sendRedirect("index.jsp");であり、最も簡単なソリューションです。これにより、すべてのリクエストパラメータがnullになります。 f5またはrefreshがヒットした場合、ifは決して実行されません。通常の送信の場合は、ifが実行され、response.sendRedirect("index.jsp");に電話します。あなたが本当にする必要があるすべてがある

要約

、:

1)if(request.getParameter("name")!=null)

2を確認してください)上記の場合はtrueで、データベースは

3を挿入します)上記の場合、response.sendRedirect("index.jsp");

真であります

UPDATE

if(request.getParameter("name")!=null){ 
    DbUtility.addNameToDb(request.getParameter("name")); 
    ArrayList<String> currentList = DbUtility.getAllNamesFromDb(); 
    session.setAttribute("nameList", currentList); 
    response.sendRedirect("index.jsp"); 
} 

これら2つの方法を実装するだけで済みます。 addNameToDb(String)はデータベースにinsertを作成します。 getAllNamesFromDb()は、データベースのエントリを表すArrayList<String>オブジェクトを返します。

+0

ご回答いただきありがとうございますが、データベースにエントリを追加したいと思います。私がしたいことは、データベースのフォームを使用して1つのエントリを作成した後、すべてのエントリ(名前がプライマリキーであると仮定します)私が使ったのと同じ形の下に表示されます。今は表示されていますが、リフレッシュすると重複したエントリも見つかります。 – Abubakkar

+0

論理の私の更新を参照してください – MaVRoSCy

+0

私はそれを試みますが、私はそれが '要求'スコープにある必要がある私のデータを格納するために 'session'スコープを使いたくありません。 – Abubakkar

0

のURLパターンにマッピングされているservletに私はPRGP(ポストリダイレクトがパターンを取得しますが)、このために行くための方法だと思います。 Spring Web Flowを使用している場合は、FlashScopeがあり、ポストゲットリダイレクションの後に保持したいデータを置くことができます。このアプローチを使用するだけで、複数の編集IDを保持することができます。

関連する問題