2

I am using jsp and servlet, and method type as POST in jsp. But after inserting record refreshing the page again cerate new record. Can any one help me to use alternate of header in php .

Or any other solution, i have tries a lot but my issue is not solved so again posting this question.

Thanks

Ankit Kumar
  • 393
  • 2
  • 3
  • 18
  • Can you show us what did you mean with "header in php"? A big number of people have knowlege in jsp, though not small knowlege in php. – Reporter Aug 15 '13 at 10:59
  • my friend is working on php, he shows me the solution in php as- after insert query performed , page is redirected as header("Location:abc.php?message=1"); – Ankit Kumar Aug 15 '13 at 11:09
  • As concerned as knowing PHP , I am a noob in php. I was just interesseted to see an example -say as a keyword or clue- to do more resaerch. – Reporter Aug 15 '13 at 11:56
  • @AnkitKumar the previous version of the answer contained false information. Please review the updated answer I have verified all the examples. – linski Aug 20 '13 at 22:32

3 Answers3

4

Assume There are 3 pages

(1) Registration.jsp : Which is having the registration form < form action="AddUser.jsp" > and where user can enter the data.

(2) AddUser.jsp (OR better it is servlet) : which accept the data submitted by "Registration.jsp".

(3) Welcome.jsp : after registration, this page will appear.

So in page2 (AddUser.jsp) write the following code

  • Accept the registration form variable from "Request" object
  • Make DB connection and store the value into the database
  • perform response.sendRedirect("Welcome.jsp")

Since browser URL will be changed. so if user will refresh the page then also it will not create the duplicate entries.

Rakesh Soni
  • 10,135
  • 5
  • 44
  • 51
  • step 3.3 won't work if the webapp is deployed with context path - see update in my answer – linski Aug 15 '13 at 12:34
  • 1
    If the URL is not absolute , it redirects relative to the current URL. If the URL starts with / it redirects relative to the context root, Else it redirects to the current url – Rakesh Soni Aug 15 '13 at 12:43
  • Exactly! "If the location is relative without a leading '/' the container interprets it as relative to the current request URI. If the location is relative with a leading '/' the container interprets it as relative to the servlet container root." Upvoted. – linski Aug 15 '13 at 12:56
  • if Welcome.jsp is not in the webapp root that is. More context is needed for such statements, I withdraw my first comment. – linski Aug 15 '13 at 12:57
2

If I understood you well:

  • browser sends POST /insertdata to www.mypage.com
  • data gets inserted, server responds with OK 200
  • when user refreshes the page, the process is initiated again which inserts duplicate data

You can avoid it with redirection like this:

 response.sendRedirect("http://www.mypage.com/insertsuccessful");

Place this code at the end of your servlet/JSP handling the POST. This is what will happen:

Note: the status code (302) and location header get set automatically by the sendRedirect method.

Now when user refreshes the page it will be the www.mypage.com/insertsuccesful which won't POST the duplicate data anymore.

You can also make www.mypage.com/insertfailed page, and redirect to it if you catch an exception in your POST handler.

tutorial

update 2

