Loop through HashSet and HashMap in JSP and print the result - java

I want to do the below thing in JSP starting from for loop- I just want to loop HashSet and HashMap and print the result
private static HashMap<Long, Long> histogram = new HashMap<Long, Long>();
private static Set<Long> keys = histogram.keySet();
for (Long key : keys) {
Long value = histogram.get(key);
System.out.println("MEASUREMENT, HG data, " + key + ":" + value);
}
I am working with Spring MVC, so I added these two things in my model
model.addAttribute("hashSet", (keys));
model.addAttribute("histogram", (histogram));
And in my JSP page, I was doing something like this to emulate the above JAVA code but it was giving me an exception that something is wrong in my JSP page.
<fieldset>
<legend>Performance Testing:</legend>
<pre>
<c:forEach items="${hashSet}" var="entry">
Key = ${entry.key}, value = ${histogram}.get(${entry.key})<br>
</c:forEach>
</pre>
<br />
</fieldset>
Exception I got-
Caused by: javax.el.PropertyNotFoundException: Property 'key' not found on type java.lang.Long
at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:195)
at javax.el.BeanELResolver$BeanProperties.access$400(BeanELResolver.java:172)
at javax.el.BeanELResolver.property(BeanELResolver.java:281)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
Can anyone help me out with this?

You don't need to make use of keySet to access the values in the HashMap. When you iterate over HashMap using <c:forEach..>, you get back the EntrySet, for which you can use: - EntrySet#getKey() and EntrySet#getValue() directly: -
<c:forEach items="${histogram}" var="entry">
Key = ${entry.key}, value = ${entry.value}<br>
</c:forEach>

Related

Using dynamic variable in each

<th:block th:each="someData, index : ${someData.from.somewhere}">
<th:block th:each="image : ${images.foo0bar}">
<img th:src="${image}"/>
</th:block>
<hr/>
</th:block>
I want 0 in images.foo0bar to be replaced by index
How do I do something like th:each="image : ${images.foo + index + bar}"
You can use Thymeleaf's preprocessor to execute a getter based on a concatenated string:
__${...}__
For example:
<th:block th:each="someData, iterstat : ${someData}">
<th:block th:with="imageField=|images.foo${iterstat.index}bar|">
<th:block th:each="image : ${__${imageField}__}">
<img th:src="${image}">
</th:block>
</th:block>
</th:block>
In the above approach, the th:with="imageField=..." is used to build the string you need:
images.foo0bar
images.foo1bar
... and so on...
That imageField variable is then used with the Thymeleaf preprocessing syntax to handle it as a field name in your images object.
UPDATE
My solution above had a mistake, as originally written. Instead of this:
__${imageField}__
It should be this:
${__${imageField}__}
In other words, I forgot to wrap the pre-processor results in a Thymeleaf expression - so that the actual objects in each list (of image URLs) are retrieved.
I corrected this, above.
For backgound, here is the test data I used for the Thymeleaf model:
List<String> someData = Stream.of("abc", "def", "ghi")
.collect(Collectors.toList());
List<String> a = Stream.of("1", "2", "3")
.collect(Collectors.toList());
List<String> b = Stream.of("4", "5", "6")
.collect(Collectors.toList());
List<String> c = Stream.of("7", "8")
.collect(Collectors.toList());
Images images = new Images();
images.setFoo0bar(a);
images.setFoo1bar(b);
images.setFoo2bar(c);
Map<String, Object> model = new HashMap<>();
model.put("someData", someData);
model.put("images", images);
And my Images class contains these 3 fields:
private List<String> foo0bar;
private List<String> foo1bar;
private List<String> foo2bar;
Just a suggestion...
The Java objects which support this appear to be a bit convoluted, behind the scenes.
You have a collection of someData which you do not directly access, except to iterate through a count of its contents.
You then use this count to build a field name, so you can executed the related getter - and iterate through that collection of image URLs, in a completely different (seemingly unrelated) object.
Just as a suggestion: If you re-arrange your Java data, you could avoid this Thymeleaf complexity.

How to iterate map values which are in the form of lists in jsp?

public class Students()
{
private String title;
private String name;
//getters setters
}
I have a map
Map<String,List<Students>> mapList
What i want to is, i send a key to get value from map and iterate that lists.
My approach
jsp
<c:forEach items="${mapList['${title}']}" var="actualDetails">
//printing the values
</c:forEach>
You can't do EL expressions inside EL expressions.
It's already an EL expression, so it should just be:
<c:forEach items="${mapList[title]}" var="actualDetails">
Suppose ${mapList} points to a Map<String,List<Students>>, then you can use the following EL expressions
<c:forEach items="${mapList}" var="entry">
${entry.key}<br>
<c:forEach items="${entry.value}" var="studentDetails">
${studentDetails.title}<br>
${studentDetails.name}<br>
</c:forEach>
</c:forEach>

JSP/JSTL converting HashMap returned by JavaBean to String

I am no expert in JSP technology and looking for some help here to access HashMap from bean. I have a java class which returns a Hashmap, and would like to access both key and values of hash map in JSP.
The following is what I tried
//jsp:
<jsp:useBean id="mc" class="MyMapClassReturnsMap" />
<c:forEach items="${mc.getMap()}" var="mapkeyval">
<tr>
<td><c:out value="${mapkeyval.key}"></c:out></td>
</tr>
</c:forEach>
//Error:
javax.el.PropertyNotFoundException: Property 'key' not found on type java.lang.String
page returning the map as String, if I remove .key from mapkeyval page displaying map as String. Not sure what I am missing, but any pointers would be appreciated gr8ly
I am sure I am returning HashMap from my class, following is my main method, which works as expected
HashMap<String, String> jname1 = new HashMap<String, String>();
..
..
public static void main(String[] args) {
MyMapClassReturnsMap ta = new MyMapClassReturnsMap();
ta.searchFiles("root","CUST");
for(Map.Entry<String, String> s: ta.jname1.entrySet())
System.out.println("HashMap Values : "+ s.getKey() + " :" +s.getValue());
}
Try this,
<c:forEach items="${jname1 }" var="mapkeyval">
and provide the getter and setter methods for 'jname1' in your class.

