Converting an ArrayList<someObjects> to an HTML table - java

I have a couple of ArrayLists with variable length and sometimes null. This ArrayList contains a bunch of objects.
The table should have columns based on (some) attributes of the object. And the table should be displayed on a jsp.
I have two ideas, one is to use a JSTL tag the other is to use JavaScript. And library suggestions are welcome.

JSTL is the standard, preferred way (unless you need to load it via ajax, for example)
<table>
<tr><td>Foo header</td><td>Bar header</td></tr>
<c:forEach items="${yourRequestScopedArrayList}" var="obj">
<tr>
<td>${obj.foo}</td>
<td>${obj.bar}</td>
</tr>
</c:forEach>
</table>

JSTL is better,
Javascript you should avoid as much as possible ,
I am not sure how you are going to render datatable using java script and Collection
How to use jstl with collection that has been demonstrated by Bozho in the same thread.

Javascript doesn't have access to the Java objects that live (I presume) on the server. The server code can make the ArrayLists available to the JSP which can then loop over them with a JSTL forEach tag.
How you make the ArrayLists "available" depends on the framework you're using, but the plain servlet way is just setting an attribute from the doPost method.
request.setAttribute("list1", arrayList1);
The loop would be something like
<table>
<tr><th>Column 1</th> <th>Column 2</th> <th>Column 3</th></tr>
<c:forEach var="row" items="${list1}">
<tr><td>${row.col1data}</td> <td>${row.col2data}</td> <td>${row.col3data}</td></tr>
</c:forEach>
</table>

Related

Best way to display a java object that contains csv data in a JSP?

