JSTL doesn't remove variable value - java

I'm trying to clean a list of objects that my JSP File receives, and I execute the following command:
<c:remove var="list" scope="session" />
<c:out value="${list}"></c:out>
But when I call the JSP page, the page shows the memory address of the list that should have been deleted and fill normally the HTML elements with the attributes of objects that are defined in the list.
EDIT
I'm using my own tag, can it influence? Object contains list.
<ec:form beanName="object" controllerUrl="/param1/param2">
And if I remove the object with:
<c:remove var="object">
Raises NullPointerException
References:
http://www.java2s.com/Tutorial/Java/0380__JSTL/RemoveVariable.htm

Here I am not sure in which scope your attribute lives.So i would suggest to
Try this
<c:remove var="list"/>
This above code removes an attribute from all the scopes (page, session, application, request). In order to be specific we must need to specify the scope attribute inside tag.The below JSTL statement will remove the variable list from session scope.
<c:remove var="list" scope="session"/>

Related

Setting output of layout-render to a variable (stripes)

I'm trying to reuse a variable that's been set in a jsp and used in a Stripes layout-render.
Main page: /index.jsp
Layout Render page: /jsp/widgets/signin/oAuthUrl.jsp
My /jsp/widgets/signin/oAuthUrl.jsp has a c:set variable called ${oauth_url}. But when I call the layout-render page via s:layout-render name="/jsp/widgets/signin/oAuthUrl.jsp", I would expect to be able to use any variables that are in there, as if I was including that script. But I can't use that ${oauth_url} in index.jsp.
I've even tried doing this, which unsurprisingly doesn't work:
<c:set var="oauth_url" value="<s:layout-render name="/jsp/widgets/signin/oAuthUrl.jsp"
buttonType="signup"/>"/>
<s:link href="${oauth_url}">
How can I reuse a variable that's being set in /jsp/widgets/signin/oAuthUrl.jsp? Basically, how can I make it global to the index.jsp page so it can be used in other places?
If I want to just use c:set values declared in /jsp/widgets/signin/oAuthUrl.jsp, should I import with a different tag instead of s:layout-render? I still want to pass it some attributes - like buttonType.
By default variables set with <c:set ... /> have the page scope and will not be available outside that page.
To make a variable available to other templates higher up the nesting hierarchy for a request, use the request scope:
<c:set var="…" value="…" scope="request" />

JSP passing arrays as parameters adds square brackets to first and last element

I'm developing a spring mvc3 app and encountered the following situation:
I return through a ModelAndView object 2 items :
jobs = ArrayList
departments = ArrayList into Page1.jsp
When I print the objects in Page1 i get :
for all of them:
${jobs} -> [ADMIN, CLERK, DEPARTMENT_MANANGER, DIVISION_MANAGER]
and individually I get them well, each one on a line
<c:forEach items="${jobs}" var="job">
<h6>${job}</h6>
</c:forEach>
The problem is when I include page2.jsp and send those arrays as parameters.
<jsp:include page="page2.jsp" >
<jsp:param name="jobs" value="${jobs}" />
<jsp:param name="departments" value="${departments}" />
</jsp:include>
and try to print those elements again I get brackets in the first and last elements. (I've accessed the arrays correctly with param.jobs .. )
for all of them : [ADMIN, CLERK, DEPARTMENT_MANANGER, DIVISION_MANAGER]
each one individually:
[ADMIN
CLERK
DEPARTMENT_MANANGER
DIVISION_MANAGER]
Does anybody know why this happens and how I can avoid that?
Later edit:
Also, when I iterate through the departments which are supposed to be objects in page2.jsp and try to print their name ($dept.name, which in page1.jsp works fine) i get :
javax.el.PropertyNotFoundException: Property 'name' not found on type java.lang.String
which is a clear indicator that they are passed as Strings.
How can I have them as Objects as in page1.jsp?
Thanks :)
I've found some sort of workaround..
<c:set var="allJobs" value="${jobs}" scope="request" />
and then I can access them as ${allJobs}
Not sure if this is the most orthodox way though..
You can only pass Strings as request parameters, but you can set any kind of object as request attributes. Request scope (not page scope) beans should also work.
Try setting the values using jstl,
<c:set var="type1" value="${jobs}" />
<jsp:include page="index.html">
<jsp:param name="jobs" value="${type1}" />
</jsp:include>
Hope this helps!!

