jsp:param with Java class - java

I have a JSP file that includes another JSP file. The first JSP should pass an instance of a Java class (widget) to the second JSP file.
This is what I have:
The first JSP:
<jsp:include page="/container/SpecialWidget.jsp">
<jsp:param name="widget" value="${widget}"/> // widget is a .Java POJO
</jsp:include>
The second JSP:
${param.widget.id}
The problem is that this code gives an error (it says it doesn't know ID). If I omit the ".id" part, the page prints the Java code for the Java class, which means the class has been transferred correctly. If I change the ${widget} rule of the first page in, for example, ${widget.id} and I try to print ${param.widget}, everything works fine.
My question: Why can't I pass a Java class and directly call upon its attributes? What am I doing wrong?
Edit: error message: Caused by: javax.el.PropertyNotFoundException: Property 'id' not found on type java.lang.String

I managed to fix my problem with the following code:
<c:set var="widget" value="${widget}" scope="request" />
<jsp:include page="/SOMEWHERE/SpecialWidget.jsp"/>
Thank you both for your help:) It saved my day

When you pass the variable ${widget} it is translated at request time to a string (widget.toString()). This value is then passed to the second JSP as a String, not as the original java object.
One approach to access the object's values is setting the parameter's value with the attribute's value:
<jsp:param name="widgetId" value="${widget.id}"/>
Then use the code bellow on the second JSP:
${param.widgetId}
You can also set widget as an request attribute and use it on the second page as ${widget.id} or ${request.widget.id}. I suggest you use the second approach.

<jsp:param> passes the parameter as an HTTP request parameter, which can only be a String. So toString() is called on your widget, and the result of this method is passed as parameter.
You should use a JSP tag, implemented as a tag file, instead of using a JSP include. See http://docs.oracle.com/javaee/1.4/tutorial/doc/JSPTags5.html for how to define an use them.
For example:
Tag definintion, in /WEB-INF/tags/specialWidget.tag:
<%# tag %>
<%# attribute name="widget" required="true" type="the.fully.qualified.name.of.WidgetClass" %>
TODO: add the HTML markup that must be displayed, using ${widget} to access the passed in widget attribute
Tag usage, in any JSP:
<%# taglib prefix="myTags" tagdir="/WEB-INF/tags" %>
...
Tada! I will use the specialWidget tag here, with widget as an attribute:
<myTags:specialWidget widget="${widget}"/>

Related

Embed/nest custom JSP tag to set the attribute value of another HTML tag

I am new to Java and struts and I am working on a project where I need to set the value of an attribute from a custom tag which retrieve the value of a Java property.
...
<cust:urlGeneration porlet="<cust:write property="tgtPortlet"/>">
<a href="<% wsp.write(out) %>"/>the link</a>
<cust:urlGeneration/>
...
This property is set in a Java class depending on the context. This code is in my corresponding java class :
if(isMyFirstUseCase)
screenbean.setTgtPortlet = "portlet.myFirstValue";
else
screenbean.setTgtPortlet = "portlet.mySecondValue";
But it does not work, the portlet attribute is not set correctly (the tag string is not interpreted).
I want the porlet property to be set either with portlet.myFirstValue or portlet.mySecondValue but I do not manage to dynamically set it...
Do I need to escape something or is it simply not possible ? Otherwise anyone has suggestion or alternative solution ?
I can provide any additional information if needed.
Thanks
You cannot nest tags this way; it would require recursive tag processing.
This is the same in XML–you can't use a tag as a property value for another tag.
Attributes should be set using normal JSP EL.
If it can help anyone, I found a workaround using JSLT :
<%# taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
I set an intermediate variable with the value of my java class property using my "write" custom tag (Business requirement) :
<c:set var="varTgtValue"><cust:write property="tgtValue"/></c:set>
Then simply use this new variable to set my JSP tag's property using ${myVar} :
<cust:urlGeneration porlet="${varTgtValue}">
<a href="<% wsp.write(out) %>"/>the link</a>
<cust:urlGeneration/>

Java Server Page Param confusion

When jsp:include or jsp:forward is executed, the included page or forwarded
page will see the original request object, with the original parameters
augmented with the new parameters and new values taking precedence over
existing values when applicable.
For example, if the request has a parameter
Lname=abc and a parameter Lname=xyz is
specified for forward, the forwarded request
will have Lname=xyz, abc.
The new parameter has precedence
Please explain with an example.
Lets understand main difference between jsp:include and jsp:forward.
jsp:include, includes the page inside the current page. So the included page will appear exactly where u have added the jsp command inside the current page.
e.g.
...
<jsp:include page="inc/include.jsp" />
...
but jsp:forward will forward the current page to the forwarded page. Meaning when the current page is called the forwarded page is called immediately after.
e.g.
if (...) { forwarded to pageOne.jsp }
else if (...) { forwarded to pageTwo.jsp }
Now following is the way we can access parameters for both jsp:forward and jsp:include.
jsp:include : we can access parameters using param not by request object.
e.g.
${param.param1}
while in jsp:forward : we can access parameters using request object.
e.g.
request.getParameter("param1")
This is what the main difference between the parameters in jsp:inlcude and jsp:forward. And thus, we are getting new value in jsp:forward (say Lname=xyz).
example:
say we have a parameter Lname=xyz in request object. In current jsp it can be accessed using below code
<%= (String)request.getParameter("Lname"); %> <%-- This will print xyz on jsp --%>
Now, further the same parameter name can be used with jsp:forward, like...
<jsp:forward page="fwd/pageOne.jsp?Lname=abc" />
or
<jsp:forward page="fwd/pageOne.jsp">
<param name="Lname" value="abc"/>
</jsp:forward>
This will result Lname=abc in fwd/pageOne.jsp using request.getParameter() method.
Thanks