I have a jsp that gathers data from the user and passes that data to a servlet. The servlet uses that data to query an api and the response is a string object that contains csv data, which is forwarded to a search results jsp page.
In the search results jsp page I call the object. It's just a string of csv values and it looks bad on the page. I'm a total novice when it comes to web app development. Any idea the best way to parse the csv data in such a way that it looks better? Maybe into a HTML table? All I can find is info on parsing through a csv file, not an object with csv data in it.
I'm sure there's a simple way to handle this but after a whole day of combing the internet I need a little help where to look...
-----Edited to add sample data.
The data is returned to the jsp like so.
product_nbr,member_nbr,prod_cd,create_dt XYZ0000,000,777,2015-10-30
The first 4 fields are the headers and the data follows in line. I would like it to look like this..
(stackoverflow doesn't allow the table tag, but you really I just want to be able to display an HTML table on screen)
<table>
<tr>
<td>product_nbr</td>
<td>member_nbr</td>
<td>prod_cd</td>
<td>create_dt</td>
</tr>
<tr>
<td>XYZ0000</td>
<td>000</td>
<td>777</td>
<td>777</td>
</tr>
</table>
I recommend you to read this article:
http://www.journaldev.com/2090/jstl-tutorial-with-examples-jstl-core-tags
It shows you how to use JSTL in a JSP. You have to use the forEach tag like this, but before yoy have to parse your csv file into a array.
http://www.tutorialspoint.com/java/java_string_split.htm
String a = "product_nbr,member_nbr,prod_cd,create_dt XYZ0000,000,777,2015-10-30";
String[] b = a.split(",");
Este es un JSP de ejemplo
<table>
<tbody>
<tr><th>ID</th><th>Name</th><th>Role</th></tr>
<c:forEach items="${requestScope.empList}" var="emp">
<tr><td><c:out value="${emp.id}"></c:out></td>
<td><c:out value="${emp.name}"></c:out></td>
<td><c:out value="${emp.role}"></c:out></td></tr>
</c:forEach>
</tbody>
</table>

Combinate JSTL var with Java method

How can I use the Jstl attribute ${theDetail.id} from a Jstl foreach inside a java function? I have tried a lot, but nothing works.
<c:forEach items="<%= facade.getAllDetails() %>" var="theDetail">
// how to use ${theDetail.id} inside this java function
<c:forEach items="<%= facade.getSomeStuffById(...) %>" vars="theStuff">
${theStuf.name}
</c:forEach>
</c:forEach>
Never use scriptlet expressions inside JSP tags. In fact, never use scriptlets at all. The JSP tags are designed to use the JSP EL expressions. Not scriptlet expressions.
The way to write your code is, assuming facade is an attribute of some scope
<c:forEach items="${facade.allDetails}" var="theDetail">
<c:forEach items="${facade.getSomeStuffById('someHardCodedId')}" var="theStuff">
${theStuff.name}
</c:forEach>
</c:forEach>

JSTL - accessing cookies

Hello everyone,
I was just wondering whether it's possible to access all the stored cookies like this:
<c:forEach items="${cookie}" var="currentCookie" varStatus="lp">
<tr><td>${cookie[lp.index].key} </td></tr>
</c:forEach>
if not, is there any way I could somehow itterate over cookies and other array in one loop?
<c:forEach items="${cookie}" var="currentCookie" varStatus="lp">
<tr><td>${CurrentCookie.key} </td></tr>
<tr><td>${MyArray[lp.index].name} </td></tr>
</c:forEach>
Thanks for any suggestions,
Wrack
Yes you can interate over cookies using JSTL for each, its similar like iterating over a map.
Similar question Retrieving cookie and array values in JSTL tags

Concatenating JSTL

I have a HashMap in the controller:
HashMap<String, ArrayList<String> map = new HashMap<String, ArrayList<String>();
In the JSP page I want to access this through something like this:
<c:forEach var="list" items="${requestScope.list}">
<c:set var="testing" value="{requestScope.map}"></c:set>
<c:forEach var="anotherTesting" items="${testing['${list.item}']}">
<option><c:out value="${anotherTesting}"/></option>
</c:forEach>
</c:forEach>
Where list.item is a String but it is used for another process but I want it to be used to access the HashMap.
Is there a way to concatenate JSTL? Either map.key or map['key'] will do.
I guess simply this would work:
<c:forEach var="anotherTesting" items="${testing[list.item]}">
<option><c:out value="${anotherTesting}"/></option>
</c:forEach>
Notice the difference with and without quotes:
${testing[list.item]} is equivalent to testing.get(list.getItem());
${testing['list.item']} is equivalent to testing.get("list.item");.
Some Note:
You don't need to specify the scope to access the attributes, unless there is a conflict with the same name in different scopes. So, "${requestScope.list}" can be changed to ${list}, and "${requestScope.map}" can be changed to ${map}.
Please use a different name for var attribute of outer loop. May be listItem instead of list.
No need to set the map to a different variable. That <c:set...> is not needed. You can directly access the property of map attribute.
So, your loop can be modified to:
<c:forEach var="listItem" items="${list}">
<c:forEach var="anotherTesting" items="${map[listItem.item]}">
<option><c:out value="${anotherTesting}"/></option>
</c:forEach>
</c:forEach>
The code in ${...} is not JSTL but Expression Language. You don't need to c̶o̶n̶c̶a̶t̶e̶n̶a̶t̶e̶ nest EL ${} expressions, just add it cleanly.
Knowing this, the expression ${testing['${list.item}']} will be ${testing[list.item]}.
BUT note that this is not what you really want/need unless testing is indeed a Map<String, ArrayList<String>>, otherwise you will get unexpected results. From your code above, assuming requestScope.list is a List<Map<String, ArrayList<String>>>, then the code would be:
<c:forEach var="listItem" items="${list}">
<c:forEach var="innerString" items="${map[listItem.item]}">
<option><c:out value="${innerString}"/></option>
</c:forEach>
</c:forEach>
Note that ${list} is the same as ${requestScope.list} assuming there's no list attribute nor in page, session or application scope, similar for ${map}.

JSTL vs JSP Scriptlets

I want someone to explain some points in BlausC's amazing answer in this question.
He said that scriptlets had some disadvantages, which are:
Reusability: you can't reuse scriptlets. My question : how could I reuse JSTL code?
Replaceability: you can't make scriptlets abstract. What does abstract mean and how could JST become abstract?
OO: you can't make use of inheritance/composition. How could I use OO paradigms in JSTL?
Debugging: if a scriptlet throws an exception halfway, all you get is a blank page.
Testability: scriptlets can't be unit tested. What does that mean, and how can JSTL be unit tested?
Maintainability: per saldo, more time is needed to maintain mingled/cluttered/duplicated code logic. What does this mean?
The last thing is what he quoted form Oracle's recommendation:
JSP scriptlets should not be used for writing business logic.
In the MVC pattern, I use scriptlets only in the presentation layer. What does he mean here?
You seem to concentrate on only the presentation and flow-control part of the scriptlets as in using if, for and switch statements and out.print() things. You seem to compare scriptlets 1:1 with JSTL. This is wrong. I was not talking about the flow control part only (which is indeed to be replaced by JSTL), but about writing raw Java code in JSP files in general. I.e. gathering request parameters, validating and converting values, interacting with database and other Java classes/methods, etc. All things you normally (indirectly) do in a Servlet or Filter.
You should not have scriptlet code in JSPs. I'd recommend 100% JSTL and zero scriplet code.
JSPs should be purely presentation. That's the hidden benefit of writing JSPs using only JSTL, because they get all their dynamic data elsewhere. Let the service layer have the business logic and determine what data the JSP needs.
This answers your unit testing question, too. You should not have to unit test JSPs; those would be Selenium-like UI tests. If the logic is in the service tier, it's obvious how you test it.
JSPs should not be inherited. You can certainly compose them together using something like SiteMesh, but inheritance has no part in your JSPs. Once they inherit from Servlet, the chain should be ended.
Besides, it's a false alternative. Neither one should require reuse, inheritance, or unit testing. But that doesn't mean there isn't a clear winner: it's JSTL. No one should be using scriptlets in JSPs, except for very rare one-liners. Scriptlets are begging for trouble.
These days I prefer Velocity as my web UI template solution for Java, much more than JSPs. Just my opinion.
I can't speak for BalusC but in general I believe he was getting at the idea that these kinds of things should be accomplished by your ordinary Java code (in the Controller and Model layers if you're into the whole MVC thing).
You can't literally reuse JSP tags at an individual level, but you can reuse the classes they call into.
JSTL can't be abstract, but ordinary Java code (which you can perhaps invoke from JSTL) can be.
Again, you can't make objects usefully in jstl, but you can in all the classes that are called.
JSTL by itself is not unit-testable. But the classes and methods you call through it are.
It depends on the pattern you're using. By using the MVC (spring, struts, ...) you should avoid the usage of scriptlets in your JSP, because it represent the view it should contain pure XHTML tags. JSTL is a declarative language some kind of XML, while scriplet isn't.
Particularly I have used JSTL in combination with AJAX via prototype for generating RIA without needing to implement another pattern. Recently I have seen this kind of programming with ExtJS and DWR. In my case I found It was necessary to combine both JSTL and scriplets always preferring JSTL when possible.
<!-- simple controller, each action is called by means of AJAX -->
<% String signExt="jpg"; %>
<% int r=0, iMaxRows=0, iMaxCols=0;%>
<c:choose>
<c:when test="${param.action == 'get_chrequest_profile_table_by_family_and_date'}">
<sql:query var="dataset">
CALL GetProfilesView('<c:out value="${param.family_name}" />', '<c:out value="${param.reg_date}" />')
</sql:query>
<c:set var="strElements"><c:out value="${dataset.rowCount}" /></c:set>
<%
String strElements = pageContext.getAttribute("strElements").toString();
int iElements = (int)Integer.valueOf(strElements).intValue();
String to = "";
%>
<table class="tb_profiles" id="tb_profiles" iElements="<%=iElements%>"
width="100%" frame=void border="0" cellPadding="0" cellSpacing="0" style="border-top: 3px solid gray; border-left: 1px solid gray">
<%for(int i=1, j=0, col=0; i<100; i++){%>
<tr>
<%for(j=0; j<4; j++, col++){%>
<c:set var="c" scope="page"><%=col%></c:set>
<td name='<c:out value="${dataset.rows[c].chreqprofile_id}" />' >
<table width="100%" frame="below" cellPadding="0" cellSpacing="0"style="border-right: 1px solid gray;">
<%if( col < iElements){%>
<tr style="height:10mm">
<td class="td_function" style="cursor:default;">
<c:out value="${dataset.rows[c].description}" />
</td>
</tr>
.................
<tr style="height:14mm">
<td class="td_signature" align="center" vAlign="middle">
<img class="img_signature"
src='../xdata/signatures/<c:out value="${dataset.rows[c].responsible_name}"/>.<%=signExt%>'
alt='<c:out value="${dataset.rows[c].email}" />'
/>
</td>
</tr>
.................
<c:set var="sMail"><c:out value="${dataset.rows[c].email}"/></c:set>
<% if( col < iElements-1){
to = to + pageContext.getAttribute("sMail").toString() + ",";
}else{
to = to + pageContext.getAttribute("sMail").toString();
}
%>
<%}else{%>
<tr style="height:10mm">
<td class="td_function" style="cursor:default;">x</td>
.............
</tr>
<%}%>
</table>
</td>
<%}%>
</tr>
<%
if( col >= iElements){break;}
}%>
</table>
<span id="span_mail_to" style="display:none;"><%=to%></span>
</c:when>
<c:when test="${param.action == 'functions_form_insert'}">
.............
</c:when>
</c:choose>
I dont see that scriplets is too bad specially if you follows design pattern in it, I work a lot on spring mvc, in my jsp i just get the model data in scriplits, and i show it to the user using simple java code in html, i feel it give me more freedom than JSTL.
Here is a table comparing JSP and Facelets that may possibly be helpful to someone, somewhere:
Source

Categories