I have done some research, and majority of the examples I have found use forms (obviously for user input) to collect data which is then passed to another JSP page through the request object.
My question is: Is it possible to pass a parameter between JSP pages if the parameter hasn't been set in HTML <form> tags?
There are a few ways to pass information from one JSP page to another.
1. Hidden values.
Simply write the data to an input field within a form with the type 'hidden', e.g.
<input type="hidden" name="mydata" value="<%=thedata%>">
Data written thus will get posted back when the relevant form is submitted. This can be a useful way to 'carry along' information as the user fills out a series of dialogs as all state is user side and the back and forward buttons will work as expected.
2. URL writing.
Attach parameters to URLs in links on the page, e.g.
<a href="another.jsp?mydata=<%=thedata>>Go!</a>
This also maintains the state with the client while removing the need for a form element to be submitted.
3. Cookies.
Should speak for itself.The state is still user side but is now handled by a cookie. More fragile in some ways since some people disable cookies. Also the back and forward buttons may do unexpected things if you are not careful
4. Server side (session)
Finally you could store the data in a session variable on one JSP and retrieve it on the next, e.g.
session.setAttribute(String key, Object value)
and
session.getAttribute(String key)
Here the state is kept server side which has some benefits (the user can browse away and return without losing his place, but tends to make the back and forward buttons in the browser a bit unreliable unless you are careful. Also the value is available to all pages.
It does however have the advantage that the information is never sent to the client and is thus more secure and more tamper proof.
There's no way a JSP page can tell the difference between a manually constructed GET url, e.g.:
Go to the next JSP page, versus something like:
<form method="get" action="/foo.jsp">
<input name="bar" value="baz">
</form>
Either way it can be accessed through getParameter or getParameterValues
Is that what you're asking?
You usually pass data between servlet/JSP or JSP pages in scoped attributes (in request, session or application). E.g. request.setAttribute("key", data) can set "key" attribute in one JSP, and request.getAttribute("key") gets you this data in other JSP (if multiple JSPs are processing same request).
It is possible to create fake parameters by wrapping your request, and overriding getParameter and similar method, if that is what you really need.
Update: my answer is talking about passing data between several parties which all process same request. This may or may not be what you want, as your question isn't clear.
Related
This question already has answers here:
Design Patterns web based applications [closed]
(5 answers)
Closed 6 years ago.
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.
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.
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.
I have a JSP page that displays a list of items, each one accompanied by a form that allows the user to edit the corresponding item's data. The changes made by the user are processed by a servlet.
Right now, the JSP page produces invalid HTML, because every input of every form share the same id. I can add some suffix to every id, but then the code at the servlet side that gathers all the parameters is not as simple as calling request.getparameter("constantValue") anymore.
I can use request.getParameterNames() and guess which input belongs every id to by its prefix, but I think it looks ugly and it's probably bad code.
Am I missing a better solution?
Right now, the JSP page produces invalid HTML, because every input of
every form share the same id
Id's are not considered here, as request.getparameter("Name") requires the attribute name . So make sure that you have unique name for the inputs in various form.
Several forms in a JSP page: how to avoid duplicated ids and tedious
parameter processing at the same time?
I believe you have submit button for each form. so that doesnt matter if you are not submitting to the servlet
This is probably quite a simple, newbie question for seasoned Web developers, which I am not, and googling around does not help.
I have a very simple webapp hosted on Heroku, the code of which is here. It has two JSP pages, one index, one with the validation results, nothing fancy. The two JSP pages are here (index.jsp) and here (results.jsp).
The problem is with the validation servlet: it is a POST, and is triggered, when using the app itself, via an input button in index.jsp. But I have tested that it will also work if I call the servlet directly... And I don't want that.
Is there a way to reliably ensure that this servlet may only be called when coming from the index page (and send a 403 otherwise)?
One way I've used is to have the input form on index.jsp include a hidden field which contains an md5 hash which the results.jsp can also calculate. I use the md5 hash of the client machine's IP address concatenated with a shared secret phrase.
I guess for a given client IP address the hash is always going to be the same so you could also salt it with another value (like current time) which is passed in another hidden field for inclusion in the calculation by results.jsp.
You could generate a fingerprint (for example UUID.randomUUID()) when the first page is loaded and save the value in the current session.
When you post the result to the validation servlet you include that fingerprint as a hidden field and check that the fingerprint exists on the session.
There is no way you can be 100% sure of that. Eventualy you can check the referer but it's possible to forge it. You can also set a cookie when loading the index.jsp and check the value in the servlet. But it's also possible for someone to load index.jsp to retrive the cookie and then use it to post on the validation servlet. Same think with an input hidden with a hash.
Designing and processing a form where the user can add an arbitrary number of new input fields is very tedious without using JavaScript.
Currently I am doing the following: using two different submit buttons in a form, one for adding a new input field and one for submitting the form which results into a database request.
the used method is POST
for adding new input fields I would like to use GET but since two methods in one form is not possible I have to do it in the POST request.
making this for one type of input field is rather easy, but when you need to do this for sub-forms (some groups of input fields in the same form), this becomes not only tedious, but also error-prone!
I am not satisfied, is there a more intelligent way to realize this without starting to write a lot of processing code and doing redirection or at least ease the implementation to reduce the error risk!
Also, maybe there is a solution provided by Java to solve this generically elegant, since I am using Java Servlets.
With JavaScript turned on I would offer a separate solution, I am only concerned with the fall back solution, this is not the normal case.
See, working without JavaScript severely restrict your abilities: you have to rely upon the standard HTTP request/response cycle. In other words, you have to rebuild a new page (adding some input field) and send this new page each time - there's no workarounds.
Here's how I would implement it:
<form action="/path/to/action" method="post">
<input name="param_a" />
<input name="param_b" />
<button type="submit" name="next_input" value="param_c">Add a field</button>
<button type="submit" name="submit">Submit your form</button>
</form>
... then within the server-side code I'd just check whether next_input param is sent or not. If sent, its value will be used to get the control which is to be added - and give the corresponding value (param_d, for example) to the next next_input.
UPDATE: but I just can't help wondering is this really necessary. Usually we design for 'No JS' cases when these pages are typical landing pages (scanned by search robots). Thinking about some users that will go to your page without JS enabled, yet willing to use it with all pretty things enabled... well, it's not very cost-effective, to say the least. )
I am working on JSP-servlet application and now I am programming a page which edit information about registrars.
The senario is that there's an ArrayList I send form servlet to JSP page when I load the page. The ArrayList contains information about groups the registrar belongs, the ArrayList is resulted after making multiple SQL statements. When user try to edit some fields and make one required field empty and submit the form, the servlet makes validation and return error to edit page.
The problem I face is that all the groups I sent in the first time fly in the sky. So I have to make connection to DB again and make multiple queries to get the groups again and send it back to JSP page.
Is there's another simple way to make arrayList stable in JSP page ?
EDIT
Here's the code which I make the scope of the ArrayList in the session.
<c:set var="userGroups" value="${userGroups}" scope="session"></c:set>
Either store it in the session or just live with it. I really don't see any issues with that. If the concrete problem is that you have to copypaste the same code again or that the whole code is ugly to have in a Servlet class, then just refactor/hide that into an useable DAO class which you import/call/reuse in the Servlet the usual Java way.
Update: as per your update, this doesn't make sense. You just need to change your servlet code from
request.setAttribute("userGroups", userGroups);
to
request.getSession().setAttribute("userGroups", userGroups);
You don't need <c:set> for this.