0

EDIT: I have posted a somewhat shorter and revised question here: Java web development: transfer control from one servlet to another while passing the request object (Version 2)

As more or less a beginner at Java web development, I’m unsure about how I should structure the flow between servlets/pages when a form is submitted (POST). It’s an elementary issue, I suspect this may be an easy question to answer for the experts. (Still, my book and some googling didn’t deliver a clear answer.) My question is a bit long, and that's because I want to make it clear where I'm coming from. Thanks for you patience.

Let’s say we have two servlets A en B, with each having its ‘own’ .jsp-page; let’s call those pages a.jsp and b.jsp respectively. Now as long as there are no forms on either page (i.e., no POST method used), it’s clear how things should go. That is, before any .jsp-page is shown, the corresponding servlet is activated, doing some preparation for the .jsp-page by setting the relevant data elements (most notably, as attributes of the request object) that the .jsp-page needs, then forwarding the request object (etc.) to the .jsp-page, which then actually displays the page with the data. So for example, a link on page a.jsp may link to the servlet B, and on clicking that link a GET-request for servlet B is triggered, which then does some preparation (setting some request attributes), before forwarding to its ‘own’ .jsp-page (i.e. b.jsp).

But now let’s assume that page a.jsp displays a form with a submit button, method=”POST” and action=”B”. Then yes, servlet B is activated, and this servlet has to determine whether the data entered by the user is valid. If the data is in fact valid, we can simply forward to b.jsp, no problem there. But what if the data is NOT valid?

In that case, we obviously want to show a.jsp (the form page) again, with the data that the user entered the first time still present. One way to achieve this, is to simply have servlet B forward to a.jsp (thus bypassing servlet A). However, there is a big problem with that: the URL shown to the user, in the address bar, will still read “……/B”. So the user will see the correct page (i.e., a.jsp, containing the form), but with the wrong URL (/B). So for example, if we take “Register” and “ThanksForRegistering” instead of “A” and “B”, the user will see register.jsp – but with URL “……/ThanksForRegistering”! Not good.

And calling ‘include()’ instead of ‘forward()’ on the request-dispatcher doesn’t seem to work either. If we do that, not only does it result in a GET-request (as opposed to the POST-request we want), but we actually lose the whole (original) request-object with its attributes (which we need, after all, to re-populate the form). At least, that’s what my own experimentation seems to show. So using ‘include()’ doesn’t seem like a viable option at all.

Another obvious idea is to have "action=A" (instead of "action=B") for the submit. Then the servlet A itself can handle the validation, and if validation fails it can simply forward to a.jsp again, no problem. BUT then what if validation succeeds? Then we want to show the follow-up page b.jsp, but that page may well need the attributes from the original request-object (from the form-submit) again; for example, to have the user check that his entered data was in fact all correct. So basically we have the same problem as before, but with the roles of A and B (and their respective .jsp-pages) reversed. So this doesn't seem like a real solution either.

And I don’t see any other alternatives.

So basically, I’d simply like to be able have one servlet give control back to another servlet, but with the request object being passed from the former to the latter servlet. Or, if that’s not possible, I’d want to be able to forward from servlet B to a.jsp directly, but with the correct URL shown to the user. Or any other way to accomplish what I want.

Many thanks.

Community
  • 1
  • 1
