I have a map like this,
Map<Integer,ArrayList<Object>> myMap = new LinkedHashMap<Integer,ArrayList<Object>>();
Now I have to iterate this Map and then the ArrayList inside the map. How can I do this using JSTL?
You can use JSTL <c:forEach> tag to iterate over arrays, collections and maps.
In case of arrays and collections, every iteration the var will give you just the currently iterated item right away.
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${collectionOrArray}" var="item">
Item = ${item}<br>
</c:forEach>
In case of maps, every iteration the var will give you a Map.Entry object which in turn has getKey() and getValue() methods.
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${map}" var="entry">
Key = ${entry.key}, value = ${entry.value}<br>
</c:forEach>
In your particular case, the ${entry.value} is actually a List, thus you need to iterate over it as well:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${map}" var="entry">
Key = ${entry.key}, values =
<c:forEach items="${entry.value}" var="item" varStatus="loop">
${item} ${!loop.last ? ', ' : ''}
</c:forEach><br>
</c:forEach>
The varStatus is there just for convenience ;)
To understand better what's all going on here, here's a plain Java translation:
for (Entry<String, List<Object>> entry : map.entrySet()) {
out.print("Key = " + entry.getKey() + ", values = ");
for (Iterator<Object> iter = entry.getValue().iterator(); iter.hasNext();) {
Object item = iter.next();
out.print(item + (iter.hasNext() ? ", " : ""));
}
out.println();
}
See also:
How to loop through a HashMap in JSP?
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
How to loop over something a specified number of times in JSTL?
Did you try something like this?
<c:forEach var='item' items='${map}'>
<c:forEach var='arrayItem' items='${item.value}' />
...
</c:forEach>
</c:forEach>
you haven't closed c tag.try out this
<c:forEach items="${logMap}" var="entry">
Key = ${entry.key}, values =
<c:forEach items="${entry.value}" var="item" varStatus="loop">
${item} ${!loop.last ? ', ' : ''}
</c:forEach><br>
</c:forEach>
You can also loop round just the map.value its self if you know the key
<c:forEach var="value" items="${myMap[myObject.someInteger]}">
${value}
</c:forEach>
Related
This is my arraylist for index 17
In this code may have data list or may not. Data is dispay when there are records. Not handled for no records
Java code:
//To avoid arrayindexoutofbound exception length checked
if (resultList.length >17) {
statisticsDetails.setqNames(resultList[17]);
//System.out.println(resultList[17]);
String[] qName=resultList[17].split("\\^");
List<StatisticsDetails> statisticsDetailsList = new ArrayList<StatisticsDetails>();
for (String queueName:qName ){
StatisticsDetails details = new StatisticsDetails();
String[] splitQueues = queueName.split("=");
details.setqKey(splitQueues[0]);
details.setqCount(splitQueues[1]);
statisticsDetailsList.add(details);
}
statisticsDetails.setqNamesList(statisticsDetailsList);
}
Jsp code:
<logic:iterate id="iteratorId" name="statistics.statisticsDetails" property="qNamesList">
<tr>
<td class="col-sm-6 col-md-6 col-lg-6"><bean:write name="iteratorId" property="qKey" /></td>
<td class="col-sm-6 col-md-6 col-lg-6"><bean:write name="iteratorId" property="qCount" /></td>
</tr>
</logic:iterate>
how to avoid arraybound error and JSP to handle when no data found
Use a null check using JSTL(Do not forget to import the tag library):
import core library:
<%# taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
and then use:
<c:if test="${not empty statistics.statisticsDetails}">
//keep your code here to iterate the list
</c:if>
Or use:
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
and then:
<c:if test="${fn:length(statistics.statisticsDetails) > 0}">
//keep your code here to iterate the list
</c:if>
Please check all mapping is correct or not in the struts-config.xml. In my case, i found incorrect type was mentioned for form and then it was giving the error. Type means package name for the form. in tag.
I would like to know why I am not able to get values from an outer hashtable using the keys in jstl, the keys are integer values, the values are inner hashtables and I am working on some legacy code hence the reason for the Hashtables, which are returned from a stored procedure call in this form.
Oddly in the inner hashtable as I process it in my forEach loop I am able to get those values out... ${data['NAME']} actually does work.
I am able to loop over the entire outer hashtable using JSTL forEach loop and its ok but if I try to get a value like ${missing_ciphers[1]} or even ${missing_ciphers['1']} then nothing is returned.
The hashtable when printed looks like this:
{4={SOURCE=D, NAME=D}, 3={SOURCE=C, NAME=C}, 2={SOURCE=B, NAME=B}, 1={SOURCE=A, NAME=A}}
I am able to loop over it ok using the following code but the list is not in the order I want it to be in so I wanted to use the loop counter to get objects out by their key but this doesnt seem to return anything (the inline styles will be moved into a css file once I have this working as I want...):
<c:forEach items="${missing_ciphers}" var="ciphers" varStatus="cipher_loop">
<c:set var="data" value="${ciphers.value}">
</c:set>
<tr style="border-left: none; border-right: none;" class="${cipher_loop.index % 2 == 0 ? 'even' : 'odd'}">
<td><span style="font-weight: bold;">${data['SOURCE']}</span></td>
<td><span style="font-weight: bold;">${data['NAME']}</span></td>
</tr>
</c:forEach>
Can anyone help me understand what is happening here and why I am not able to get a value out using the ${missing_ciphers[1]} type syntax?
I should add that the following code does print the inner hashtable into the tomcat console:
<% System.out.println("val: " + ((Hashtable)request.getAttribute("missing_ciphers")).get(1)); %>
I have even tried the following just to see if it was down to the type of the key this still doesnt get from the outer hashtable:
<c:forEach items="${missing_ciphers}" var="ciphers" varStatus="cipher_loop">
<c:set var="counter" value="${cipher_loop.index + 1}" />
<fmt:parseNumber var="fmt_counter" integerOnly="true" type="number" value="${counter}" />
<c:out value="${fmt_counter}" />
<c:set var="data" value="${missing_ciphers[fmt_counter]}"></c:set>
<tr style="border-left: none; border-right: none;" class="${cipher_loop.index % 2 == 0 ? 'even' : 'odd'}">
<td><span style="font-weight: bold;">${data['SOURCE']}</span></td>
<td><span style="font-weight: bold;">${data['NAME']}</span></td>
</tr>
</c:forEach>
Thanks
You should be using variable name assigned to varStatus - 'cipher_loop' and not varStatus itself.
Also you should use the index property or the count property to get the current index. (index starts at 0 and count at 1 by default)
${missing_ciphers[varStatus]}
should be
${missing_ciphers[cipher_loop.count]}
Edit
What is the type of your key in your outer hastable? Integer?
The type of varStatus.index (or counter) is long and you will have to explicitly set it as integer to use it as a key of your outer table
The following code works for me
<jsp:directive.page import="java.util.*"/>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
Hashtable h = new Hashtable();
Hashtable h1 = new Hashtable();h1.put("SOURCE","D");h1.put("NAME","D");
Hashtable h2 = new Hashtable();h2.put("SOURCE","C");h2.put("NAME","C");
Hashtable h3 = new Hashtable();h3.put("SOURCE","B");h3.put("NAME","B");
Hashtable h4 = new Hashtable();h4.put("SOURCE","A");h4.put("NAME","A");
h.put(4,h1);h.put(3,h2);h.put(2,h3);h.put(1,h1);
request.setAttribute("missing_ciphers",h);
%>
<c:forEach items="${missing_ciphers}" var="ciphers" varStatus="cipher_loop">
<c:set var="counter" value="${cipher_loop.index + 1}" />
<c:out value = "${counter}"/>
<c:set var = 'counter' value = '<%=new Integer(pageContext.findAttribute("counter").toString())%>'/>
<c:set var="data" value="${missing_ciphers[counter]}"></c:set>
<tr>
<td><span style="font-weight: bold;">${data['SOURCE']}</span></td>
<td><span style="font-weight: bold;">${data['NAME']}</span></td>
</tr>
</c:forEach>
OTOH, if the keys in your table is of type long, then you can use the varstatus.index property directly
<jsp:directive.page import="java.util.*"/>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
Hashtable h = new Hashtable();
Hashtable h1 = new Hashtable();h1.put("SOURCE","D");h1.put("NAME","D");
Hashtable h2 = new Hashtable();h2.put("SOURCE","C");h2.put("NAME","C");
Hashtable h3 = new Hashtable();h3.put("SOURCE","B");h3.put("NAME","B");
Hashtable h4 = new Hashtable();h4.put("SOURCE","A");h4.put("NAME","A");
h.put(new Long(4),h1);h.put(new Long(3),h2);h.put(new Long(2),h3);h.put(new Long(1),h1);
request.setAttribute("missing_ciphers",h);
%>
test
<<c:forEach items="${missing_ciphers}" var="ciphers" varStatus="cipher_loop">
<c:set var="counter" value="${cipher_loop.index + 1}" />
<c:set var="data" value="${missing_ciphers[counter]}"></c:set>
${data}
<tr>
<td><span style="font-weight: bold;">${data['SOURCE']}</span></td>
<td><span style="font-weight: bold;">${data['NAME']}</span></td>
</tr>
</c:forEach>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%=new Date() %>
<%
ArrayList al = new ArrayList();
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
%>
<select>
<option value="<%=al%>"></option>
</select>
</body>
</html>
This is my code i want to add Arraylist in drop down in Jsp I dont know how to Bind arraylist in html obtion or drop down please help me i have tried Much but unable to do this .
You have to use JSTL <forEach> to iterate through the elements and add it to the select-option . Probably make the List a scoped attribute . Populate the List object in the servlet, set it in request/session scope and forward the request to this JSP. Remember you can populate the List in the JSP itself and use pageScope to refer it , but that will be bad design in my opinion.
<select>
<c:forEach var="element" items="${al}">
<option value="${element}">${element}</option>
</c:forEach>
</select>
Here , al is the name of the attribute which stores the List in probably request or session scope.
Use JSTL in project :
Download the JSTL 1.2 jar .
Declare the taglib in JSP file for the JSTL core taglib.
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
If you want to use just the scriptlets(which is bad off course) :
<%
List<String> al = new ArrayList<String>();
al.add("C");
..........
...........
%>
<select>
<% for(String element: al) { %>
<option value="<%=element%>"><%=element%></option>
<% } %>
</select>
The above code will work if you have defined the List as List<String> , or else you need to cast the element to String.
Read How to avoid Java Code in JSP-Files?.
EDITED
Try this:
<%
ArrayList al = new ArrayList();
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
%>
<select>
<% for(int i = 0; i < al.size(); i++) {
String option = (String)al.get(i);
%>
<option value="<%= option %>"><%= option %></option>
<% } %>
</select>
</body>
</html>
Take a look at the tag in the core JSTL library.
Store the arraylist in pageScope.myList and loop as follows:
<select>
<c:forEach items="${pageScope.myList}" var="item" varStatus="status">
<option value='${item}'></option>
</c:forEach >
</select>
This is preferable than using scriptlets which are not considered good practice
Try this: declare your arraylist in between <%! … %>
<%! ArrayList al = new ArrayList(); %>
I have following two array in my code
List<Double> centralityList = (List<Double>) request
.getAttribute("centralityList");
List<String> labelList = (List<String>) request
.getAttribute("labelList");.
Now I have six string values and corresponding 6 double values of the string in these two array. My question is how to display them in tabular format in my JSP?Is this possible
For Example:
label list contains [a,b,c,d,e]
centrality list contains- [4,6,8,9,0]
So now I want to display output like:
label list centrality list
a 4
b 6
c 8.
. .
etc
Yes of course you can. You can use scriplets but they are not recommended. Instead use JSTL.
Try this out:
Have this at top of your JSP:
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
And code for displaying data
<c:forEach begin="0" end="${fn:length(centralityList) - 1}" var="index">
<tr>
<td><c:out value="${centralityList[index]}"/></td>
<td><c:out value="${labelList[index]}"/></td>
</tr>
</c:forEach>
try this code
<%
List<Double> centralityList = (List<Double>) request
.getAttribute("centralityList");
List<String> labelList = (List<String>) request
.getAttribute("labelList");
String myString="";
%>
<table>
<tr><td>
<%
for(int i = 0; i < labelList.size(); i++)
{
out.println((String)labelList.get(i));
}
%>
</td><td>
<%
for(int i = 0; i < centralityList.size(); i++)
{
out.println((double)centralityList.get(i));
}
%>
</td>
</table>
You can achieve this eaisly by using JSTL which is even more easy and far better way but as in your code I didn't find any evidence of using JSTL , so this is the way for now
You can use JSTL tags and iterate through this-
<c:forEach var="Array" items="userNames">
// do something with the element
</c:forEach>
Use this in your jsp page
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
I have the following code:
<div>
<%
TaxonomicTypeFeed ttf = new TaxonomicTypeFeed();
ArrayList<String> tmp = ttf.getTypes();
System.out.println("Going to print");
for (int i=0; i < tmp.size(); i++)
{
System.out.println(tmp.get(i));
}
%>
<form>
<select>
<%
Iterator<String> i = tmp.iterator();
while (i.hasNext())
{
String str = i.next(); %>
<option value="<%str.toString();%>"><%str.toString();%>
</option>
<%}%>
</select>
</form>
</div>
It creates a dropdown list fine, however there is no text.
This is the first time I have ever used any of these options before, so I have no idea if I am even going about it in the right manner.
You need to print the values by <%= %>. The <% %> won't print anything.
<option value="<%=str%>"><%=str%></option>
Unrelated to the problem: this is not the best practice. Consider using taglibs/EL. You end up with better readable/maintainable code.
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id="taxonomicTypeFeed" class="com.example.TaxonomicTypeFeed" />
...
<select>
<c:forEach items="${taxonomicTypeFeed.types}" var="type">
<option value="${type}">${type}</option>
</c:forEach>
</select>
Instead of <jsp:useBean> you can also use a preprocessing servlet.