When we can access all the implicit variables in JSP, why do we have pageContext ?
My assumption is the following: if we use EL expressions or JSTL, to access or set the attributes we need pageContext. Let me know whether I am right.
You need it to access non-implicit variables. Does it now make sense?
Update: Sometimes would just like to access the getter methods of HttpServletRequest and HttpSession directly. In standard JSP, both are only available by ${pageContext}. Here are some real world use examples:
Refreshing page when session times out:
<meta http-equiv="refresh" content="${pageContext.session.maxInactiveInterval}">
Passing session ID to an Applet (so that it can communicate with servlet in the same session):
<param name="jsessionid" value="${pageContext.session.id}">
Displaying some message only on first request of a session:
<c:if test="${pageContext.session['new']}">Welcome!</c:if>
note that new has special treatment because it's a reserved keyword in EL, at least, since EL 2.2
Displaying user IP:
Your IP is: ${pageContext.request.remoteAddr}
Making links domain-relative without hardcoding current context path:
login
Dynamically defining the <base> tag (with a bit help of JSTL functions taglib):
<base href="${fn:replace(pageContext.request.requestURL, pageContext.request.requestURI, pageContext.request.contextPath)}/">
Etcetera. Peek around in the aforelinked HttpServletRequest and HttpSession javadoc to learn about all those getter methods. Some of them may be useful in JSP/EL as well.
To add to #BalusC's excellent answer, the PageContext that you are getting might not be limited to what you see in the specification.
For example, Lucee is a JSP Servlet that adds many features to the interface and abstract classes. By getting a reference to the PageContext you can gain access to a lot of information that is otherwise unavailable.
All 11 implicit EL variables are defined as Map, except the pageContext variable.
pageContext variable provides convenient methods for accessing request/response/session attributes or forwarding the request.
Related
There are following scopes in JSP:
page scope
request scope
session scope
application scope
I am confused about page scope. Can anybody tell me what is this page scope? I have not found its clear definition anywhere.
page scope means, it can be thought of as an object that represents the entire JSP page,i.e. the JSP object can be accessed only from within the same page where it was created.
The page object is really a direct synonym for the this object.
Note:
The main difference between page scope and request scope(often confusing ) is that page scope attributes are no longer available if the request is forwarded to another JSP page where as request scope attributes are available.
The page scope indicates that, in addition to
being bound to a local variable, the bean object should be placed in
the javax.servlet.jsp.PageContext object for the duration of the current request.
Acording to Allamaraju (2004):
JSP defines four scopes for the objects that can be used by the JSP authors:
page - Objects can be accessed only within the JSP page in which they are referenced.
request - Objects can be accessed within all the pages that serve the current request. These include pages that are forwarded to, and included in, the original JSP page to which the request was routed.
session - Objects can only be accessed within the JSP pages accessed within the session for which the objects are defined.
application - Application scope objects can be accessed by all JSP pages in a given context.
Storing the object there means that servlet code can access it by
calling getAttribute() on the predefined pageContext variable. Since every page and every request has a different PageContext object, this indicates that the bean is not shared and thus a new bean will be created for each request.
References
Allamaraju, S. (2004). Professional Java Servlets 2.3. Berkeley, Calif: Apress.
We often do the following inside the scriptlet:
<%
request.getCookies();
%>
Can anyone tell me, what is request here? I know it represents HttpServletRequest but I haven't declared it. I just do not understand this.
request is a variable of type HttpServletRequest that is declared and initialized for you in the code generated by the servlet container when the JSP code is transformed into a Servlet class and compiled, it also known as one of implicit objects in JSP.
Note that using scriptlets in JSP is bad practice for years. You should learn JSP EL, the JSTL, and choose an MVC framework that allows separating the Java code for the pure markup-generation code.
In Expression Language, I can access my model like so: ${model.member}
How do I achieve the same thing when I want to use <%=some_method(${model.member}); %>
The reason is because I have some HTML helper methods I created to separate logic from UI, and I need to pass a member of the model to create the user control.
The JSP's main method has the following signature:
_jspService(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, java.io.IOException
Based on this, you can access the request and response objects programattically from a scriptlet. For example:
<%= request.getParameter("foo").toString() %>
or
<%= request.getAttribute("bar").toString() %>
If you want to do something more complication, you could precede these with scriptlets to declare / initialize local (Java) variables; e.g.
<% String foo = request.getParameter("foo") == null ?
"no foo" : request.getParameter("foo").toString(); %>
<%= foo %>
You can use this to lookup your model in the request or response object (I think it will be an attribute of the request with name "model"), cast it to the appropriate type, and call its getter methods.
The reason is because I have some HTML helper methods I created to separate logic from UI, and I need to pass a member of the model to create the user control.
A better idea would be to turn those helper methods into custom JSP tags so that you can use them without resorting to scriptlets. JSPs with embedded scriptlets are generally thought to be hard to read and hard to maintain. One small mistake (or one change to the model API) and the JSP generates bad Java on your deployment platform and you get a broken page.
Take a look at JSTL custom functions. It allows a way for you to call static functions from your code in a JSTL standard way. You just need to set then up in your tld file.
I am using Servlet and JSP without a framework to study for my SCWCD. I have a simple form that I want the parameters to bind to a bean automatically. Is this possible without writing binding code or using a framework?
Thanks
Well, without a "framework" you can't do this. But you can use the Jakarta BeanUtils (http://commons.apache.org/beanutils/), more precisely the static method BeanUtils.populate in your servlet. Ex.:
BeanUtils.populate (myBean, request.getParameterMap());
Remember: the input properties names must match with bean attributes, ok?
You can do this with <jsp:useBean>.
<jsp:useBean id="form" class="com.example.Form" scope="request" />
<jsp:setProperty name="form" property="*" />
<jsp:include page="servletUrl" />
All bean properties whose names match the request parameter names -if any- will be set and the bean will be available as request attribute in the servlet matching the url-pattern of /servletUrl.
However, you'd like to use a servlet and/or MVC framework for this since it abstracts it all away and gives a better control over actions and response handling. This is essentially abuse of JSP (as being a view technology) as controller (which should be (in)directly done by a Servlet).
No, it isn't. You should use some framework, which I guess would be an overkill.
So what you can do, is iterate request.getParameterMap() keys and set the values to object with the corresponding field names (via reflection)
I've come across a few other questions that describe a similar, but not identical situation, to mine. This question, for instance, shows pretty much the same problem, except that I'm not using portlets - I'm just using boring ol' JSP+JSTL+EL+etc.
I have two application contexts, and I'd like to import a JSP from one to the other. I know how do that:
<c:import context="/" url="/WEB-INF/jsp/foo.jsp"/>
However, I also want to pass a parameter to the imported foo.jsp. But this code:
<c:import context="/" url="/WEB-INF/jsp/foo.jsp">
<c:param name="someAttr" value="someValue"/>
</c:import>
does not seem to properly send the parameter to foo.jsp; if foo.jsp is something like*
<% System.out.println("foo.jsp sees that someAttr is: "
+ pageContext.findAttribute("someAttr")); %>
then this gets printed out:
foo.jsp sees that someAttr is: null
whereas I want to see this:
foo.jsp sees that someAttr is: someValue
so, obviously, someAttr can't be found in foo.jsp.
How do I fix this?
*(yes, I know, scriplets==bad, this is just for debugging this one problem)
You're setting it as a request parameter, so you should also be getting it as request parameter.
Since you seem to dislike scriptlets as well, here's an EL solution:
${param.someAttr}
Note that <c:import> doesn't add any extra advantages above <jsp:include> in this particular case. It's useful whenever you want to import files from a different context or an entirely different domain, but this doesn't seem to be the case now. The following should also just have worked:
<jsp:include page="/WEB-INF/jsp/foo.jsp">
<jsp:param name="someAttr" value="someValue" />
</jsp:include>
This way the included page has access to the same PageContext and HttpServletRequest as the main JSP. This may end up to be more useful.