Evaluating dynamic EL expressions at runtime in JSP page - java

I am putting together an application and would like to apply "Custom" EL Expressions to sections on the page when it is rendered. This will help me control what parts are displayed on the page given the status of the page. The problem is that the EL Expressions are not being evaluated and treated only as String values. For example
<c:if test="${form.conditionEL}" >
<input type="submit" value="Close">
</c:if>
The value of the ${field.conditionEL} might evaluate to something like "submission.status eq 'COMPLETE'".
So, is there a way to get that string value to be interpreted within the JSP page ?
Thanks for any help in making this happen. Let me know if I missed providing any pertinent information to help resolve.
Environment: Java 8, Tomcat 9, JSP 3.0, Spring
Regards,
Mike

I would simply add the submission status to the page context which let's you simply do:
<c:if test="${submissionStatus eq 'COMPLETE'}" >
<input type="submit" value="Close">
</c:if>

Check whether EL expressions are ignored in your page tag. I've also faced the same issue and this resolved mine.
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" isELIgnored="false" %>

Related

Custom tag that evaluates its body based on the variables of the tag

Ok, now this is something for the hard core JSTL wizards I guess ;-)
I would like to have a tag whose body does not substitute the variables of the surrounding page. It should only take the variables into account that have been specified in the body of the tag or in the tag itself like this:
<c:set var="outsideVar" value="outside value"/>
<a:component>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<div data-component-id="9">
<c:set var="componentId" value="9"/>
<c:set var="path" value='${abc:getCurrentPath()}_${componentId}'/>
<c:set var="resource" value='${abc:getResourceFromPath(path)}'/>
<c:set var="val" value="${resource.getValue('paragraphValue')"/>
<p>${fn:escapeXml(val)}</p>
${outsideVar}
</div>
</a:component>
The outsideVar variable should not be set and the body of the tag should behave like the content of a <jsp:include/>
This is a more specific question of this one:
Is it possible to create a local page scope in a JSP?
The link also explains the background of this question.
Your custom tag can grab and remove all page attributes before evaluating the body, and then clear and restore afterwards.

send parameter from jsp to servlet using jsp:useBean

I am beginner in java and trying to figure out how to send parameter from jsp to servlet using this
inside my jsp -
<%! String option;%>
<% option = request.getParameter("option"); %>
<jsp:useBean id="processBean" scope="session" class="helpers.ProcessBean" />
${processBean.processRequest(option)}
I want to send 'option' to processRequest but this way it is always empty string, so I am doing something wrong.Could not find anything online.
Any help is highly appreciated.
Variable declared/set on the page's scripting language is not automatically available from EL. You can manually make it available via:
<c:set var="option" value="<%= option %>" />
before using it in EL.

How to use Boolean variable in c:if

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.

Why my included JSP file won't get processed correctly?

I am trying (and learning) to build a java web framework, and in the process of developing its' code generator based on the content of the database. In the view making process, I stumble in a difficulty, which I don't know how to solve it.
Firstly, I want all the pages to be created using the following index.jsp :
<body>
<%# include file="header.jsp" %>
<hr/>
<%# include file="body.jsp" %>
<hr/>
<%# include file="footer.jsp" %>
</body>
And, in the body.jsp, I want it to be like this :
<jsp:include page="${application_modul}" %>
Where application_modul is an attribute defined in its' controller this way :
request.setAttribute("application_modul","user_account\\view_user_account.jsp");
It can find the file correctly, but the processed jsp is not what I expected. Here :
<c:forEach items="[application.models.UserAccountModel#18a49e0, application.models.UserAccountModel#1f82982]" var="item" varStatus="status" >
<tr>
....
You can see the items attribute of jstl forEach, got its variable name (toString())...
Any Idea what the problem is????
I hope I describe my problem correctly
Many thanks!
PS :
I already create a quick fix for this, but not what I want it though. In the generated view_user_account.jsp, I do it like this :
<body>
<%# include file="header.jsp" %>
<hr/>
<c:forEach items="${row}" var="item" varStatus="status" >
<tr>
....
<hr/>
<%# include file="footer.jsp" %>
</body>
You can see that I create the whole file here...
EDITED:
PS : ${row} is an ArrayList populated with data from certain table
So, to summarize your problem in a single sentence, JSTL tags are not been parsed and they end up plain in generated HTML output?
You need to declare JSTL taglib in top of the JSP page where you're using JSTL tags to get them to run. For the JSTL core taglib, that'll be
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
I am not sure but, Try this...
index.jsp
<jsp:param name="parameterName" value="{parameterValue | <%= expression %>}" />

