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.
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>
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Evaluate empty or null JSTL c tags
I'm refactoring scriptlets to JSTL and EL and I would like to know how to write the following in JSTL / EL:
if(sokandeList != null && sokandeList.size() > 0) { %>
...
I don't know how to test for null and AFAIK EL can only access getters in this context so I must add a method getSize() to the sokandeList class. Correct? What should the JSTL / EL expression look like? Thanks for any help
Use the empty keyword, it checks both nullness and emptiness.
<c:if test="${not empty sokandeList}">
...
</c:if>
Note that when your intent is to iterate over the list using <c:forEach> then it may be good to know that it already won't run when the provided items is empty. If the <c:forEach> is directly surrounded by this check, then this check is entirely superfluous.
See also:
Java EE 6 tutorial - operators in EL
Java EE 6 tutorial - examples of EL expressions
Here's one way:
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<c:if test="${fn:length(sokandeList) > 0}">
I think you can use this too:
<c:if test="${!empty myObject.sokandeList}">
Awesome JSTL cheat sheet
I've been told that the use of scriptlets (<%= ... %>) in my JSP pages isn't such a great idea.
Can someone with a bit more java/jsp experience please give me some pointers as to how to change this code so its more 'best practice', whatever that may be?
This JSP is actually my sitemesh main decorator page. Basically my web design has a tab strip and a submenu, and i wish to somehow highlight the current tab and show the correct submenu by looking at the current request URI.
<%# taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator" %>
<html>
<head>
<title>My Events - <decorator:title /></title>
<link href="<%= request.getContextPath() %>/assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="tabs">
<a
<%= request.getRequestURI().contains("/events/") ? "class='selected'" : "" %>
href='<%= request.getContextPath() %>/events/Listing.action'>Events</a>
<a
<%= request.getRequestURI().contains("/people/") ? "class='selected'" : "" %>
href='<%= request.getContextPath() %>/people/Listing.action'>People</a>
</div>
<div class="submenu">
<% if(request.getRequestURI().contains("/events/")) { %>
List of Events
|New Event
<% } %>
<% if(request.getRequestURI().contains("/people/")) { %>
List of People
|New Person
<% } %>
</div>
<div class="body">
<decorator:body />
</div>
</body>
</html>
Thanks all
I think it helps more if you see with your own eyes that it can actually be done entirely without scriptlets.
Here's a 1 on 1 rewrite with help of among others JSTL (just drop jstl-1.2.jar in /WEB-INF/lib) core and functions taglib:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>My Events - <decorator:title /></title>
<link href="${pageContext.request.contextPath}/assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="tabs">
<a
${fn:contains(pageContext.request.requestURI, '/events/') ? 'class="selected"' : ''}
href="${pageContext.request.contextPath}/events/Listing.action">Events</a>
<a
${fn:contains(pageContext.request.requestURI, '/people/') ? 'class="selected"' : ''}
href="${pageContext.request.contextPath}/people/Listing.action">People</a>
</div>
<div class="submenu">
<c:if test="${fn:contains(pageContext.request.requestURI, '/events/')}">
List of Events
|New Event
</c:if>
<c:if test="${fn:contains(pageContext.request.requestURI, '/people/')}">
List of People
|New Person
</c:if>
</div>
Here's a more optimized rewrite, note that I used c:set to "cache" expression results for reuse and that I use HTML <base> tag to avoid putting the context path in every link (just make all relative URL's in your webpage relative to it --without the leading slash!):
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<c:set var="isEvents" value="${fn:contains(pageContext.request.requestURI, '/events/')}" />
<c:set var="isPeople" value="${fn:contains(pageContext.request.requestURI, '/people/')}" />
<html>
<head>
<title>My Events - <decorator:title /></title>
<base href="${pageContext.request.contextPath}">
<link href="assets/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="tabs">
<a ${isEvents ? 'class="selected"' : ''} href="events/Listing.action">Events</a>
<a ${isPeople ? 'class="selected"' : ''} href="people/Listing.action">People</a>
</div>
<div class="submenu">
<c:if test="${isEvents}">
List of Events|New Event
</c:if>
<c:if test="${isPeople}">
List of People|New Person
</c:if>
</div>
It can actually be optimized more if you collect all those "hardcoded" values like events and people and link texts in a Map in the application scope and use under each the JSTL <c:forEach> to display the tabs.
As to your actual question, you can disable scriptlets (and get runtime errors about using it) by adding the following entry in webapp's web.xml. It may help to spot overseen scriptlets.
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
To learn more about EL, check the Java EE tutorial part II chapter 5. Implicit EL objects, such as ${pageContext} are described here. To learn more about JSTL, check the Java EE tutorial part II chapter 7. Note that JSTL and EL are two separate things. JSTL is a standard taglib and EL just enables to access backend data programmatically. Although it is normally used in taglibs like JSTL, it can also be used standalone in template text.
As an aside, is <%= request.getContextPath() %> an acceptable use of scriptlets that isn't frowned on so much?
This may be an unpopular opinion, but if all you do are simple conditionals and text insertions, I cannot find much fault in the use of scriptlets. (Note the if)
I'd probably use JSTL and the expression language, but mostly because it can be less typing, and IDE support may be better (but a good JSP IDE can also find missing closing brackets and stuff like that).
But fundamentally (as in "keep logic out of templates") I fail to see any difference between
<% if(request.getRequestURI().contains("/events/")) { %>
and
${fn:contains(pageContext.request.requestURI, '/events/')
Scriptlets aren't the worst thing in the world. An important consideration is to think about who is going to be maintaining the code. If its web designers who don't have much Java experience, you are probably better off going with tag libraries. However, if Java developers are doing the maintainance, it may be easier on them to go with scriptlets.
If you end up using a tag library and JSTL, you are expecting the maintainer to also learn the tag library and know JSTL. Some developers will be fine with this as it is a skill they want or already have, but for some developers who only have to deal with JSPs every few months or so, it can be lot less painful to work with clearly written scriptlets written in nice, familiar Java.
This isn't a direct answer to your question (and there are already several good ones, so I won't try to add to it), but you did mention:
Can someone with a bit more java/jsp
experience please give me some
pointers as to how to change this code
so its more 'best practice', whatever
that may be?
In my opinion, best practice, with regards to JSP, is that it should be used strictly as a templating engine, and no more (i.e., no business logic in there). Using JSTL, as many pointed out, definitely helps you get there, but even with JSTL, it's easy to do to much in a JSP.
I personally like to follow the rules laid out in Enforcing Strict Model-View Separation in Templating Engines by the Terence Parr when developing in JSP. The paper mentions the purpose of templating engines (separating model and view), and characteristics of a good templating engine. It takes a good look at JSP and points out ways it's not a good templating engine. Not surprisingly, JSP is basically too powerful and allows developers to do too much. I strongly recommend reading this paper, and it'll help you restrict yourself to the "good" parts of JSP.
If you read only one section in that paper, read chapter 7, which includes the following rules:
the view cannot modify the model either by directly altering model
data objects or by invoking methods on
the model that cause side-effects.
That is, a template can access data
from the model and invoke methods, but
such references must be side-effect
free. This rule arises partially
because data references must be
order-insensitive. See Section 7.1.
the view cannot perform computations upon dependent data
values because the computations may
change in the future and they should
be neatly encapsulated in the model in
any case. For example, the view cannot
compute book sale prices as
“$price*.90”. To be independent of the
model, the view cannot make
assumptions about the meaning of data.
the view cannot compare dependent data values, but can test the
properties of data such as
presence/absence or length of a
multi-valued data value. Tests like
$bloodPressure<120 must be moved to
the model as doctors like to keep
reduc- ing the max systolic pressure
on us. Expressions in the view must be
replaced with a test for presence of a
value simulat- ing a boolean such as
$bloodPressureOk!=null Template output
can be conditional on model data and
com- putations, the conditional just
has to be computed in the model. Even
simple tests that make negative values
red should be computed in the model;
the right level of abstraction is usu-
ally something higher level such as
“department x is losing money.”
the view cannot make data type assumptions. Some type assumptions are
obvious when the view assumes a data
value is a date, for example, but more
subtle type assumptions ap- pear: If a
template assumes $userID is an
integer, the pro- grammer cannot
change this value to be a non-numeric
in the model without breaking the
template. This rule forbids array
indexing such as colorCode[$topic] and
$name[$ID] The view further cannot
call methods with arguments be- cause
(statically or dynamically) there is
an assumed argu- ment type, unless one
could guarantee the model method
merely treated them as objects.
Besides graphics designers are not
programmers; expecting them to invoke
methods and know what to pass is
unrealistic.
data from the model must not contain display or layout information.
The model cannot pass any display
informa- tion to the view disguised as
data values. This includes not passing
the name of a template to apply to
other data values.
Incidentally, Terence has created his own templating engine called String Template which supposedly does a really good job of enforcing these rules. I have no personal experience with it, but would love to check it out on my next project.
You may want to start by using tag libraries. You can use the standard tag library JSTL to do most of the common things that you need scriplets for. There are many other richer tag libraries that are used like in the struts2 framework or from apache.
e.g.
<c:if test="${your condition}">
Your Content
</c:if>
would replace your if statements.
The preferred alternative to scriptlets is the JSTL expression language; here's a good overview. You'll need to add the taglib like so:
<%# taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c' %>
As an example, JSTL provides a bunch of implicit objects that give you the stuff you need; the one you want is pageContext.request.
So you can replace <%request.getRequestURI%> with ${pageContext.request.requestURI}.
You can do conditionals using <c:if> tags.
You'll need to use some web framework. Or at least some convenient taglib. Or a templating enginge like FreeMarker.
Ad frameworks:
If you like JSP way of coding, then I'd suggest Struts 2.
<s:if test="%{false}">
<div>Will Not Be Executed</div>
</s:if>
<s:elseif test="%{true}">
<div>Will Be Executed</div>
</s:elseif>
<s:else>
<div>Will Not Be Executed</div>
</s:else>
Then there's component-oriented JSF.
If you like OOP and coding everything in Java, try Apache Wicket (my favorite) or Google Web Toolkit.
The c:if test always fails for me and it never gets inside the loop. I am using the following namespaces
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:c="http://java.sun.com/jstl/core"
The string ('array') to be split is "Tom and Jerry are GAP1 friends"
<s:decorate template="/layout/display-text.xhtml">
<c:set var="array" value="#{_mybean.value}"/>
<c:set var="space" value="#{fn:split(array, ' ')}"/>
<c:set var="len" value="#{fn:length(space)}"/>
<h:outputText value="total length = #{len}"/><br/>
<c:forEach begin="0" end="5" var="index">
<h:outputText value="index = #{index}, value = #{space[index]}"/><br/>
<c:set var="val" value="#{space[index]}"/>
<c:if test="#{fn:startsWith(val, 'GAP')}">
<h:outputText value="Found keyword parameter GAP" /><br/>
</c:if>
</c:forEach>
</s:decorate>
The JSTL core URI is invalid. As per the JSTL TLD it should be (note the extra /jsp):
xmlns:c="http://java.sun.com/jsp/jstl/core"
That said, mixing JSF with JSTL is never been a good idea. It won't always give results as you'd expect because they doesn't run in sync as you would expect from the coding. It's more that JSP/JSTL runs from top to bottom first and then hands over the produced result to JSF to process further from top to bottom again. That would cause some specific constructs to fail. Better use pure JSF components/attributes instead.
Instead of c:forEach, rather use Seam's a4j:repeat or Facelets' ui:repeat and instead of c:if make use of the rendered attribute of the JSF component which has to be toggled to show/hide. Instead of all that JSTL c:set, write appropriate code logic in managed bean constructor or action method or getter.
The JSTL functions (fn) taglib is however still highly valuable in JSF. You can keep using it.