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

4

27

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.

Petrick answered 17/5, 2013 at 22:57 Comment(0)
I
37

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:

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.
Isomerize answered 17/5, 2013 at 23:10 Comment(3)
This did in fact work. Can I ask for a more technical explanation of what is going on here? Why does the jsp:include not have access to a variable set within the parent? Last question: Is this the right way to accomplish what I am trying to do?Petrick
Super helpful. Thank you for taking the time to provide these details!Petrick
@LuiggiMendoza there is a small typo in sentence "There are four scopes in JS known as context:" - there should be JSP instead of JS. I was thinking for a second that suddenly we are talking about JavaScript :-)Unwholesome
I
4

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/>
Instar answered 28/8, 2015 at 16:7 Comment(0)
L
3

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}" />
Lawmaker answered 17/5, 2013 at 23:11 Comment(1)
No need to add requestScope since ${} already searches the variable in all the scopes attributes.Isomerize
E
0

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>
Edraedrea answered 4/9, 2019 at 12:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.