JSTL forEach tag: problems with enumeration, and with understanding how it should work

I've experienced rather strange behavior of JSTL forEach tag.
I have some bean called SessionBean:
public class SessionBean {
private Collection<MyObject> objects;
public Collection<MyObject> getObjects() {return objects;}
...
}
And a simple JSP page like that:
<%#page contentType="text/html"%>
<%#page pageEncoding="UTF-8"%>
<%#taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%#taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
<f:view>
<h:form>
<c:forEach var="myObject" items="#{SessionBean.objects}">
<h:outputText value="#{myObject}" /> <br />
</c:forEach>
</h:form>
</f:view>
</body>
And, it doesn't work. Exeption thrown is
javax.servlet.jsp.JspTagException: Don't know how to iterate over supplied "items" in <forEach>
at org.apache.taglibs.standard.tag.common.core.ForEachSupport.toForEachIterator(ForEachSupport.java:255)
at org.apache.taglibs.standard.tag.common.core.ForEachSupport.supportedTypeForEachIterator(ForEachSupport.java:219)
....
Why?
And then I change items="#{SessionBean.objects}" to items="${SessionBean.objects}", and there's no exception. Except for MyObjects aren't printed.
Then, I make the same change to <h:outputText value="#{myObject}" />, and it's invalid value for this attribute.
Finally, replacing JSF outputText tag with just ${myObject} works as expected.
Could somebody explain, what happens here on each phase, please?
U: SessionBean is managed by JSF, and surely was created, for it performs some actions in the header.
RESOLUTION: The problem proved to be due to incompatibility between JSTL and JSF in J2EE 1.4. Switching to J2EE 5 made the first variant work just fine.
Thanks!
This article explains the difference between the unified EL and the EL. Here is a snippet
Evaluation of EL
Evaluation of EL is categorized as immediate evaluation and deferred evaluation. Immediate evaluation means a JSP page evaluates the expression when the page is rendered. With immediate evaluation, all values are always read-only. JSP EL expressions take the form of ${imExpr}. JSP expressions are evaluated immediately.
Deferred evaluation means that the technology using the unified EL takes over the responsibility of evaluating the expression from the JSP engine and evaluates the expression at the appropriate time during the page lifecycle. The EL takes control from the JSP container to evaluate the expression at the appropriate time. JSF EL expressions take the form of #{defExpr}. JSF expressions work in this way.
The following example shows a JSF inputText tag, which represents a text field component into which a user enters a value. The inputText tag's value attribute references an expression that points to the name property of the book bean.
<h:inputText id="name" value="#{student.name}"/>
For an initial request of the page containing this tag, the JSF implementation evaluates the #{student.name} expression during the "render response" phase of the lifecycle. During this phase, the expression merely accesses the value of quantity from the book bean, as is done in immediate evaluation.
For a postback, the implementation evaluates the expression during the "apply request values," "process validations," and "update model" phases, during which the value is retrieved from the request, validated, and propagated to the book bean.
I am wondering if the problem is from the fact that an instance of SessionBean was not created?
Try this:
<jsp:useBean class="packagename.SessionBean" id="sb"/>
<c:forEach var="myObject" items="${sb.objects}">
<h:outputText value="${myObject}" /> <br />
</c:forEach>
[Update] I wonder if this article might help then. It explains how the two EL's work together.

Categories