Unable to pass none string parameters to TAG files

I'm using JBOSS 4.0.2 with JSP 2.0.
I have created a TAG file with the following directives:
<%# attribute name="id" required="true" %>
<%# attribute name="upgradeAccount" type="com.upc.domain.UpgradeAccountData" %>
However, when I try to pass an object of type UpgradeAccountData to the tag as a parameter it is always resolved as String, for instance :
<wmtags:paymentOptions id="23" upgradeAccount="${upgradeAccountCommand}">
</wmtags:paymentOptions>
in the above example the upgradeAccountCommand is passed as the "${upgradeAccountCommand}" string.( I've check it by defining the the type attribute in the tag as object and printing the object type and it's string value).
I've also made sure that the upgradeAccountCommand in the caller page is an actual UpgradeAccountData object.
What can I do to solve this?
Many Thanks
That should work; it sounds like EL expression evaluation might be turned off? That could be due to <%#page isELIgnored="false"%> in the page, or the webapp is using the 2.3 servlet spec (or earlier).
Try this:
<wmtags:paymentOptions id="23" upgradeAccount="<%=upgradeAccountCommand%>">

How Do I make dynamic-attributes Work in JSP Tag Files?

So according to my JSP reference book, as well as every other reference I can find on the web, I'm supposed to be able to do something like:
<%# tag dynamic-attributes="dynamicAttributesVar" %>
and then when someone uses an attribute that I didn't define in an attribute directive, I should be able to access that attribute from the "dynamicAttributesVar" map:
<%= dynamicAttributesVar.get("someUnexpectedAttribute") %>
However, that doesn't work, at all; I just get a "dynamicAttributesVar cannot be resolved" error when I try.
Now, I did discover (by looking at the generated Java class for the tag) that I can "hack" a working dynamic attributes variable by doing:
<% Map dynamicAttributesVar = _jspx_dynamic_attrs; %>
Now, that hack doesn't work unless I also use the dynamic-attributes parameter on my tag directive, so it seems that the parameter is doing something.
But what I want to know is, how can I make it do what it does for every other JSP user out there?
Just trying to get a badge for answering a four year old question.
I have this problem as well and came across some help at O'Reilly to use JSTL instead of scriptlets.
The original poster could have used this code to get all keys/values:
<c:forEach items="${dynamicAttributesVar}" var="a">
${a.key}="${a.value}"
</c:forEach>
This would get a specific value:
<c:out value="${dynamicAttributesVar['someUnexpectedAttribute']}"/>
Isn't "dynamicAttributesVar" the name of the key in the page context that the dynamic attributes are put into? So you could do
<c:out value="${dynamicAttributesVar.someUnexpectedAttributes}"/>
or if you must use scriptlets:
Map dynamicAttributes = (Map) pageContext.getAttribute("dynamicAttributesVar")
(Disclaimer: I haven't tried it, I've just used dynamic attributes in tags with direct Java implementations... but it seems reasonable)

JSTL, Beans, and method calls

I'm working on a JSP where I need to call methods on object that come from a Bean. The previous version of the page does not use JSTL and it works properly. My new version has a set up like this:
<jsp:useBean id="pageBean" scope="request" type="com.epicentric.page.website.PageBean" />
<c:set var="pageDividers" value="<%= pageBean.getPageDividers() %>" />
<c:set var="numColumns" value="${pageDividers.size()}" />
The variable pageDividers is a List object.
I'm encountering this issue: when I ask for pageDivider's size, an exception is thrown. I know this is a simple JTSL error -- what am I doing wrong?
The error message is:
The function size must be used with a prefix when a default namespace is not specified
How do I correctly access or call the methods of my pageDividers object?
When using the dot operator for property access in JSTL, ${pageDividers.size} (no () needed) results in a call to a method named getSize().
Since java.util.List offers a method called size() (rather than getSize()) you won't be able to access the list length by using that code.
In order to access to a list size, JSTL offers the fn:length function, used like
${fn:length(pageDividers)}
Note that in order to use the fn namespace, you should declare it as follows
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
In addition, the same function can be used with any collection type, and with Strings too.
To access the property of a bean using EL you simply name the property (not invoke the method). So lets say you have a method called getSize() in the bean then
${pageDividers.size}
Notice no ().
EDIT:Sorry...made an error in the original post.

Categories

Resources