Is there a standard way of printing an array/collection elements of javabeans in JSP? All I know is the <jsp:getProperty> tag which can't do this. I know it can be done using custom tags, but it being such an essential requirement should be provided by JSP.
Also, I have read that using setAttribute() method of PageContext, ServletContext etc we can in a Servlet get the bean and work on it, but it's giving me null value.
pageContext.getAttribute("beanPropertyVariable") //set in page scope
application.getAttribute("beanPropertyVariable") //set in application scope
How can I achieve this?
The standard way is using JSTL <c:forEach>.
Assuming that ${beans} represents the collection of javabeans, here's an example:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
...
<c:forEach items="${beans}" var="bean">
${bean.property1}<br/>
${bean.property2}<br/>
${bean.property3}<br/>
</c:forEach>
That's also the simplest way you can get.
See also:
Our JSTL wiki page
Our Javabeans wiki page
you can use JSTL c:foreach tag like below
<c:forEach items="${list}" var="var">
${var}<br/>
</c:forEach>
Related
I've started to learn Hybris and I want to find out how to pass the class as a parameter to a custom CMS Component (for the component's root element).
Let's suppose that in a jsp file named customNavigationComponent.jsp I have this piece of code:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="cms" uri="http://hybris.com/tld/cmstags"%>
<c:forEach items="${navigation.entries}" var="navigationLink">
<div class="custom-component-wrapper">
<cms:component component="${navigationLink.item}"/>
</div>
</c:forEach>
And the custom component looks like this:
<a href="${component.url}">
<div>${component.linkText}</div>
</a>
I would like to understand what I need to do to pass the class navigation-link as a parameter, like this:
<cms:component component="${navigationLink.item}" class="navigation-link"/>
so that the rendered result will be similar to:
<a href="stackoverflow.com" class="navigation-link">
<div>Lorem Ipsum</div>
</a>
There is no attribute called, class in cms:component and therefore the following statement will not work:
<cms:component component="${navigationLink.item}" class="navigation-link"/>
Please check https://help.sap.com/doc/a4265d5ea8314eb2929e6cf6fb8e35a5/1811/en-US/de/hybris/platform/cms2lib/cmstags/CMSComponentTag.html
In order to understand it better, you can compare it with c:forEach. At https://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/c/forEach.html, you will find a list of attributes available with c:forEach and if you want to dig deeper, you can further check https://tomcat.apache.org/taglibs/standard/apidocs/javax/servlet/jsp/jstl/core/LoopTagSupport.html
If you want to use your statement, you will need to create a custom tag.
I have a parent jsp a.jsp which includes another jsp b.jsp. I am calculating some values in b.jsp which needs to be used in parent jsp a.jsp , which will pass this calculated value to another jsp say c.jsp. How can I evaluate value in child jsp and pass it to parent jsp before that page completely loads?
How are you including the "child" jar inside the parent? static or dynamic import?
if you have
<%# include file="myFile.jsp" %>
change it by
<jsp:include file="myFile.jsp" />
then in the parent set a property in the request (not in the session, that would be "dirtier"):
<% request.setAttribute("attrName", myValue) %>
finally, in the "child" jsp:
<% myValue = (MyValueType)request.getAttribute("attrName") %>
If you need to pass an attribute between including and included jsp (and viceversa)you should use the page context, which is the more short context (from lifecycle perspective)
You can set variables in the request in b.jsp, and use them in parent.jsp. But you can only use them in the parent jsp after the <jsp:include> tag. Remember that this is all evaluated on the server side, so when you say "before that page completely loads," you can be guaranteed that the server has evaluated it before the browser has loaded it. If you mean that you want to delay evaluation on the server until some code below it is evaluated, that's not going to be possible. At least not like this.
b.jsp
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="myVar" scope="request" value="Hello"/>
parent.jsp
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<jsp:include page="b.jsp"></jsp:include>
<span>
The value is ${requestScope.myVar}.
</span>
You could you session scope to accomplish this.
(b.jsp)
session.setAttribute("value",value);
(c.jsp)
session.getAttribute("value");
However, I would recommend doing some major restructuring instead. In your example, the value of your data depends on the order of the elements on the page. If you ever need to re-arrange things (for instance, moving the b.jsp include after the c.jsp include), you risk breaking the business logic.
A good pattern for web development is a model-view-controller pattern. The "controller" determines what page should be displayed, the "model" calculates all the data and makes it available, and the "view" does the display and formatting.
I would recommend reviewing this article, which is helpful for understanding why MVC is a valuable approach:
http://www.javaranch.com/journal/200603/Journal200603.jsp#a5
Edit: As other users have mentioned, request scope would be cleaner than session scope. However, I still recommend determining the value first before writing any display content.
I am using this code in JSF.:
<c:if test="#{sV.done.booleanValue()}">
<option value="#{sV.id}" selected="selected">#{sV.text}</option>
</c:if>
<c:if test="#{not sV.done.booleanValue()}">
<option value="#{sV.id}">#{sV.text}</option>
</c:if>
sv is my class containing data (pojo), done is an Boolean variable, I want to display option tag with selected attribute if sV.done is true.
But I couldn't make it. Don't know where I am wrong.
Otherwise there can be something wrong with c, because c:forEach was not working before some time in my case in same page? It can be the reason? Where I am wrong?
Every time it displays option tag without selected attribute.
Try this: -
<c:if test="${sV.done == true}">...</c:if> // or
<c:if test="${sV.done eq true}">...</c:if> // or
<c:if test="${sV.done}">...</c:if> // or
And for negation (If sV.done is false): -
<c:if test="${! sV.done}">...</c:if> /// OR
<c:if test="${not sV.done}">...</c:if> /// OR
<c:if test = "${sV.done != true}">...</c:if> // OR
<c:if test = "${sV.done ne true}">...</c:if> // OR
For more on if with operators check out this link: - JSTL if
Your syntax is fine, provided that you're using EL 2.2. So, none of the JSTL <c:xxx> tags are been interpreted? You need to import the JSTL core taglib. It's unclear what view technology and JSTL version you're using, so here are import examples for both JSP and Facelets.
JSP with JSTL 1.0:
<%#taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
JSP with JSTL 1.1/1.2:
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Facelets 1.x with JSTL 1.1/1.2:
<html ... xmlns:c="http://java.sun.com/jstl/core">
Facelets 2.x with JSTL 1.2:
<html ... xmlns:c="http://java.sun.com/jsp/jstl/core">
See also:
Our JSTL wiki page
Unrelated to the concrete problem, have you considered using a JSF UISelectOne component instead of fiddling with <option> elements yourself? You can find some concrete examples in our h:selectOneMenu wiki page.
JSF and JSTL both access 'boxed' objects (Boolean, Integer etc) directly. No unboxing is necessary -- so you don't have to call booleanValue().
<c:if test="${sV.done}">...</c:if>
But actually, your whole approach could be better -- I don't render a options in a page, without a list of options & a value. I don't write out loops & selection tests manually every time, there are tags or you can write a method to do this.
Super hint: I have a class called Pair( String name, Object value) & library method HtmlUI.renderSelectOptions(), to output SELECT options from a list of these & a 'current' value.
Select combo-box may not really be the best representation for a boolean either? You could go with a checkbox.. But this is up to your UI design.
If you did want to go this way, you could switch just the SELECTED attribute inside the tag. Easier than duplicating code for the entire , key & value.. For legacy code, I have a function that fulfills this exact requirement also :)
Hope this helps! Vote me up.
As I mentioned in question, It seems to look like some other component/library is interfering in work of c:if, it didn't work in any case. I tried all the suggestions given above. Thanks to all for replies.
I have a 2d array stored in a java bean and I'm trying to iterate through its contents to print a corresponding table on a JSP page. The array is a bean data member which I'm accessing through the EL code ${board.cells}. I tried to do this with a c:forEach tag, but it's only printing a single cell. I know the array contents are valid, as I can see them when I index them directly by ${board.cells[0][0]}
Here's my loop code, embedded in the JSP.
<c:forEach items="${board.cells}" var="row">
<tr>
<c:forEach items="${row}" var="cell">
<td><img src=${cell} align="" alt="cell"></td>
</c:forEach>
</tr>
</c:forEach>
Any help is much appreciated!
As per the comments, JSTL core tags are simply not been interpreted/parsed. They are been sent plain to the HTML response. You need to declare the JSTL core taglib in top of your JSP to get them to run.
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
See also:
Our JSTL wiki page
How do I access a JSP tag's attribute value within a JSTL tag? In the code below, I would like to access the url attribute and test if it's empty. I am using the JSTL 1.0 specification.
<%# taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%# attribute name="url" required="false"%>
<c:if test="${!empty url}">
...
</c:if>
If you're creating tag files, then you're using at least JSP 2.0 - which means you should be using at least JSTL 1.1. At any rate, the attribute directive should create a page-scoped var with the same name as its name attribute (unless it's optional and not provided). So, can you provide any more detail on the errors and/or output you're observing?