Willkommen zum JSP-Beispiel-Tutorial für Anfänger. In den letzten Beiträgen habe ich viel über Java Servlet geschrieben und sehr gute Rückmeldungen von unseren Lesern erhalten. Daher habe ich eine weitere Serie über JSP-Tutorials gestartet, und dies ist der erste Beitrag der Serie.
JSP-Beispiel-Tutorial
In diesem JSP-Beispiel-Tutorial werden wir uns die Grundlagen von JSP, die Vorteile von JSP gegenüber Servlets, den Lebenszyklus von JSP, JSP-API-Schnittstellen und -Klassen sowie die Frage ansehen, wo wir JSP-Dateien in der Webanwendung platzieren können. Wir werden auch die JSP-Kommentare, Scriptlets, Direktiven, Ausdrücke, Deklarationen und JSP-Attribute kurz im Detail betrachten. Einige dieser Themen sind sehr wichtig, und wir werden sie in zukünftigen Beiträgen genauer betrachten.
JSP-Tutorial
- Was ist JSP und warum brauchen wir JSP?
- Vorteile von JSP gegenüber Servlets?
- Lebenszyklus der JSP-Seite
- Lebenszyklusmethoden von JSP
- Einfaches JSP-Beispiel mit Eclipse und Tomcat
- Speicherort der JSP-Dateien in der Webanwendungs-WAR-Datei
- JSP-API-Schnittstellen und Klassen
- JspPage-Schnittstelle
- HttpJspPage-Schnittstelle
- JspWriter-Abstrakte Klasse
- JspContext-Abstrakte Klasse
- PageContext-Abstrakte Klasse
- JspFactory-Abstrakte Klasse
- JspEngineInfo-Abstrakte Klasse
- ErrorData-Finale Klasse
- JspException-Klasse
- JspTagException-Klasse
- SkipPageException-Klasse
-
JSP in Servlet-Quellcode und Klassendateispeicherort in Tomcat umgewandelt
-
Was ist JSP und warum brauchen wir JSP?
JSP (JavaServer Pages) ist eine Server-seitige Technologie zur Erstellung dynamischer Java-Webanwendungen. JSP kann als Erweiterung der Servlet-Technologie betrachtet werden, da sie Funktionen bereitstellt, um Benutzeransichten einfach zu erstellen. Eine JSP-Seite besteht aus HTML-Code und bietet die Möglichkeit, Java-Code für dynamische Inhalte einzubinden. Da Webanwendungen viele Benutzeroberflächen enthalten, werden JSPs häufig in Webanwendungen verwendet. Um die Kluft zwischen Java-Code und HTML in JSP zu überbrücken, bietet es zusätzliche Funktionen wie JSP-Tags, Ausdruckssprache und benutzerdefinierte Tags. Dies macht es einfach zu verstehen und hilft einem Webentwickler, schnell JSP-Seiten zu entwickeln.
-
Vorteile von JSP gegenüber Servlets?
- Wir können auch HTML-Antworten aus Servlets generieren, aber der Prozess ist umständlich und fehleranfällig. Wenn es darum geht, eine komplexe HTML-Antwort zu schreiben, wird das Schreiben in einem Servlet zum Albtraum. JSP hilft in dieser Situation und bietet uns die Flexibilität, normale HTML-Seiten zu schreiben und unseren Java-Code nur dort einzuschließen, wo er benötigt wird.
- JSP bietet zusätzliche Funktionen wie Tag-Bibliotheken, Ausdruckssprache, benutzerdefinierte Tags, die die schnellere Entwicklung von Benutzeroberflächen unterstützen.
- JSP-Seiten sind einfach bereitzustellen, wir müssen nur die modifizierte Seite im Server austauschen und der Container kümmert sich um die Bereitstellung. Für Servlets müssen wir das gesamte Projekt erneut kompilieren und bereitstellen. Tatsächlich ergänzen sich Servlets und JSPs. Wir sollten Servlets als serverseitigen Controller und zur Kommunikation mit Modellklassen verwenden, während JSPs für die Präsentationsschicht verwendet werden sollten.
-
Lebenszyklus der JSP-Seite
Der Lebenszyklus von JSP wird ebenfalls vom Container verwaltet. In der Regel enthält jeder Webcontainer, der einen Servlet-Container enthält, auch einen JSP-Container zur Verwaltung von JSP-Seiten. Die Phasen des JSP-Lebenszyklus sind:
- Übersetzung – JSP-Seiten sehen nicht wie normale Java-Klassen aus. Tatsächlich analysiert der JSP-Container die JSP-Seiten und übersetzt sie, um den entsprechenden Quellcode für das Servlet zu generieren. Wenn der JSP-Dateiname beispielsweise home.jsp ist, lautet der generierte Dateiname normalerweise home_jsp.java.
- Kompilierung – Wenn die Übersetzung erfolgreich ist, kompiliert der Container die generierte Servlet-Quelldatei, um eine Klassendatei zu generieren.
- Klassenladen – Nachdem JSP als Servlet-Klasse kompiliert wurde, ist ihr Lebenszyklus ähnlich wie der eines Servlets, und es wird in den Speicher geladen.
- Instanzerstellung – Nachdem die JSP-Klasse in den Speicher geladen wurde, wird ihr Objekt vom Container instanziiert.
- Initialisierung – Die JSP-Klasse wird dann initialisiert und wird von einer normalen Klasse zu einem Servlet transformiert. Nach der Initialisierung stehen der JSP-Klasse die ServletConfig- und ServletContext-Objekte zur Verfügung.
- Anforderungsverarbeitung – Für jede Clientanforderung wird ein neuer Thread mit ServletRequest und ServletResponse gestartet, um die HTML-Antwort zu verarbeiten und zu generieren.
- Zerstörung – Letzte Phase des JSP-Lebenszyklus, in der es aus dem Speicher entladen wird.
-
Lebenszyklusmethoden von JSP
JSP-Lebenszyklusmethoden sind:
- jspInit() in der JspPage-Schnittstelle deklariert. Diese Methode wird nur einmal im JSP-Lebenszyklus aufgerufen, um Konfigurationsparameter zu initialisieren.
- _jspService(HttpServletRequest request, HttpServletResponse response) in der HttpJspPage-Schnittstelle deklariert und ist für die Bearbeitung von Clientanfragen zuständig.
- jspDestroy() in der JspPage-Schnittstelle deklariert, um das JSP aus dem Speicher zu entladen.
-
Einfaches JSP-Beispiel mit Eclipse und 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-Schnittstelle
Die JspPage-Schnittstelle erweitert die Servlet-Schnittstelle und deklariert die Lebenszyklusmethoden jspInit() und jspDestroy() der JSP-Seiten.
-
HttpJspPage-Schnittstelle
Die HttpJspPage-Schnittstelle beschreibt die Interaktion, die eine JSP Page Implementation Class erfüllen muss, wenn das HTTP-Protokoll verwendet wird. Diese Schnittstelle deklariert die Service-Methode der JSP-Seite für das HTTP-Protokoll wie folgt: public void _jspService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException.
-
JspWriter-abstrakte Klasse
Ähnlich wie PrintWriter in Servlets mit zusätzlicher Unterstützung für Pufferung. Dies ist eine der impliziten Variablen auf einer JSP-Seite mit dem Namen „out“. Diese Klasse erweitert java.io.Writer und der Container stellt ihre eigene Implementierung für diese abstrakte Klasse bereit und verwendet sie beim Übersetzen der JSP-Seite in ein Servlet. Wir können ihr Objekt mit der Methode PageContext.getOut() erhalten. Die konkrete Klasse von Apache Tomcat für JspWriter ist
org.apache.jasper.runtime.JspWriterImpl
. -
JspContext abstrakte Klasse
JspContext dient als Basisklasse für die PageContext-Klasse und abstrahiert alle Informationen, die nicht spezifisch für Servlets sind. Der JspContext bietet Mechanismen zum Abrufen des JspWriter für die Ausgabe, Mechanismen zum Arbeiten mit Attributen und eine API zum Verwalten der verschiedenen Namespace-Bereiche.
-
PageContext abstrakte Klasse
PageContext erweitert JspContext, um nützliche Kontextinformationen bereitzustellen, wenn JSP für Webanwendungen verwendet wird. Eine PageContext-Instanz bietet Zugriff auf alle mit einer JSP-Seite verknüpften Namensräume, bietet Zugriff auf mehrere Seiteneigenschaften sowie eine Schicht über den Implementierungsdetails. Implizite Objekte werden automatisch zum pageContext hinzugefügt.
-
JspFactory abstrakte Klasse
Die JspFactory ist eine abstrakte Klasse, die eine Reihe von Factory-Methoden definiert, die einer JSP-Seite zur Laufzeit zur Verfügung stehen, um Instanzen verschiedener Schnittstellen und Klassen zu erstellen, die für die Unterstützung der JSP-Implementierung verwendet werden.
-
JspEngineInfo abstrakte Klasse
Die JspEngineInfo ist eine abstrakte Klasse, die Informationen zum aktuellen JSP-Engine bereitstellt.
-
ErrorData final Klasse
Enthält Informationen über einen Fehler für Fehlerseiten.
-
JspException Klasse
Ein generischer Ausnahmefall, der dem JSP-Container bekannt ist, ähnlich wie ServletException. Wenn JSP-Seiten JspException auslösen, wird der Fehlerseitenmechanismus verwendet, um dem Benutzer Fehlerinformationen zu präsentieren.
-
JspTagException-Klasse
Ausnahme, die von einem Tag-Handler verwendet wird, um einen nicht wiederherstellbaren Fehler anzugeben.
-
SkipPageException-Klasse
Ausnahme, die angibt, dass die aufrufende Seite die Auswertung einstellen muss. Von einem einfachen Tag-Handler ausgelöst, um anzugeben, dass der Rest der Seite nicht ausgewertet werden darf. Diese Ausnahme sollte nicht manuell in einer JSP-Seite ausgelöst werden.
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.
Das ist alles für das JSP-Beispiel-Tutorial für Anfänger. Ich hoffe, es hilft Ihnen, die grundlegenden Konzepte von JSPs zu verstehen und Ihnen den Einstieg zu erleichtern. Wir werden uns in zukünftigen Beiträgen mit anderen JSP-Funktionen befassen.
Source:
https://www.digitalocean.com/community/tutorials/jsp-example-tutorial-for-beginners