Using JSPs
The container looks at your JSP, translates it into Java source code, and compiles it into a fully-fledged Java servlet class, this servlet is alot like any other servlet, except that the servlet class is written for you by the container.
With JSP you can put regular Java code in a JSP using a scriptlet which means Java code within a <% ... %> tag. The one thing to note is that if your Java code needs to use any other class that it is in the classpath just like a normal Java program. You have two options to use other classes within your JSP
JSP Expressions, Variables and Declarations
A directive is away for you to give special instructions to the Container at page translation time, they come in three flavors
page directive example | <%@ page import="foo.*" > <%@ page import="foo.*,java.util.*" %> <%@ page import="foo.*" session="false" %> Note: the <%@ sign means that its a directive |
include | <%@ include file="datadiskHeader.html" %> |
taglib | <%@ taglib tagdir="/WEB-INF/tags/cool" prefix="cool" %> |
13 Page Directive attributes |
|
import | Defines the Java import statements that'll be added to the generated servlet class |
isThreadSafe | Defines whether the generated servlet needs to implement the Single ThreadModel which as you know know is a bad thing |
contentType | Defines the MIME type for the JSP response (default is "text/html") |
isELIgnored | Defines whether EL expressions are ignored when this page is translated |
isErrorPage | Defines whether the current page represents another JSPs error page |
errorPage | Defines a URL to the resource to which uncaught Throwables should be sent |
language | Defines the scripting language used in the scriptlets, expressions and declarations, only java is available at the moment |
extends | Defines the superclass of the class this JSP will become |
session | Defines whether the page will have an implicit session object |
buffer | Defines how buffering is handled by the implicit out object (reference to the jspWriter) |
autoFlush | Defines whether the buffered output is flushed automatically |
info | Defines a String that gets put into the translated page, just so that you can get it using the generated servlets inherited getServletInfo() method |
pageEncoding | Defines the character encoding for the JSP |
One of the points in using JSP is that you don't need to use the println() statement, the expression element automatically prints out whatever you put between the tags
expression element | <% out.println(Counter.getCount()); %> <%= Counter.getCount() %> |
The two above statements are the same, but did you notice the equals sign in the second statement, this is what turns the code into a expression statement, also the Container automatically adds the out.println( ... ); to your statement so there is no need to put a semi-colon on the end of your statement, so never end an expression with a semi-colon.
Scriptlet | <% %> |
Directive | <%@ %> |
Expression | <%= %> |
Instance Declaration | <%! %> Note: talk about this next |
So what happens when to create a simple JSP, here is an example
JSP |
JSP Becomes a Servlet |
<html><body> <% int count=0; %> The page count is now: <%= ++count %> </body></html> |
public class basicCounter_jsp extends SomeSpecialHttpServlet { public void _jspService(HttpServletRequest request, HttpServletResponse response ) throws java.io.IOException, ServletException { PrintWriter out = response.getWriter(); response.setContentType("text/html"); out.write("<html><body>"); int count=0; out.write("The page count is now:"); out.print( ++count ); out.write("</body></html>"); } } |
The problem with the above example is the count will be a local variable, which means that it will get reset every time the servlet is run. JSP declarations are for declaring members of the generated servlet class. That means both variables and methods which means you can declare static variables and methods.
JSP |
JSP Becomes a Servlet |
<html><body> <%! int count=0; %> The page count is now: <= ++count %> </body></html> Note: the ! (bang) character |
public class basicCounter_jsp extends SomeSpecialHttpServlet { Note: count is now an instance variable |
What if you use the same name as a local and a instance variable
use local and instance variables | <html><body> Note: this is pretty much the same as Java |
You can write an JSP knowing that your code is going to be part of a servlet, this means you can take advantage of your servletness, even though you're not directly writing the servlet class yourself., there are a few reasons your JSP might need to use some of what's available to a servlet. All of the implicit objects map to something from the Servlet/JSP API.
API |
Implicit Object |
JspWriter |
out |
HttpServletRequest |
request |
HttpServletResponse |
response |
HttpSession |
session |
ServletContext |
application |
ServletConfig |
config |
Throwable |
exception |
PageContext |
pageContext |
Object |
page |
With any programming you should write comments throughout your code, this helps in maintaining it
HTML Comment | <!-- HTML Comment --> |
JSP Comment | <%-- JSP Comment --%> |
The container generates a class from your JSP that implements the HttpJspPage interface, there are three key methods that you need to know about
jspInit() | This method is called from the init() method and it can be overridden see a override example of this below |
jspDestroy() | This method is called from the servlets destroy() method and it too can be overridden |
_jspService() | This method is called from the servlets service() method which means its runs in a separate thread for each request, the container passes the request and response object to this method. You cannot override this method. |
When you deploy a web application with a JSP, the whole translation and compilation of the JSP happens only once in the JSP's life, the first time it is called. Although this is a big hit for the first user who accesses the JSP, some vendors Containers can perform this translation and compilation in advanced, thus it is ready for the first user
You can do servlet initialization in your JSP, but its slightly different from what you do in a regular servlet.
initialize servlet via JSP | # add to the applications web.xml file <web-app ...> <servlet> <servlet-name>myTestJSPInit</servlet-name> <jsp-file>/TestInit.jsp</jsp-file> <init-param> <param-name>email</param-name> <param-value>sales@datadisk.co.uk</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>myTestJSPInit</servlet-name> <url-pattern>/TestInit.jsp</url-pattern> </servlet-mapping> </web-app> |
using the parameter and overriding jspInit() | # create the file TestInit.jsp <!-- Below are a number of ways to get the web.xml init parameter --> <%-- override the jspInit() method %> <% <% Note: remember that if you change the web.xml it will automatically be picked up |
There are four implicit objects to get and set attributes corresponding to the four attribute scopes available
In a Servlet |
In a JSP |
|
Application | getServletContext().setAttribute("foo",barObj); | application.setAttribute("foo",barObj); |
Request | request.setAttribute("foo",barObj); | request.setAttribute("foo",barObj); |
Session | request.getSession().setAttribute("foo",barObj); | session.setAttribute("foo",barObj); |
Page | does not apply | pageContext.setAttribute("foo",barObj); |
You can use a PageContext reference to get attributes from any scope, including the page scope for attributes bound to the PageContext
Setting a paged-scoped attribute | <% Float one = new Float(42.5); %> <% pageContext.setAttribute("foo", one); %> |
Getting a page-scoped attribute | <%= pageContext.getAttribute("foo") %> |
Using the pageContext to set a session-scoped attribute | <% Float two = new Float(42.5); %> <% pageContext.setAttribute("foo", two, PageContext.SESSION_SCOPE); %> |
Using the pageContext to get a session-scoped attribute | <%= pageContext.getAttribute("foo", PageContext.SESSION_SCOPE ) %> |
Using the pageContext to get an application-scoped attribute | <%= pageContext.getAttribute("mail", PageContext.APPLICATION_SCOPE) %> |
Using the pageContext to find an attribute when you don't know the scope | <%= pageContext.findAttribute("mail") %> Note: find looks from the most restricted to the least restrictive page then request then session and finally application scope. The first one it finds with that name wins. |
Expression Language Introduction
Putting Java code into an JSP is very bad and you should'nt do it, the reason for the above tutorial is that years ago this was the only way to get Java code within your web pages and there are still lots of web pages out there with Java code imbedded that needs to be maintained (hence the tutorial above).
So how do we use Java code with out exposing the code itself within the JSP, the answer is EL (Expression Language), it is now part of the JSP 2.0 spec. EL offers a simpler way to invoke Java code but he code itself belongs somewhere else. That means in a regular old Java class that's either a JavaBean, a class with static methods or something called a Tag Handler.
EL example | # Java Expression (old way don't do now) Please contact: <%= application.getAttribute("mail") %> # EL way please contact: ${applicationScope.mail} |
You can stop all JSP pages from using any scripting elements by using a <scripting-invalid> DD tag, you can even disable EL if you want to
stop JSP from using scripting elements | <web-app ...> ... <jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <scripting-invalid>true</scripting-invalid> <el-ignored>true</el-ignored> </jsp-property-group> </jsp-config> ... </web-app> |
stop using EL | <%@ page isELIgnored="true" %> Note: this takes priority over the DD tag above |
I have a complete topic on Expression Language so pop over and pickup from here.
There is another type of element you can use in a JSP called actions which I discuss in another topic, but here is an example
standard action | <jsp:include page="datadiskFooter.jsp" /> |
not a standard action | <c:set var="rate" value="32" /? |
I have covered six JSP element types, examples are below
Element Type | Example |
directive | <%@ page import="java.util.*" %> |
declaration | <%! int y = 3; %> |
EL Expression | email: ${applicationScope.mail} |
scriptlet | <% Float one = new Float(42.5); %> |
expression | <%= pageContext.getAttribute(foo") %> |
action | <jsp:include page="foo.html" /> |