To follow up on @JB Nizet's comments (thx for being careful), let's suppose that your webapp is deployed with a context path, e.g. www.mypage.com/webapp, and review the following scenarios:

  1. the URL of your page for insert (http://www.mypage.com/webapp/insertdata?redirectOnOK=/insertsuccessful) contains a query string parameter redirectOnOk which defines where the client will be redirected upon successful insert ->http://www.mypage.com/webapp/insertsuccessful
  2. webapp employs URL rewriting
  3. you are using Session for login control

1st scenario

The first thing to notice is that http://www.mypage.com/webapp/insertdata?redirectOnOK=/insertsuccessful is not a valid URL. It is not valid because you don't expect a slash (/) after a question mark (?):

scheme://domain:port/path?query_string#fragment_id

A valid URL can contain english alphabet letters, numbers, dot (.), hyphen (-), underscore (_) and a tilde (~). Some other punctuation characters are reserved and every other character (and sometimes even the reserved characters) must be URL-encoded:

http://www.mypage.com/webapp/insertdata?redirectOnOK=%2Finsertsuccessful

Since a reserved character slash (/) isn't expected after a reserved character question mark (?) it must be encoded. This is the solution for the first scenario:

String redirectRelativeUrl = new URLDecoder().decode(request.getParameter("redirectOnOk"),"UTF-8");
response.sendRedirect(request.getContextPath() + redirectRelativeUrl)

If you are using non english alphabet charaters when forming the query string the keys and values should always be URL encoded:

String safe = new UrlEncoder().encode("ž@Š","UTF-8");

2nd scenario

URL rewriting is a mechanism for mapping URL's based on regular expressions. In other words, the browser requests:

http://www.mypage.com/webapp/resource/someName/12

If under the context root there is a JSP page resource.jsp, then a URL rewrite rule can be defined to map the above to:

http://www.mypage.com/webapp/resource.jsp?name=someName&count=12

So if you are redirecting programmatically from your serlvet/JSP you must also apply the (outbound) URL rewrite rules. In the above example the inbound rules are:

  • /someName/12 -> ?name=someName&count=12
  • /webapp/resource -> /webapp/resource.jsp

The outbound rules need to be applied when redirecting programmatically from server:

  • name=someName&count=12 -> /someName/12
  • /resource.jsp -> /resource

The rules are presented this way for the sake of simplicity, and are not regular expressions actually. The solution in this case is:

response.sendRedirect(response.encodeRedirectURL(request.getRequestURI() + "?" + request.getQueryString())
  • getRequestURI returns /webapp/resource.jsp
  • getQueryString returns name=someName&count=12
  • encodeRedirectURL has input /webapp/resource.jsp?name=someName&count=12
  • the browser gets redirected to /webapp/resource/someName/12

3rd scenario

Initiating a HTTP session is really simple:

Session session = request.getSession();

this has the consequence that it sets a JSESSIONID cookie:

jsessionid=9ADABC18DB58C4DA99896C6261D2DD25

If the browser has disabled the cookies, upon programmatic redirect the user won't be authenticated anymore, meaning that he will have to login again. The solution in this case is:

String relativeRedirectUrl="/insertSucessful";
response.sendRedirect(response.encodeURL(request.getContextPath() + relativeRedirectUrl));
  • encodeURL appends ;jsessionid=9ADABC18DB58C4DA99896C6261D2DD25 to input if cookies are disabled
  • the browser gets redirected to /webapp/insertSucessful;jsessionid=9ADABC18DB58C4DA99896C6261D2DD25

Conclusion

  • Errors that emerge from invalid URL syntax are hard to debug, and very hard to notice. It is good practice to log URL's before redirecting to them.
  • It is better to use relative URL's because then you can deploy your webapp's on multiple servers with different domain names, and on different context path's without changing the source code or values in some property files.
Community
  • 1
  • 1
linski
  • 5,046
  • 3
  • 22
  • 35
  • 1
    Why not simply use `response.sendRedirect()`? – JB Nizet Aug 15 '13 at 11:35
  • with no need to set the Location header then, exactly! thx, will update in a sec :) – linski Aug 15 '13 at 11:36
  • 1
    You should not hard-code the host and context in the URL, and you should use encodeRedirectURL is URL-rewriting must be supported: `response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + "/somePage"))` – JB Nizet Aug 15 '13 at 11:47
1

I think you have already got the most important part of the answer with what "linski" and "Rakesh" have detailed. I am up-voting them both for that.

I would however like to point out one thing.

What is mentioned in both answers is the PRG(Post-Redirect-Get) pattern that has been around for sometime. This would solve most of the duplicate post issues but one area where it fails is when there is 'Server lag'. If your backend work has some noticeable lag time before initiating a redirect, a user can potentially initiate multiple post action by clicking the submit button(assuming you are using a button for posting the data) again.

One simple front-end solution for this would be to disable the button(or whatever you are using to initiate the post action) after the first click temporarily.

You could of-course get creative on the backend to insure that the same user is not issuing duplicate posts before a redirect occur, but that would require more work.

PJR
  • 443
  • 4
  • 9