Pass java map from JSTL/JSP to JavaScript methods

We have couple of related drop downs where results of one drop down relate to other dropdown.
We have a mapping defined for what to select when in the form of map-of-map, like this;
Map<String,Map<String,String>> topics = new HashMap<String, Map<String,String>>();
Map<String,String> ds = new HashMap<String, String>();
ds.put("Array", "Array");
ds.put("LL", "LL");
topics.put("DS", ds);
Map<String,String> algo = new HashMap<String, String>();
algo.put("BS", "BS");
algo.put("Sorting", "Sorting");
topics.put("Algorithm", algo);
Map<String,String> phil = new HashMap<String, String>();
phil.put("phil1", "phil1");
phil.put("phil2", "phil2");
topics.put("Philosophy", phil);
Map<String,String> others = new HashMap<String, String>();
others.put("others", "others");
topics.put("Others", others);
As per the above map, when "DS"is selected, we want to display "Ă„rray"and "LL". Similar is the case with other mappings.
I pass this map to JSP and use JSTL to render the options. While making decision to call JS to populate subsequent drop-down, I want to change it to JSON.
I want to pass specific map of the selected option to the JS method and populate subsequent drop down.
Is converting to JSON the only way? If yes, how about passing it from the controller? If we don't pass it from the controller, what are the cleaner ways to do it in JSP itself?
JSP Block is as follows:
<div>Subject</div>
<select name="topic" onchange="callJavaScriptMethodWithMapOfSelectedComponent(mapOfSelectedValue)");">
<c:forEach var="entry" items="${topics}">
<option value="${entry.key}">${entry.key}</option>
</c:forEach>
</select>
<select name="college">
<option value="default">Select Subject</option>
</select>
Depending on the values selected in first drop down, we need to populatevalues in second drop down.
JS method would take map of selected value in first drop down and populate second one.
function setOptions(chosen) {
var selbox = document.myform.college;
selbox.options.length = 0;
if (chosen == " ") {
selbox.options[selbox.options.length] = new Option('Please select one of the options above first',' ');
}
selbox.options[selbox.options.length] = new Option('//Choosen from the map passed','oneone');
}
}
First off I think you better change it so that topics is a Map < String, List < String > >, that'd make more sense since it's a single depth hierarchy.
Next up you have the choice of either converting the map into JSON and using eval to fill an object in javascript, or manually transverse the map keys and add them to the object, it all depends on the tools you have at hand to serialize the map into JSON server side (You can use new JSONObject(topics); from json.org) then just eval the json into a variable on Javascript.

Order of request.getParameterNames()

How do I get all the parameterNames in an HTML form in
the same sequence?
Example:
If the form contains FirstName, LastNameand Age
The output should appear exatcly in the same sequence
I have tried using the following but this shifts the
order of the output:
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String) paramNames.nextElement();
out.print(paramName);
}
I don't think there's nothing in the HTTP spec that forces browsers to send parameters in the order they appear in the form. You can work it around by prefixing a number to the name of the parameter like:
FirstName --> 0_FirstName
LastName --> 1_LastName
...
After that you could basically order the elements by the prefix. It is an ugly solution but it is the only way to do it. Something like:
// Assuming you fill listOfParameters with all the parameters
Collections.sort(listOfParameters, new Comparator<String>() {
int compare(String a,String b) {
return Integer.getInt(a.substring(0,a.indexOf("_"))) -
Integer.getInt(a.substring(0,b.indexOf("_")))
}
});
for (String param : listOfParameters) {
// traverse in order of the prefix
}
By the way - does it really matters the order in which you receive the parameters ?
None of the answers here really did answer my question. A HttpServletRequest saves all it's parameters in a HashMap, and a HashMap has NO ORDER. So, I saved the order of the parameters in an ordered ArrayList and saved it in a HttpSession, so I could retrieve the order of the parameters by querying the ArrayList (that was saved in the session) and achieve what I wanted!
request.getParameterNames () uses HashMap internally to store the name value pairs of form fields. There is no order maintained in this. if you need this in order then , some sort of naming convention for form parameters to control the order of retrieval.
SortedSet temp = new SortedSet();
Enumeration enumeration = request.getParameterNames();
while (enumeration.hasMoreElements())
{
temp.add((String)enumeration.nextElement());
}
Updated: You can use sorted set for that. Note that you must have all the parameters with different names (in this case it is most likely). Write any prefix as your parameter name.
Example:
<input type="text" name="1step">
<input type="text" name="2step">
Then in java code you can write:
SortedSet ss = new TreeSet();
Enumeration<String> enm = request.getParameterNames();
while(enm.hasMoreElements()) {
String pname = enm.nextElement();
}
Iterator i = ss.iterator();
while(i.hasNext()) {
String param = (String)i.next();
String value = request.getParameter(param);
}
HTML or Jsp Page
<input type="text" name="1UserName">
<input type="text" name="2Password">
<input type="text" name="3MobileNo">
<input type="text" name="4country">
and so on...
then in java code
SortedSet ss = new TreeSet();
Enumeration<String> enm=request.getParameterNames();
while(enm.hasMoreElements()){
String pname = enm.nextElement();
ss.add(pname);
}
Iterator i=ss.iterator();
while(i.hasNext()) {
String param=(String)i.next();
String value=request.getParameter(param);
}

Categories

Resources