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

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" />

Related

JSTL doesn't remove variable value

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"/>

Is it possible to create a local page scope in a JSP?

I'm working on a componentization system based on JSPs. This means that parts of the JSP can be moved from one JSP to an other one via drag and drop and leads to a need for a local page scope as variable of a component defined in one JSP my collide in an other JSP.
I can use Servlet 3.0 / JSP 2.2 / JSTL 1.2.
++ Tag File ++
The straight way of doing that would be to create a tag file for a component or something similar as they have this local page scope. But for every change in the tag file it would need to get redeployed and needing to create a tag file needs some time by itself. But if there is no other solution this direction (custom tags, tag files, JSP includes,...) is probably the way to go.
++ Namespace prefixing/suffixing ++
In Portlets one is supposed to concatenate each variable with a namespace provided from the portlet response object. I could do something similar but this can lead to side effects and unexpected behavior. If someone forgets to prefix/suffix the namespace it might work for some time but stops working at an other time without changing the code when the component moved to an other JSP with a conflicting variable name.
++ Custom Tag wrapping ++
I was hoping that I as a component framework developer can wrap the component code of a component developer with a tag file for a component tag like this
<a:component>
<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><c:out value="${value}"/></p>
</div>
</a:component>
to have the variable in the local page context of the tag file. But instead they are in the context of the surrounding page. I'm looking for something like this
<% { %>
<div data-component-id="9">
<%
String componentId = 9;
String path = obj.getCurrentPath()+componentId;
Resource resource = otherObj.getResourceFromPath(path);
String value = resource.getValue("paragraphValue");
%>
<p><c:out value="<%=value%>"/></p>
</div>
<% } %>
which would create a code block in which variables have their own namespace. But of course for JSTL and JSTL-EL instead of scriptlet code.
I had a look at the JSTL specification but did not find out if there is a way to create such a local page scope. But I didn't check everything as it's huge and I'm not sure if it's possible with custom tags.
It is clear to me that bigger code blocks should not be in the JSP but with the framework I would like to provide simple solutions for smaller components.
++ Changing the JSP code ++
When components are initially placed on a JSP or moved around via drag 'n drop I actually move the JSP code of a component from one JSP to an other or within a JSP. This means I can also programmatically manipulate the JSP code of a component if it doesn't get too complex and it helps solving the problem.
As I thought that custom tag wrapping could be the ideal solution I created an other more specific question and I've got an answer here that solves the problem.
It's simply to remove all pageContext attributes before the evaluation of the body and adding them again at doEndTag().

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>

Variable refering in two different jsp pages

If i declare a variable in my A.jsp and i am trying to include A.jsp to B.jsp.So my question stands here whether the variable declared in A.jsp is acessable in B.jsp?
Please explain me for both the cases Dynamic include and static include.
When you include a jsp template using <%#page include=""> the source will actually be inserted and compiled into the including file. This is what makes you able to use variables declared in the parent file.
When doing a "dynamic" include it will use RequestDispatcher.include which will invoke the calling page as a new Servlet. This makes you unable to use declared variables.
I would recommend you to pass variables on the request scope using request.setAttribute("name", obj); when doing this
You can't pass server-side parameters using the <%# include %> directive. This directive does a static include. The contents of the included file are statically inserted into the including page. That is, during translation time from jsp to servlet.
Use the <jsp:include> tag instead, it is processed at runtime, and with it you can pass parameters using <jsp:param>.
For instance, if you have a.jsp with
<jsp:include page="b.jsp" />
<jsp:param name="param1" value="value1" />
<jsp:param name="param2" value="value2" />
</jsp:include>
You can get those parameters as request parameters in b.jsp
<% String v = request.getParameter("param1"); %>
Take into account you can still get request parameters available on a.jsp in b.jsp.

How to access variable set by JSTL core in my JSP page?

In my webapp, I want to set a default cookie to store a locale of 'en_US'. I have functionality in place for the user to change this successfully.
However, I've removed a lot of scriptlets on my .jsp and replaced with some JSTL tags to set a default cookie value, but it doesn't seem to work. It seems that I can't access my ${lang} variable in my locale declaration. Am I missing something?
Here's my code:
<c:set var="lang" scope=="session">
<c:out value="${cookie['locale'].value}" default="en_US"/>
</c:set>
<fmt:setLocale value="${lang}" />
<fmt:bundle basename="com.foo.bar.app">
Edit
It seems as though I'm still having a problem. My setLocale call is not getting a good value. I tried a simple <c:out value="${lang}"/> and it is printing out ${lang} rather than a value, so I assume that my locale is being set to the variable name rather than the value. Any idea?
There's one = too much behind scope.

Categories