Our application is developed with Struts2 and run on a JBoss server.
I have the requirement to develop a JSP page where the content of a grid will be displayed using <s:iterator> and <s:property> tag from a List (say ArrayList of person object) which is stored in session.
Now users can Add/Update/Delete the row(s) content generated by iterating session List.
For example if I have a list of size n of Peron object, and in JSP it's displayed as
name age contact
name1 24 1234456
name2 30 45654634
and so on...
Users can Add/Update/Delete any number of rows and then finally can save.
How to approach this requirement ?
This is dangerous... let's say that the power goes away, the session is not persisted everywhere.
So instead of updating the session n times and finally saving the data at once, you could simply save the data n times. But the requisite was thought to prevent too many access to the database (may be relevant with thousands of users), then you can use AJAX and Struts2-JSON-plugin like this:
Create an AJAX Action (in a <package> that extends="json-default" and return a <result type="json">), that implements SessionAware, and receives a row from the JSP;
in the execute() method, read your List from the Session Map, add the new row, then return SUCCESS;
in the JSP, create a binding to call your AJAX Action (a click of a button in the row, the onblur event, whatever you like).
Add a button to call another Action (AJAX or not, but it should implement SessionAware too) to save the data in the database. That action will simply read the List from the Session Map and save it in the database.
This way the user can change page, coming back and finding all the data previously entered, and you will avoid a lot of POSTs of the entire page (AJAX + JSON is a lot lighter).
Related
I want to make a checklist webpage in jsp page. I am using struts2 tags in my jsp page. I want when my jsp first loaded the check box should automatically populated based on the value which comes from database. And when a user manually check or uncheck the check box something should get stored in the database, so that when another user access the same URL he can see the same state of check box. I don't want to use submit button.
Please help me how to implement it....!!!
Thanks in advance
Create String variables in your Struts2 Action files and also getters and setters. Set these variables in the execute() method (or the method you are using in your action class) with true or false values fetched from the database.
Then you can access them like this
<s:property value="varname"/>
You can set variables in your jsp like this
<s:set var="varname" value="varname"/>
Then check checkboxes like this
<input type="checkbox" <s:if test="#varname == 'true'">checked="checked"</s:if>/>
To set the values back to the database without submitting the form you will have to make an ajax call. Check out JQuery ajax() function. You will have to create a url with the parameters and values that will be mapped onto your corresponding variables in your action class. You can use these values in your action you specified in the url to write them to the database
I initially wrote a .jsp connected by Struts 1.1 to pull some data from a database using scriplets:
<% Map<String, myObject> map = MyClass.returnMap();
for(Map.Entry<String, myObject> entry : map.entrySet()) {
myObject element = entry.getValue();
out.println("<tr>");
out.println("<td><input type=\"checkbox\" name=\"objects[]\" value=\"" + entry.getKey() + "\"/>" + entry.getKey() + "</td>");
out.println("<td>" + element.property1() + "</td>");
out.println("<td>" + element.property2() + "</td>");
}
%>
So I end up with a table with a checkbox, object name, and two of the element's properties as the columns, with a row for each entry in the Map returned by returnMap().
Now, I want to be able to check however many checkboxes inside the generated table, and then click a button to send a list of all the checked checkboxes to a servlet to perform some server-side calculations depending on the checkboxes selected.
One problem is that the said "submit" button is outside the table, in a separate div (used for a fixed position header). Could I just wrap a form around the entirety of the div containing the button, and the table?
I am starting out in web development, and have done some tutorials on Servlets and I understand the basic concepts. I have seen that it's generally bad practice to use scriptlets for business logic in the jsp, so I am considering generating the table through my Servlet instead. However, I also want to be able to use the elements generated by the Servlet in another Servlet method (if that makes sense).
My thought process was:
1) .JSP loads through Struts
2) .JSP receives table from Servlet
3) When submit button is clicked, sends list of checked checkboxes back to the Servlet
4) Servlet uses list of checkboxes and performs some business logic
5) .JSP refreshes with updated table
Is this a viable process? Or is there a better way to do this?
I have to access the .jsp (through Struts), not the servlet url most of the tutorials use
I suggest to avoid Scriplet instead use JSP Standard Tag Library and Expression language that is easy to user and less error prone.
Map.Entry contains getKey() and getValue() methods to access key and value from Map Entry.
Simply set the return value as request attribute in Servlet and then you can access it in JSP using JSTL.
Sample code:
Servlet:
request.setAttribute("map",MyClass.returnMap());
// forward the request to the jsp
JSP:
<c:forEach var="entry" items="${map}">
<c:out value="${entry.key}"/>:<core:out value="${entry.value}"/>
</c:forEach>
read more...
Struts1 is rather outdated now and is officially no longer supported by Apache foundation. From Apache Struts site : The Apache Struts Project Team would like to inform you that the Struts 1.x web framework has reached its end of life and is no longer officially supported. So if you are beginning with it, you should considere using another framework such as Struts2 or Spring MVC.
But the resources are still present and you should use Struts 1 User Guide.
So you should have one Action for displaying the JSP. In the JSP, the form must include all the input fields **and* the submit one (possibly across many divs). You should have another Action to treat the inputs and an ActionForm to carry the data between first Action and the JSP at render time, and to give the input values to the second one at submit time.
Do not forget that Struts1 comes with a taglib that could help you to avoid as much scriptlet as possible from you JSP, but IMHO, you should use JSTL when possible instead of Struts specific tags when they do same thing : migration will be easier if you later want to use another framework.
Normally it is the job of second action to call business methods to do intelligent things with input values, and it is recommended to do a redirect after a submit (POST) to avoid submitting again if user refreshes its browser or clicks on back arrow button of browser.
This question is in continuation of Forwarding the request from one jsp to another jsp with all request parameters?. For the convenience of user, will explain the scenario and new query on that .
i have this scenario. User enter some stuff on jsp form in browser and submit. In servlet i process the request and show the jsp page1 to client which has just continue button. Now on click of continue, i want to forward this request to another jsp page2 with all request parameter present on page1. basically i want to get all request parameters which were present in first request on page 2 also. As per replies i can go for hidden variable which i agree. Now a question this.
EDIT
if i have customer info object in request, how will submit it as hidden field. I will get customer object as string in second jsp. Right? Is there a way i can get it as customer object in request instead of string object?
Store it in Session scope and retrieve where ever u want to get it back, on the first call of servlet , just put it in session and later on third jsp just get it from the session
I have a jsp search page (Search.jsp) and a result page (Result.jsp), both of them can choose search criteria. and then passed the parameters to a java controller file (Controller.java) to build a query string and performs query searching. The query string and searched results will be passed to Result.jsp for displaying.
Currently I use servletContext to remember the processed query string, and if users use Result.jsp to select search criteria, Controller.java will append such criteria to the existing query string. If I do a few searches using Result.jsp. For example, query string would display ((Query1) AND Query2) AND Query3 on the Result.jsp page. Then using the browser's back button to go back to the previous display page. For the same example, query string displays (Query1) AND Query2. Then if I do search again. The query string (((Query1) AND Query2) AND Query3) AND Query4 would be used. I know this is expected with my current implementation since Result.jsp does not do any modification with the processed query string.
However, I would like when user uses the browser Back button, for example, query string displays on the page as (Query1) AND Query2, and perform search, the query string should be ((Query1) AND Query2) AND Query4 in which the query string is build based on the current displayed query string on the Result.jsp page plus the current selection. How can I do that? It sounds quite simple but I have tried several ways of using the in Result.jsp to update the query string, but still couldn't get it right. Therefore I am wondering maybe my approach of using <c:set> is wrong. I would like to hear your suggestion. Thanks in advance.
Currently I use servletContext to remember the processed query string
Do you realize that the ServletContext is shared among all users/sessions who are visiting your webapplication? Once visitor X modifies it, the changes are reflected for all other visitors. Don't you rather want to store it in the HttpSession to keep the data visitor-specific?
See also:
Servlet lifecycle and multithreading
I want to use back button for some reason
I really have a hard time in understanding your functional requirement (the some reason part). But at least, since you'd like to have the back button to work properly, you'd like to use idempotent requests here. So, where applicable, replace POST by GET.
Whenever you'd like to refire a real HTTP request on the server instead of loading the page from browser's cache, you'd like to instruct the browser to not cache the pages by adding the following headers to the response:
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
You can do that in your controller or some Filter covering the url-pattern of interest.
See also:
Make sure that a webpage is not cached across all browsers
Webbrowser caching tutorial
My title maybe confusing so please read on. I'm using the following technologies if you may. Spring, Hibernate, JSF (RichFaces), MySQL, Internet Explorer.
I have a List of items which is displayed in a RichFaces datatable like so:
item a
item b
item c
item d
item e
On the same page I have the following buttons: search, edit, add, delete and new.
When an user enters a search string, e.g. "item c", and press search button, then it displays a list of matching items, e.g:
item c
When the user presses the new button, the request will be redirected to another page using:
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.getExternalContext().redirect(page + ".jsf" );
When the browser back button of IE is been pressed on that page, the page displays "web page expired". What is this and how can I avoid this?
web page expired
You will get this error when you're trying to obtain a non-cached POST request from the browser history. This behaviour is fully expected. To fix this "problem", you need to either turn the cache on or to replace POST by GET.
Enabling the browser cache is actually easy: just remove the Cache-Control: no-cache and related headers from the HTTP response of the POST request in question. The enduser will then only get a warning dialog that the POST data will be resent to the server, which in case of fully non-idempotent requests like placing an order or deleting an item is really not desirable. Replacing POST by GET is then a better solution. Getting searchresults (like as Google does) should really be done by GET.
Replacing POST by GET isn't easy in JSF prior to version 2.0. Best what you can do is to fire a redirect after the POST and pass the data of interest as request parameter which you retain from #{param} as managed property (more recommended) or store the data of interest in session scope (not recommended). A completely different alternative is to replace the JSF <h:form> by a simple HTML <form action="searchresults.jsf"> and do the search job in a #PostConstruct method in the backing bean associated with searchresults.jsf, after the submitted query has been gathered as managed property or from request parameter map.