Using JSTL how to "put" a value into a HashMap - java

I'm looking to set the key value pairing of a HashMap using JSTL only. Is this possible?
I know how to retrieve the key value pairs, but I haven't found a way to set them.
Any help would be appreciated.
Example of retrieving HashMap key/value pairs using JSTL:
<c:forEach var="hash" items="${myHashMap}">
<c:out value="${hash.key}" />
<c:out value="${hash.value}" />
...

You can use the <c:set>.
<c:set target="${myHashMap}" property="key" value="value"/>

I wouldn't use JSTL to do that, but straight-up JSP will get it done...
<%
myHashMap.put("hello", "world");
%>

Related

JSTL Remove ALL session attributes

I have been googling and found that I can remove a session attribute using:
<c:remove var="foo" />
What I want is to clear all session attributes from a JSP, something like this:
<c:forEach var="item" items="${sessionScope}">
<c:remove var="${item }" scope="session"/>
</c:forEach>
The problem is that the code from above gives me this warning
c:remove doesn't support runtime expression
And I can't view the JSP where I put the code.
Is it possible? Is it a good practice to do something like this?
Because your are iterating through "item" and while iterating it inside loop you are trying to delete.
Better do this logic in java only rather than JSP

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}.

Is there a way to populate a map in JSP?

For example
<jsp:useBean id="total" class="java.util.LinkedHashMap"/>
// need somehow do something like this: total.put('key', 'value');
But without using scriptlets (it's obvious but a little bit ugly)
You can use JSTL <c:set> for this.
<jsp:useBean id="total" class="java.util.LinkedHashMap"/>
<c:set target="${total}" property="key" value="value" />

Converting an ArrayList<someObjects> to an HTML table

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>

concepts about JSTL

I want to understrand what happens when i use JSTL to access maps,in Hidden features of JSP/Servlet
in #blausC's answer, he explained what happend, but when i try to use the following code
<c:set var="resultMap" value="validationResults" scope="request"></c:set>
<c:if test="${resultMap['userName'] != null}">
${resultMap['userName'].details}
</c:if>
a confused exception happend
Caused by: javax.el.PropertyNotFoundException: Property 'userName' not found on type java.lang.String
The key of the map should be string, so whay is this exception, i tried the examples in the above question and the same exception,Can some one tell me where I have misunderstanding?
Edit: I populate the map in the servlet and send it to jsp
Map<String, ValidationResult> result = new HashMap<String, ValidationResult>();
aValidationResult = new ValidationResult();
check whether the field is valid or not if not fill the map
result.put("userName", aValidationResult);
result.put("group", aValidationResult);
if map is not empty, return the map to jsp
request.setAttribute("validationResults", result);
the map is filled when i make server side validation ,
Thanx in advance.
resultMap is a String because of this line
<c:set var="resultMap" value="validationResults" scope="request"></c:set>
You need to use EL to assign the value
<c:set var="resultMap" value="${validationResults}" scope="request"></c:set>
Edit: The following is working code
<c:set var="validationResults" value="<%= new java.util.HashMap() %>" />
<c:set target="${validationResults}" property="username" value="Hello World" />
<c:set var="resultMap" value="${validationResults}" />
<c:out value="${resultMap['username']}"></c:out>
This is caused because String class does not have a method called getUserName()

Categories