Holland
  • 395
  • 9
  • 22
  • 1
    Indeed a little bit long and hard to get the problem. Maybe posting code would help us. – Pascal Heraud Dec 30 '16 at 14:40
  • Furthermore, don't you use any web framework ? They propose solutions for making redirects, flows, ... – Pascal Heraud Dec 30 '16 at 14:40
  • I think you need to read up on redirects. What you can do is, in your original scenario if validation fails in servlet B. You send a redirect to A. Ref: http://stackoverflow.com/questions/6175722/redirect-from-servlet – Mukul Goel Dec 30 '16 at 14:43
  • @Pascal Thanks. I'm simply using NetBeans... this is course work (school). But I suppose it should be possible to do what I want without a framework. Also, I'll edit to add a less verbal version of my issue (may take a few hours though). – Holland Dec 30 '16 at 14:45
  • @Mukul Goel. Ah yes redirect, I actually tried that yesterday as well, but I didn't manage to pass the request from one servlet to another. (I may have confused include() with redirect in my question actually, but in any case neither seemed to accomplish what I want.) But I will now read up on redirects. – Holland Dec 30 '16 at 14:48
  • @Holland been a long time since used plain servlets but a redirect should work. I suggest sharing the code you tried. – Mukul Goel Dec 30 '16 at 14:56
  • @Loc Within a few hours I should be able to add a less verbose version with some code, so please do check back later. – Holland Dec 30 '16 at 14:58
  • 1
    You should let the form in JSP A submit to Servlet A whose doPost() should in turn decide whether to forward back to JSP A in case of validation errors, or to send a redirect to Servlet/JSP B. This approach is outlined among others here: http://stackoverflow.com/q/3541077, which I think is pretty much the canonical Q&A you're looking for. Your concrete mistake is thus that you're submitting to the wrong URL. You should basically submit to exactly the (same) URL which you'd like to see in browser's address bar in case the validation has failed (the correct term for that is "postback"). – BalusC Dec 30 '16 at 15:08
  • @BalusC Many thanks, yes I understand, I'm just going to need to figure out response.redirect, which is what I'm going to do now. – Holland Dec 30 '16 at 15:16
  • @all - See my new follow-up question here: http://stackoverflow.com/questions/41399411/java-web-development-transfer-control-from-one-servlet-to-another-while-passing – Holland Dec 30 '16 at 16:28

2 Answers2

1

I think that the assumption that there has to be one page per servlet is causing the problem here....have one servlet which based on input redirects,forwards or includes a particular page....you dont really need to always invoke a different servlet for a page.....you can have a single front controller with a view resolver the combination of which will redirect or forward to a page.

prashant
  • 1,382
  • 1
  • 13
  • 19
  • +1 for suggestion of using a single servlet acting as a router. This is sort of like implementing your own router. But I would argue that if your aim is to implement a single servlet for this purpose, then it should always forward and act like a behind the scenes router and not do any processing. – Mukul Goel Dec 30 '16 at 14:53
  • Thanks @phrasant, yes I think you may be onto something. However, suppose that, if validation succeeds, I want to go back to the home page, and have some of the entered data shown on that homepage (i.e., I still need the attributes of the request-object). Surely it would be strange to have the homepage (the .jsp) shown with the URL of the Register page (i.e., the form page) in the address bar. But that's what would happen if I simply forwarded from the Register servlet to homepage.jsp. – Holland Dec 30 '16 at 14:54
  • @MukulGoel Correct mukul...all business logic should be implemented by services invoked from the servlet...and based on the service response...the servlet would then decide using the view resolver to decide which view to be displayed... – prashant Dec 30 '16 at 14:58
  • @Holland....if validation succeeds the entered data would be set in the request object by your routing servlet before you redirect to the home page........To conclude based on the logic in your servlet data would be passed from one page to another by your routing servlet..... – prashant Dec 30 '16 at 15:00
  • @phrasant Yes, and the vital issue here is just HOW do I redirect from servlet to homepage in such a way that not only the request object is passed on, but also the correct URL (in this case, "Home") appears in the address bar? I did try using redirect (forgot to mention it in the question), but it didn't seem to do what I wanted. – Holland Dec 30 '16 at 15:04
  • response.sendRedirect should work.....what issue are you facing – prashant Dec 30 '16 at 15:06
  • Can you post what you are doing...here ?? – prashant Dec 30 '16 at 15:08
  • OK. I'm going to to try response.sendRedirect again, will read a bit more about it, try it out, and (time permitting) will report back later today. – Holland Dec 30 '16 at 15:08
  • Couldn't make sendRedirect work, see my follow-up question: @all - See my new follow-up question here: http://stackoverflow.com/questions/41399411/java-web-development-transfer-control-from-one-servlet-to-another-while-passing – Holland Dec 30 '16 at 16:29
-1

You can use filters to achieve the same thing or think of setting attributes in HttpSession if validation is successful and retrieve the data in all the pages whenever it is required. session.setAttribute("object", object);

I hope this is what you are looking for.