How to pass parameter to jsp:include via c:set? What are the scopes of the variables in JSP?

I have this on welcome.jsp
<c:set var="pgTitle" value="Welcome"/>
<jsp:include page="/jsp/inc/head.jsp" />
And this in head.jsp:
<title>Site Name - ${pgTitle}</title>
But the variable is blank, and the output is merely
Site Name -
I have read many articles, and I cannot figure out what the problem is. If I echo ${pgTitle} elsewhere within the same welcome.jsp, then it outputs fine.
I am including the core tag library on both pages.
This is because the pgTitle variable is set in page scope. Check it here(sorry I can't get an official documentation for this).
If you want to make this work, you have to set the variable in request scope at least. To set your variable in request scope, use the scope attribute on <c:set>:
<c:set var="pgTitle" value="Welcome" scope="request" />
Per your comment, in web development, the scope of the variables matter because it defines where the variable can be used (similar to a variable declared as field in a class and a variable declared locally in a method). There are four scopes in JSP known as context:
Page scope (handled by PageContext). The variables can only be reached if set as attributes in the current page. This means, only current page can access these attributes, included pages are different pages, so they can't access these attributes.
Request scope (handled by ServletRequest). The variables can only be reached if set as attributes in the current request. This means, every page handled in the same request can access to these attributes. Important Note: A redirect implies a new request/response process. This means, if you set attributes on the request and execute a redirect, these attributes won't be set as attributes on the new request.
Session scope (handled by HttpSession). The variables can only be reached if set as attributes in the current user session. This means, every page used in the same user session can use these attributes until they are removed or the session expires.
Application scope (handled by ServletContext). The variables can only be reached if set as attributes in the current context. This means, every page on every session attribute can access to these variables until they are removed from SessionContext or the web application is undeployed.
More info:
What are the different scopes in JSP?
Is this the right way to accomplish what I am trying to do?
If there's a Servlet or another controller that handles the attributes to be set in the request (e.g. #Controller from Spring MVC or JSF managed bean), then set the attribute there and not in your page directly.
Personally, it takes some time to earn experience and define the best scope of the variables when used on web applications. Basic examples:
The split of a String by comma for presentation purposes will affect only to current view, so this can be set in page scope.
Error and successful messages are best suited in request scope. If user updates the page, he/she probably must not see the same messages unless the data is re-processed.
User info as name, nickname and preferences can be set in session scope.
If you have to display a list of Countries (that should not change in few days), you can store this list in application scope.
One way is to pass variables to an include via query params:
<jsp:include page="/WEB-INF/views/partial.jsp?foo=${bar}" />
<jsp:include page="/WEB-INF/views/partial.jsp">
<jsp:param name="foo" value="${bar}" />
<jsp:param name="foo2" value="${bar2}" />
</jsp:include>
You can then access those params with ${param.foo}
Another would be to use custom tags:
/WEB-INF/tags/head.tag
<%# attribute name="title" %>
<head>
<title>${title}</title>
</head>
somePage.jsp
<%# taglib prefix="layout" tagdir="/WEB-INF/tags" %>
<html>
<layout:head title="myRadTitle" />
<body></body>
<html/>
You have to set the variable to be (at least) request scoped. You can do id as follows:
<c:set var="pgTitle" value="Welcome" scope="request"/>
<jsp:include page="/jsp/inc/head.jsp" />
And then, in the head.jsp, you can output the variable like this:
<c:out value="${requestScope.pgTitle}" />
You can accomplish this by using a combination of <c:import> and <c:param>.
somePage.jsp
<c:import url="header.jsp" >
<c:param name="pageTitle" value="Whatever the title of the page is"/>
</c:import>
header.jsp
<html>
<head>
<title>
<c:out value="${param.pageTitle}" default="Default is optional" />
</title>
</head>
</html>

How to access servlet-context in jsp/struts2?

I have a HashMap<Long, ClientProperties> that I'm putting on the ServletContext at startup.
//During application-startup:
//getProperties() returns HashMap<Long, ClientProperties>
context.setAttribute("clientProps", clientManager.getProperties());
ClientProperties is a POJO with 5 attributes that i need to access in my jsp.
Basicly I need to get the correct POJO (by HashMap-key) and access its properties in my jsp.
More spesific (for example purposes), one of the POJO attributes is clientLogo
In my jsp i now have:
<img src="<c:url value='/images/logo.png'/>" alt="Logo">
I need to replace the path to the logo-file with the clientLogo-property of the POJO.
The HashMap-key to use should be extracted from the User-object stored in the session. It can be retrieved like this: ${sessionScope['user'].clientId}
Any ideas?
Using struts2 and spring btw if that matters.
To get an attribute foo from the servlet context, you use the same syntax as to get it from the session, but replace sessionScope by applicationScope.
But you have so many nested things here that you should define variables:
<c:set var="map" value="${applicationScope['clientProps']}"/>
<c:set var="mapKey" value="${sessionScope['user'].clientId}"/>
<c:set var="pojo" value="${map[mapKey]}"/>
<c:set var="clientLogo" value="${pojo.clientLogo}"/>
<c:url value="${clientLogo}"/>
Note that this is typically the kind of hard work that you should not have to do in the view. Implement the retrieval of the image path in the controller, in Java, and make it available as a property of your action/form, and access it directly from your view.

using EL inside java tag

I have an attribute which I have forwarded from a servelet to a jsp file and while I can use this object with EL I'd like to know how to access it inside the java tags. An example is something like the following:
Searching for "${search_phrase}" returned
<c:forEach var="video" items="${results}">
${video.getVideoName()}
${video.getVideoID()}
</c:forEach>
So results here is an ArrayList of type Video which is forwarded from a servlet to a jsp
I would like to access this ArrayList inside <% %> tags in order to perform some more involved tasks that I cant do with EL.
Anybody know how to do this?
On a side note, this ArrayList I'm creating could potentially get large. Where is this stored? On the server or in some users temp files? If it's stored in server memory does it get cleaned after some period of time / an event such as the user that requested the ArrayList closes connection to server?
It all depends where you stored the list. If you stored it in a request attribute (and not anywhere else), then it will be eligible to garbage-collection when the request has been handled.
If you stored it in a session attribute, then it will be stored in the server memory (and/or the file system or the database depending on the container configuration) until the session times out or is invalidated, or until you remove it. HTTP is a stateless protocol. The user doesn't have a connection to the server.
Java code between <% %> is not a java tag. It's scriptlet, and should not be used in a JSP. If you need to do something that EL or JSP tags can't do easily, then either
write a custom JSP tag yourself, put the Java code in this JSP tag, and invoke the tag from the JSP, or
or write a custom EL function, and invoke this function from the JSP
or prepare the work in a controller (servlet, MVC framework action) before dispatching to the JSP, so that the JSP can generate the markup easily.
The list is accessible using the getAttribute method corresponding to the setAttribute method you used to store the list:
HttpServletRequest.setAttribute() --> HttpServletRequest.getAttribute()
HttpSession.setAttribute() --> HttpSession.getAttribute()
ServletContext.setAttribute() --> ServletContext.getAttribute()
I think you should use something like
<c:forEach var="video" items="${results}">
<c:forEach var="videoType" items="${video.types}"> //suppose videoType is an object
<c:out value="${videoTypeDetails}" />
</c:forEach>
</c:forEach>

Categories