Meaning of Jsp thread safe - java

JSP is thread safe by default but What is the meaning when we say
a JSP is thread-safe
?

When a jsp is create is become a servlet in the application server. All the logic runs from jspService method, all the references or variables you have in your jsp become local variables, that is why jsp can be considered thread safe by default.
Check this link to review the jsp lifecycle .
At the end all the code that you have in the jsp will be within the _jspService method.
All the content of your JSP will be inside.
public void _jspService(HttpServletRequest request,
HttpServletResponse response)
throws java.io.IOException, ServletException {

JSP is not thread safe in general! JSP is compiled into servlet and one instance can be used to serve multiple requests, so every class field (modified during the request execution) is considered not being thread safe. How can you declare class field in JSP? Using JSP declaration:
<%! private Object notThreadSafe = new Object(); %>
(BTW you can even declare methods in JSP declarations).
JSP can be thread safe, if you don't use these JSP declarations. Everything else (html/jsp tags, scriptlet code <% /* some code*/ %>, jsp expression <%= "some expression" %>,... ) is being compiled into jspService method as Koitoer has mentioned.

Related

Scriptlets inserts arbitrary code into servlet's _jspService method

Scriptlets let you insert arbitrary code into servlet's _jspService method.
Can anyone explain this statement with an example containing a block of code?
I am aware about syntactical stuff of JSP and Servlets, what I need to know is
In what context arbitrary code is used?
_jspService() is a method of JSP life cycle then,
What does it mean by servlet's method?
A JSP is in fact transformed by the container into a Java class extending HttpServlet, that class is then compiled and executed exactly as a hand-coded servlet would be.
The code you have into the JSP is transformed into Java code that constitutes the _jspService method of the generated servlet. So, for example
<html>
<% String foo = "hello"; out.println(foo); %>
is transformed by the container, into something like
void _jspService(JspWriter out) {
out.println("<html>");
String foo = "hello"; out.println(foo);
}
So, whatever code you write into your scriptlets (arbitrary code) ends up in the _jspService method of the servlet created by the container from the JSP.

JSP implicit objects vs PageContext [duplicate]

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.

Pass JSP variable to a java class method

I have a JSP file named as project.jsp. It contains a variable
String context = request.getcontextpath();
which will deliver context path of my server URL.
/ARUBA-LIB-G3245-KITKAT from http://localhost:8080/ARUBA-LIB-G3245-KITKAT/.
Now I want to access this context variable from my project.jsp file to java class which is in jar format file and resides in WEB-INF/lib/AuthenticateDetails.jar.
How can I access this variable from specified java class file?
The same as in java, an import statement and so on.
<%# page import="java.util.Random"
import="org.authdetails.dao.SomeClass" %>
(Or many imports in one import=... with line break in string.
<% new SomeClass(contextPath); %>
Using the MVC (Model-View-Controller) principle, one normally has a servlet (Controller, compilable!) that prepares the data (Model) and puts the data as request attributes, and then forwards to the JSP (view).
In the JSP you can use EL (Expression Language) variables, where some are predefined to access session variables, request parameters and such.
Combining that with JSP tags, one rarely needs to use <% ... %> scriptlets.
Pass the context path variable to the processing method in the library class (library class should be accessible from the jsp though import directive)

How to access a request attribute set by a servlet in JSP?

I'm trying to retrieve attribute values set by a servlet in a JSP page, but I've only luck with parameters by ${param}. I'm not sure about what can I do different. Maybe its simple, but I couldn't manage it yet.
public void execute(HttpServletRequest request, HttpServletResponse response) {
//there's no "setParameter" method for the "request" object
request.setAttribute("attrib", "attribValue");
RequestDispatcher rd = request.getRequestDispatcher("/Test.jsp");
rd.forward(request,response);
}
In the JSP I have been trying to retrieve the "attribValue", but without success:
<body>
<!-- Is there another tag instead of "param"??? -->
<p>Test attribute value: ${param.attrib}
</body>
If I pass a parameter through all the process (invoking page, servlets and destination page), it works quite good.
It's available in the default EL scope already, so just
${attrib}
should do.
If you like to explicitly specify the scope (EL will namely search the page, request, session and application scopes in sequence for the first non-null attribute value matching the attribute name), then you need to refer it by the scope map instead, which is ${requestScope} for the request scope
${requestScope.attrib}
This is only useful if you have possibly an attribute with exactly the same name in the page scope which would otherwise get precedence (but such case usually indicate poor design after all).
See also:
Our EL wiki page
Java EE 6 tutorial - Expression Language
Maybe a comparison between EL syntax and scriptlet syntax will help you understand the concept.
param is like request.getParameter()
requestScope is like request.getAttribute()
You need to tell request attribute from request parameter.
have you tried using an expression tag?
<%= request.getAttribute("attrib") %>
If the scope is of request type, we set the attribute using request.setAttribute(key,value) in request and retrieve using ${requestScope.key} in jsp .

Calling a java method in jsp

I have a java class which performs some operations on files. Since the java code is huge I don't want to write this code in jsp. I want to call the methods in jsp whenever required.
Please tell me the path where I need to keep this file. Also some example code how to use it would be helpful.
In the servlet (which runs before the JSP):
Person p = new Person(); // instantiate business object
p.init(...); // init it or something
request.setAttribute("person", p); // make it available to the template as 'person'
In the template you can use this:
your age is: ${person.age} <%-- calls person.getAge() --%>
I think the question is, how do you make Java code available to a JSP? You would make it available like any other Java code, which means it needs to be compiled into a .class file and put on the classpath.
In web applications, this means the class file must exist under WEB-INF/classes in the application's .war file or directory, in the usual directory structure matching its package. So, compile and deploy this code along with all of your other application Java code, and it should be in the right place.
Note you will need to import your class in the JSP, or use the fully-qualified class name, but otherwise you can write whatever Java code you like using the <% %> syntax.
You could also declare a method in some other utility JSP, using <%! %> syntax (note the !), import the JSP, and then call the method declared in such a block. This is bad style though.
Depending on the kind of action you'd like to call, there you normally use taglibs, EL functions or servlets for. Java code really, really doesn't belong in JSP files, but in Java classes.
If you want to preprocess a request, use the Servlet doGet() method. E.g.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Preprocess request here.
doYourThingHere();
// And forward to JSP to display data.
request.getRequestDispatcher("page.jsp").forward(request, response);
}
If you want to postprocess a request after some form submit, use the Servlet doPost() method instead.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Postprocess request here.
doYourThingHere();
// And forward to JSP to display results.
request.getRequestDispatcher("page.jsp").forward(request, response);
}
If you want to control the page flow and/or HTML output, use a taglib like JSTL core taglib or create custom tags.
If you want to execute static/helper functions, use EL functions like JSTL fn taglib or create custom functions.
Although I'll not advice you to do any java calls in JSP, you can do this inside your JSP:
<%
//Your java code here (like you do in normal java class file.
%>
<!-- HTML/JSP tags here -->
In case you're wondering, the <% ... %> section is called scriptlet :-)
Actually, jsp is not the right place to 'performs some operations on files'. Did you hear about MVC pattern?
If you still interested in calling java method from jsp you can do it, for example:
1. <% MyUtils.performOperation("delete") %> (scriptlet)
2. <my-utils:perform operation="delete"/> (custom tag)
Anyway I recomend you to google about scriptlets, jsp custom tags and MVC pattern.
Best Regards, Gedevan

Categories