Reputation: 899
I am trying to display list of entities in a .jsp file, but I this error:
Unable to compile class for JSP:
An error occurred at line: 28 in the jsp file: /guestbook.jsp
Can only iterate over an array or an instance of java.lang.Iterable
25: </tr>
26: <tr>
27: <%
28: for (Entity drugtarget : "${drugtargets}") {
29: %>
30: <td>
31: <%
Here is my query from servlet class:
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Query query = new Query("DrugTarget").addSort("drug", Query.SortDirection.DESCENDING);
List<Entity> drugtargets = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(10));
req.setAttribute("drugtargets", drugtargets);
And this is how I send drugtargets to jsp file:
String url = "/guestbook.jsp";
ServletContext sc = getServletContext();
RequestDispatcher rd = sc.getRequestDispatcher(url);
try {
rd.forward(req, resp);
} catch (ServletException e) {
e.printStackTrace();
}
Finally here is how I write jsp part:
<table border="1">
<tr>
<th>Drug Names</th>
<th>Target Names</th>
</tr>
<tr>
<%
for (Entity drugtarget : "${drugtargets}") {
%>
<td>
<%
pageContext.setAttribute("drug_content",
drugtarget.getProperty("drug"));
%>
${fn:escapeXml(drug_content)}
</td>
<td>
<%
pageContext.setAttribute("target_content",
drugtarget.getProperty("target"));
%>
${fn:escapeXml(target_content)}
</td>
<%
}
%>
</tr>
</table>
I think I'm making a syntax mistake, but I'm not sure. I checked some examples and the same way (to send list of entities from servlet to jsp and to reach entities in jsp file) was used. How can I resolve this error?
Upvotes: 0
Views: 6209
Reputation: 1108742
You shouldn't be using scriptlets (those oldschool <% %>
things with Java code) at all when using servlets and EL. Use taglibs like JSTL instead. It offers the <c:forEach>
tag to iterate over a collection.
For example,
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
...
<table border="1">
<tr>
<th>Drug Names</th>
<th>Target Names</th>
</tr>
<c:forEach items="${drugtargets}" var="drugtarget">
<tr>
<td>${fn:escapeXml(drugtarget.drug)}</td>
<td>${fn:escapeXml(drugtarget.target)}</td>
</tr>
</c:forEach>
</table>
(note that I also fixed the rendering of table rows by putting the <tr>
inside the loop)
Much simpler, isn't it? You can by the way also just use <c:out value="${drugtarget.drug}"/>
instead of those functions.
If you can, I suggest to add the following to your webapp's web.xml
in order to disable scriptlets altogether so that you will be forced to do things the right way.
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
Upvotes: 3
Reputation: 4380
In this case "${drugtargets}" is a String, not the list you passed. I would recommend using the looping. It's way cleaner.
<c:forEach var="drugtarget " items="${drugtargets}">
.... Your code here ...
</c:forEach>
Upvotes: 1