Welkom bij de JSP Voorbeeld Tutorial voor Beginners. In de laatste paar berichten heb ik veel geschreven over Java Servlet en kregen we een zeer goede respons van onze lezers. Daarom ben ik een andere serie gestart over JSP-tutorials en dit is het eerste bericht van de serie.
JSP Voorbeeld Tutorial
In deze JSP-voorbeeldtutorial zullen we kijken naar de basisprincipes van JSP, de voordelen van JSP ten opzichte van Servlets, Levenscyclus van JSP, JSP API-interfaces en -klassen en waar we JSP-bestanden kunnen plaatsen in de webtoepassing. We zullen ook kijken naar de JSP-opmerkingen, Scriptlets, Directives, Expression, Declaration en JSP-attributen in kort detail. Sommige van deze onderwerpen zijn erg belangrijk en we zullen ze in meer detail bekijken in toekomstige berichten.
JSP Tutorial
- Wat is JSP en waarom hebben we JSP nodig?
- Voordelen van JSP ten opzichte van Servlets?
- Levenscyclus van JSP-pagina
- Levenscyclusmethoden van JSP
- Eenvoudig JSP-voorbeeld met Eclipse en Tomcat
- JSP-bestandslocatie in webtoepassingsWAR-bestand
- JSP API-interfaces en -klassen
- JspPage-interface
- HttpJspPage-interface
- JspWriter-abstracte klasse
- JspContext-abstracte klasse
- PageContext-abstracte klasse
- JspFactory-abstracte klasse
- JspEngineInfo-abstracte klasse
- ErrorData-finale klasse
- JspException-klasse
- JspTagException-klasse
- SkipPageException-klasse
-
JSP getransformeerd Servlet-broncode en Locatie van het klassebestand in Tomcat
-
Wat is JSP en waarom hebben we JSP nodig?
JSP (JavaServer Pages) is server-side technologie om dynamische Java webapplicaties te maken. JSP kan worden beschouwd als een uitbreiding op servlettechnologie omdat het functies biedt om gemakkelijk gebruikersweergaven te maken. Een JSP-pagina bestaat uit HTML-code en biedt de mogelijkheid om Java-code toe te voegen voor dynamische inhoud. Omdat webapplicaties veel gebruikersschermen bevatten, worden JSP’s veel gebruikt in webapplicaties. Om de kloof tussen Java-code en HTML in JSP te overbruggen, biedt het extra functies zoals JSP-tags, expressietaal, aangepaste tags. Dit maakt het gemakkelijk te begrijpen en helpt een webontwikkelaar snel JSP-pagina’s te ontwikkelen.
-
Voordelen van JSP ten opzichte van Servlets?
- We kunnen ook HTML-reactie genereren vanuit servlets, maar het proces is omslachtig en foutgevoelig. Bij het schrijven van een complexe HTML-reactie kan schrijven in een servlet een nachtmerrie zijn. JSP helpt in deze situatie en biedt ons de flexibiliteit om een normale HTML-pagina te schrijven en onze Java-code alleen toe te voegen waar dat nodig is.
- JSP biedt aanvullende functies zoals tagbibliotheken, expressietaal, aangepaste tags die helpen bij snellere ontwikkeling van gebruikersweergaven.
- JSP-pagina’s zijn eenvoudig te implementeren. We hoeven alleen de gewijzigde pagina in de server te vervangen en de container zorgt voor de implementatie. Voor servlets moeten we het hele project opnieuw compileren en implementeren. Eigenlijk vullen Servlets en JSPs elkaar aan. We zouden Servlet moeten gebruiken als server-side controller en om te communiceren met modelklassen, terwijl JSPs moeten worden gebruikt voor de presentatielaag.
-
Levenscyclus van JSP-pagina
De levenscyclus van JSP wordt ook beheerd door de container. Meestal bevat elke webcontainer die een servletcontainer bevat ook een JSP-container voor het beheren van JSP-pagina’s. De fasen van de levenscyclus van JSP-pagina’s zijn:
- Vertaling – JSP-pagina’s zien er niet uit als normale Java-klassen, eigenlijk analyseert de JSP-container de JSP-pagina’s en vertaalt ze om overeenkomstige servlet-broncode te genereren. Als de JSP-bestandsnaam home.jsp is, wordt deze meestal genoemd als home_jsp.java.
- Compilatie – Als de vertaling succesvol is, compileert de container het gegenereerde servlet-bronbestand om een klassebestand te genereren.
- Klasse laden – Zodra JSP wordt gecompileerd als servletklasse, is de levenscyclus vergelijkbaar met servlet en wordt deze in het geheugen geladen.
- Instantiecreatie – Nadat de JSP-klasse in het geheugen is geladen, wordt het object ervan geïnstantieerd door de container.
- Initialisatie – De JSP-klasse wordt vervolgens geïnitialiseerd en het verandert van een normale klasse naar servlet. Na initialisatie worden ServletConfig- en ServletContext-objecten toegankelijk voor de JSP-klasse.
- Verzoekverwerking – Voor elk clientverzoek wordt een nieuwe thread gestart met ServletRequest en ServletResponse om het HTML-antwoord te verwerken en te genereren.
- Vernietiging – Laatste fase van de JSP-levenscyclus waarin het uit het geheugen wordt gelost.
-
Levenscyclusmethoden van JSP
JSP-levenscyclusmethoden zijn:
- jspInit() gedeclareerd in de JspPage-interface. Deze methode wordt slechts één keer in de JSP-levenscyclus opgeroepen om configuratieparameters te initialiseren.
- _jspService(HttpServletRequest request, HttpServletResponse response) gedeclareerd in de HttpJspPage-interface en verantwoordelijk voor het afhandelen van clientverzoeken.
- jspDestroy() gedeclareerd in de JspPage-interface om de JSP uit het geheugen te verwijderen.
-
Eenvoudig JSP-voorbeeld met Eclipse en Tomcat
We can use Eclipse IDE for building dynamic web project with JSPs and use Tomcat to run it. Please read [Java Web Applications](/community/tutorials/java-web-application-tutorial-for-beginners#first-web-app-servlet) tutorial to learn how can we easily create JSPs in Eclipse and run it in tomcat. A simple JSP example page example is: `home.jsp`
```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>First JSP</title>
</head>
<%@ page import="java.util.Date" %>
<body>
<h3>Hi Pankaj</h3><br>
<strong>Current Time is</strong>: <%=new Date() %>
</body>
</html>
```
If you have a simple JSP that uses only JRE classes, we are not required to put it as WAR file. Just create a directory in the tomcat webapps folder and place your JSP file in the newly created directory. For example, if your JSP is located at apache-`tomcat/webapps/test/home.jsp`, then you can access it in browser with URL `https://localhost:8080/test/home.jsp`. If your host and port is different, then you need to make changes in URL accordingly.
We can place JSP files at any location in the WAR file, however if we put it inside the WEB-INF directory, we wont be able to access it directly from client. We can configure JSP just like servlets in web.xml, for example if I have a JSP example page like below inside WEB-INF directory: `test.jsp`
```
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Test JSP</title>
</head>
<body>
Test JSP Page inside WEB-INF folder.<br>
Init Param "test" value =<%=config.getInitParameter("test") %><br>
HashCode of this object=<%=this.hashCode() %>
</body>
</html>
```
And I configure it in web.xml configuration as:
```
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>FirstJSP</display-name>
<servlet>
<servlet-name>Test</servlet-name>
<jsp-file>/WEB-INF/test.jsp</jsp-file>
<init-param>
<param-name>test</param-name>
<param-value>Test Value</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>/Test.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Test1</servlet-name>
<jsp-file>/WEB-INF/test.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>Test1</servlet-name>
<url-pattern>/Test1.do</url-pattern>
</servlet-mapping>
</web-app>
```
Then I can access it with both the URLs https://localhost:8080/FirstJSP/Test.do and https://localhost:8080/FirstJSP/Test1.do Notice that container will create two instances in this case and both will have their own servlet config objects, you can confirm this by visiting these URLs in browser. For Test.do URI, you will get response like below.
```
Test JSP Page inside WEB-INF folder.
Init Param "test" value =Test Value
HashCode of this object=1839060256
```
For Test1.do URI, you will get response like below.
```
Test JSP Page inside WEB-INF folder.
Init Param "test" value =null
HashCode of this object=38139054
```
Notice the init param value in second case is null because it's not defined for the second servlet, also notice the hashcode is different. If you will make further requests, the hashcode value will not change because the requests are processed by spawning a new thread by the container. Did you noticed the use of **config** variable in above JSP example but there is no variable declared, it's because its one of the 9 implicit objects available in JSP page, read more about them at [**JSP Implicit Objects**](/community/tutorials/jsp-implicit-objects "JSP Implicit Objects with Examples").
All the core JSP interfaces and classes are defined in `javax.servlet.jsp` package. Expression Language API interfaces are classes are part of `javax.servlet.jsp.el` package. JSP Tag Libraries interfaces and classes are defined in `javax.servlet.jsp.tagext` package. Here we will look into interfaces and classes of Core JSP API.
-
JspPage Interface
Het JspPage-interface breidt het Servlet-interface uit en declareert de levenscyclusmethoden jspInit() en jspDestroy() van de JSP-pagina’s.
-
HttpJspPage Interface
HttpJspPage-interface beschrijft de interactie die een implementatieklasse van een JSP-pagina moet vervullen bij gebruik van het HTTP-protocol. Dit interface declareert de servicemethode van de JSP-pagina voor het HTTP-protocol als public void _jspService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException.
-
JspWriter abstracte Klasse
Vergelijkbaar met PrintWriter in servlets met aanvullende ondersteuning voor buffering. Dit is een van de impliciete variabelen in een JSP-pagina met de naam “out”. Deze klasse breidt java.io.Writer uit en de container levert hun eigen implementatie voor deze abstracte klasse en gebruikt deze bij het vertalen van een JSP-pagina naar een Servlet. We kunnen het object ervan krijgen met behulp van de PageContext.getOut() methode. De concrete klasse voor JspWriter in Apache Tomcat is
org.apache.jasper.runtime.JspWriterImpl
. -
JspContext abstracte Klasse
JspContext dient als de basisklasse voor de PageContext-klasse en abstracteert alle informatie die niet specifiek is voor servlets. JspContext biedt mechanismen om de JspWriter voor uitvoer te verkrijgen, mechanismen om met attributen te werken, en API om de verschillende scopes te beheren.
-
PageContext abstracte Klasse
PageContext breidt JspContext uit om nuttige contextinformatie te bieden wanneer JSP wordt gebruikt voor webapplicaties. Een PageContext-instantie biedt toegang tot alle namespaces die zijn gekoppeld aan een JSP-pagina, geeft toegang tot verschillende paginakenmerken, evenals een laag boven de implementatiedetails. Impliciete objecten worden automatisch aan de pageContext toegevoegd.
-
JspFactory abstracte klasse
De JspFactory is een abstracte klasse die een aantal fabrieksmethoden definieert die beschikbaar zijn voor een JSP-pagina tijdens runtime met als doel het maken van instanties van verschillende interfaces en klassen die worden gebruikt ter ondersteuning van de JSP-implementatie.
-
JspEngineInfo abstracte klasse
De JspEngineInfo is een abstracte klasse die informatie geeft over de huidige JSP-engine.
-
ErrorData final Klasse
Bevat informatie over een fout, voor foutpagina’s.
-
JspException Klasse
Een generieke uitzondering die bekend is bij de JSP-container, vergelijkbaar met ServletException. Als JSP-pagina’s JspException gooien, wordt het foutpagina-mechanisme gebruikt om foutinformatie aan de gebruiker te presenteren.
-
JspTagException Class
Uitzondering die door een Tag Handler moet worden gebruikt om een onherstelbare fout aan te geven.
-
SkipPageException Class
Uitzondering om aan te geven dat de aanroepende pagina de evaluatie moet stoppen. Opgeworpen door een eenvoudige tag handler om aan te geven dat de rest van de pagina niet moet worden geëvalueerd. Deze uitzondering moet niet handmatig worden opgeworpen in een JSP-pagina.
Since JSP is built on top of HTML, we can write comments in JSP file like html comments as `<-- This is HTML Comment -->` These comments are sent to the client and we can look it with view source option of browsers. We can put comments in JSP files as: `<%-- This is JSP Comment--%>` This comment is suitable for developers to provide code level comments because these are not sent in the client response.
Scriptlet tags are the easiest way to put java code in a JSP page. A scriptlet tag starts with `<%` and ends with `%>`. Any code written inside the scriptlet tags go into the `_jspService()` method. For example:
```
<%
Date d = new Date();
System.out.println("Current Date="+d);
%>
```
Since most of the times we print dynamic data in JSP page using _out.print()_ method, there is a shortcut to do this through JSP Expressions. JSP Expression starts with `<%=` and ends with `%>`. `<% out.print("Pankaj"); %>` can be written using JSP Expression as `<%= "Pankaj" %>` Notice that anything between `<%= %>` is sent as parameter to `out.print()` method. Also notice that scriptlets can contain multiple java statements and always ends with semicolon (;) but expression doesn't end with semicolon.
JSP Directives are used to give special instructions to the container while JSP page is getting translated to servlet source code. JSP directives starts with `<%@` and ends with `%>` For example, in above JSP Example, I am using _page_ directive to to instruct container JSP translator to import the Date class.
JSP Declarations are used to declare member methods and variables of servlet class. JSP Declarations starts with `<%!` and ends with `%>`. For example we can create an int variable in JSP at class level as `<%! public static int count=0; %>`
Once JSP files are translated to Servlet source code, the source code (.java) and compiled classes both are place in **Tomcat/work/Catalina/localhost/FirstJSP/org/apache/jsp** directory. If the JSP files are inside other directories of application, the directory structure is maintained. For JSPs inside WEB-INF directory, its source and class files are inside **Tomcat/work/Catalina/localhost/FirstJSP/org/apache/jsp/WEB\_002dINF** directory. Here is the source code generated for above test.jsp page. `test_jsp.java`
```
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/7.0.32
* Generated at: 2013-08-21 03:40:59 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp.WEB_002dINF;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
public void _jspDestroy() {
}
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=US-ASCII");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"https://www.w3.org/TR/html4/loose.dtd\">\n");
out.write("<html>\n");
out.write("<head>\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=US-ASCII\">\n");
out.write("<title>Test JSP</title>\n");
out.write("</head>\n");
out.write("<body>\n");
out.write("Test JSP Page inside WEB-INF folder.<br>\n");
out.write("Init Param \"test\" value =");
out.print(config.getInitParameter("test") );
out.write("<br>\n");
out.write("HashCode of this object=");
out.print(this.hashCode() );
out.write("\n");
out.write("</body>\n");
out.write("</html>");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
```
Notice following points in above servlet code;
- The package of class starts with org.apache.jsp and if JSPs are inside other folders, it includes directory hierarchy too. Usually we dont care about it.
- The generates servlet class is final and can't be extended.
- It extends `org.apache.jasper.runtime.HttpJspBase` that is similar to HttpServlet except that it's internal to Tomcat JSP Translator implementation. HttpJspBase extends HttpServlet and implements HttpJspPage interface.
- Notice the local variables at the start of \_jspService() method implementation, they are automatically added by JSP translator and available for use in service methods, i.e in scriptlets.As a java programmer, sometimes it helps to look into the generated source for debugging purposes.
We can define init parameters for the JSP page as shown in above example and we can retrieve them in JSP using **config** implicit object, we will look into implicit objects in JSP in more detail in future posts.
We can override JSP init method for creating resources to be used by JSP service() method using JSP Declaration tags, we can override jspInit() and jspDestroy() or any other methods also. However we should never override \_jspService() method because anything we write in JSP goes into service method.
Apart from standard servlet attributes with request, session and context scope, in JSP we have another scope for attributes, i.e Page Scope that we can get from pageContext object. We will look it's importance in custom tags tutorial. For normal JSP programming, we don't need to worry about page scope.
Dat is alles voor de JSP-voorbeeldtutorial voor beginners. Ik hoop dat het je helpt om de basisconcepten van JSP’s te begrijpen en je op weg te helpen. We zullen andere JSP-functies bekijken in toekomstige berichten.
Source:
https://www.digitalocean.com/community/tutorials/jsp-example-tutorial-for-beginners