JavaServer Pages Dies ist eine Zusammenfassung über die JavaServer Pages Technologie von Sun Microsystems, wo die wichtigsten technischen Begriffe erklärt werden, sowie kleine Beispielprogramme enthalten sind um die Funktionalität zu veranschaulichen. Die JavaServer Pages Technologie wird benutzt um dynamsiche Webinhalte zu generieren. Webinhalte wie HTML, DHTML, WML und XML. Das aktuelle JavaServer Web Development Kit (JSWDK) 1.0.1 kann von der Sun Webseite runtergeladen werden, es beinhaltet neben den JSP 1.1 Klassen auch einen kleinen Webserver für Testzwecke. Übersicht Was sind JavaServer Pages? JavaServer Pages ist eine Technologie zur Entwicklung von dynamischen Webinhalten mit Hilfe einer serverseitigen Scriptsprache. Die JavaServer Pages Technologie baut auf den Servlet standart extensions auf. JSP ermöglicht, dass man Java direkt in einer HTML Seite als Scriptingsprache benutzen kann. Eine JSP Seite ist ein Textdokument das beschreibt wie ein Request auf dem Server verarbeitet werden muss um eine Response zu kreieren die dann dem Browser geschickt wird. Die JaveServer Pages sind Templates die mit dynamisch generierten Daten aufgefüllt werden. JSP und Servlets werden Web components genannt und ermöglichen Zugriff auf Resourcen via JDBC und Enterprise Beans. Sie stellen eine mächtige Platform für E-Commerce Applikationen dar, da mit dieser Technologie Businesssystem Funktionalität über das HTML interface angeboten werden kann. HTML hat verschiedene Vorteile gegenüber konventionellen Clients. Die wichtigsten haben zu tun mit der Verteileung und den Firewalls: Konventionelle Clients müssen verteilt und installiert werden, das bedeutet zusätzlichen Aufwand. HTML im Gegenzug muss nicht installiert werden und hat keine komplizierten Sicherheitsrestriktionen. Inhalt einer JavaServer Page Eine JSP Seite beinhaltet Declarations, fixe template Daten, Action instances und einige Scripting Elemente. All diese Inhalte werden bei einem Request benutzt um ein Response Objekt auf dem Server zu kreieren dass dann dem Client geschickt wird. Wie sieht so eine JSP Seite aus? Hier ein Beispiel: (HelloWorld.jsp) <%@page language=”java” info=”hello world example” %> <html> <head></head> <body> Output JSP: <%= out.println(“Hello World!“) %> </body> </html> JSP Klassen Die JavaServer Pages sind ein Teil der Java Enterprise Edition (J2EE) Spezifikation. Eine JSP Seite ist zur Requestzeit ein Objekt dass das javax.servelt.Servlet Interface implementiert. Folgende Java packages gehören zu der JSP 1.1 Spezifikation: javax.servelt.jsp javax.servelt.jsp.tagext Vorteile von JSP JavaServer Pages haben verschiedene Vorteile: • • • • • Write Once, Run Anywhere properties: Sind die JSP Seiten einmal entwickelt, können sie auf jeder Platform auf einem beliebigen Webserver laufen. Reuse von Java Komponenten und Tag Librarys: JavaBeans, Enterprise JavaBeans und Tag Libraries können bei der Entwicklung einer Webapplikation wiederverwendet werden. Die statischen und die dynamischen Inhalte können getrennt werden: Die statischen Inhalte einer Seite liegen in einem Template vor, die dynamische Inhalte einer JSP Seite werden durch Scripting generiert. Web Zugang für N-tier Enterprise Applikationen: Die JavaServer Pages sind ein Teil der J2EE Spezifikation. JSP können nun als Frontend verwendet werden um auf middle-tier Server Applikationen zuzugreifen. Ein portabler Tag extension Mechanismus Technisches Applikations Modelle JSP Seiten können in Kombination mit Servelts, HTTP, XML, WML, Applets, JavaBeans und Enterprise JavaBeans benutzt werden um verschiedene Applikations Modelle zu implementieren. N-tier Applikation Dieses Modell besteht aus mehreren Schichten, wo die mittlere Schicht (JSP) mit den Backend Resourcen über eine Enterprise JavaBeans Komponente kommuniziert. Objekte und Scope In einer JSP Seite können Objekte kreiert werden, es gibt Implicit Objects die schon existieren und bei den explizit kreierten Objekten kann man den Scope festlegen. Der Scope definiert wo eine Referenz zu einem Objekt gültig ist und wann sie gelöscht wird. Es gibt folgende Scopes: Page: Objekte die in einer JSP Seite kreiert werden, sind nur auf dieser Seite gültig. Alle Objektreferenzen sollten freigegeben werden wenn die Response zum Client zurückgeschickt wird. Request: Objekte mit einem Request Scope sind von Seiten aus zugänglich in denen der selbe Request verarbeitet wird. Session: Objekte mit Session Scope sind während einer ganzen Usersession zugänglich. Es ist nicht erlaub Sessionobjekte auf einer Seite zu kreieren die keine Session Page(siehe Page Directive) ist. Selbstkreierte Objekte mit Sessionscope werden im session Objekt gespeichert. Application: Objekte mit Application Scope sind global gültig. Sie werden einmal für die ganze Applikation kreiert, und können dann auch von sessionlosen Seiten aufgerufen werden. Die globalen Objekte werden im application Objekt gespeichert. JSP kompilieren Eine JSP Seite kann manuell in ein Servlet kompiliert werden, in die Implementationsklasse plus Deployment Descriptor. Die JSP Seiten können zusammen mit der ganzen Webapplikation in ein WAR File gepackt werden, um sie so auf dem Server zu installieren. Normalerweise werden die .jsp Seiten gleich wie HTML Seiten auf den Webserver getan, und sie werden dann zur Requestzeit in ein Java Servlet kompiliert und auf dem Server ausgeführt um die Response zu generieren. Ausführen von JSP Pages Eine JSP Seite wird in einem JSP Container, der auf dem Webserver installiert ist ausgeführt. Der Container gibt einen Request vom Client an den eine JSP Seite weiter und die Response wird von der JSP Seite über den Container an den Cleint geschickt. Eine JSP Seite definiert auch ein Events die behandlet werden. JSP Container Eine JSP Seite wird von einem Container ausgeführt, der auf dem Webserver installiert ist. Der Container gibt einen Request von Client zur JSP Seite, und eine Response von der JSP Seite zum Client weiter. Das darunterleigende Modell einer JSP Seite ist ein Servlet. Eine JSP Seite hat auch einige Events die behandelt werden können: JSP Events jspInit() Diese Methode einer JSP Seite wird als erstes aufgerufen wenn die Seite initialisiert wird. jspDestroy() Diese Methode einer JSP Seite wird aufgerufen wenn die Seite verlassen wird. _jspService() Diese Methode beinhaltet den Body einer JSP Seite. Diese Methode wird automatisch vom JSP Container generiert, sie darf nie vom Author definiert werden. JSP und XML Eine JSP Seite kann auch als XML Dokument repräsentiert werden, was aber zum manuellen editieren nicht sehr gebräuchlich ist. Alle <% Elemente müssen in gültige XML Elemete konvertiert werden. Zum Beispiel aus einer <% ... %> Anweisung wird in XML ein Tag: <jsp:scriptlet> ... <jsp:scriptlet> Der DTD für das XML Dokument ist im folgenden File definiert: http//:java.sun.com/products/jsp/dtd/jsp_1_0.dtd Tag Librarys Tag Librarys sind sind Definitionen von Actions die bestimmte Funktionalitäten in einer JSP Seite bereit stellen. Mit einer taglib Direktive macht man verschiedene selbstdefinierte Tags in einer Seite bekannt, die dann benutzt werden können. Die Tag Librarys sind XML Dokumente mit denen Tags definiert und erweitert werden können. Hier ein Beispiel dazu: <%@taglib uri="simpleDB.tld" prefix="x" %> Tag: <x:queryStatement> SELECT * FROM ACCOUNT </x:queryStatement> Scripting Scriptlets Scriptlets enthalten Code Fragmente in der definierten Scriptingsprache, die in der <%@page language="..." %> Direktive spezifiziert werden kann. Scriptlets werden zur Requestzeit ausgeführt, und können einen Output in den out Stream generieren. Mit JavaServer Pages kann man auf die ganze Java Runtime zugreifen. Beispiel: <% for(int i=0;i<5;i++) { %> Good Morning <% } %> Expressions Das Gleichzeichen evaluiert den Ausdruck, wandelt das Resultat in einen String um und printet es aus. Beispiel: <%= (new java.util.Date()).toString() %> Actions Actions können Objekte kreieren und modifizieren und sie können eine Auswirkung auf den out Steam haben. Beispiel: <jsp:useBean id="clock" class="calendar.jspCalendar" /> JSP und Beans Mit JavaServer Pages kann man auf selbst geschriebene JavaBeans zugreifen, die serverseitig installiert sein müssen. Propertys Mit den Property Tags kann man auf die Getter und Setter Methoden einer Bean zugreifen. <jsp:getProperty name="mort" property="PI"/> Mit diesem Tag kann man die getPI() Methode des den Property Wert zurück. Beans aufrufen, und kriegt so <jsp:setProperty name="numguess" property="*"/> So funktioniert der setzen eines Propertys. Mit dem "*" Parameter iteriert man über die ServletRequest Parameter, und wenn der Name und der Typ des Propertys übereinstimmen, werden die entsprechenden Setter Methoden aufgerufen. In diesem kleinen Beispiel sieht man wie das serverseitiges Bean object clock erstellt wird, und darauf verschiedene Methoden ausgeführt werden. Example (Clock.jsp): <html> <jsp:useBean id="clock" class="calendar.jspCalendar" /> <ul> <li>Day: <%= clock.getDayOfMonth() %> <li>Year: <%= clock.getYear() %> </ul> </html> Syntax Hier sind die wichstigsten Elemente der JSP Syntax aufgeführt, die man üblicherweise benutzt. Für eine komplette Zusammenstellung siehe http://java.sun.com/products/jsp/syntax.pdf Comment Kommentar in einer JSP Seite: <% // comment %> <% /* comment */ %> Declaration Zur Deklaration von Variabeln oder Methoden: <%! declaration %> Expression Scripting expression: <%= expression %> Scriptlet <% code fragment %> Directives Page Directive : <%@page language="java" extends="Class" import="Class" etc. %> Include Directive : <%@include file="test.html" %> Taglib Directive : <%@taglib uri=”URIToTagLibraray” prefix=”tagprefix” %> JSP Tags ( Actions ) Forward <jsp:forward page"test.jsp" /> Include <jsp:include page="test.jsp" /> useBean <jsp:useBean id="hello" scope="session" class="hello.Name" /> getProperty <jsp:getProperty name="hello" property="propertyName "/> setProperty <jsp:setProperty name="hello" property="propertyName "/> Implicit Objects Dies sind Objekte, auf die man in einer JSP Seite zugreifen kann, ohne sie vorher zu instanzieren: request javax.servlet.ServletRequest response javax.servlet.ServletResponse pageContext javax.servlet.jsp.PageContext session javax.servlet.http.HttpSession application javax.servlet.ServletContext out javax.servlet.jsp.JspWriter config javax.servlet.ServletConfig exeption java.lang.Throwable Examples JSP Scriptlet mit Fromhandling Dies ist ein simples Beispiel einer JSP Seite mit Fromhandling mit Hilfe von Java Scriptlets. HTML Form: //index.html <HTML> <BODY bgcolor="white"> <FORM METHOD="post" ACTION=result.jsp> <BR> <font size=5 color="black"> Check all favorite cars: <br> <br> <input TYPE=checkbox name=car VALUE="Ferrari"> Ferrari <BR> <input TYPE=checkbox name=car VALUE="BMW Z3"> BMW Z3 <BR> <input TYPE=checkbox name=car VALUE="Corvette"> Corvette <BR> <input TYPE=checkbox name=car VALUE="Porsche 911"> Porsche 911 <BR> <input TYPE=checkbox name=car VALUE="Smart"> Smart <BR> <br> other: <input TYPE=text name=cartxt> <BR> <br> <INPUT TYPE=submit name=submit Value="Submit"> </font> </FORM> </BODY> </HTML> JSP mit Scriptlet: //result.jsp <html> <!-JSP Example Get the params from the form --> <body bgcolor="white"> <font size=5 color="black"> <%! String[] cars; //var declaration String other; java.util.Date now; %> <hr> The selected cars (got using request) are: <P> <% now=new java.util.Date(); out.println( now.toString() ); cars = request.getParameterValues("car"); other = request.getParameter("cartxt"); %> <ul> <% if (cars != null) { for (int i = 0; i < cars.length; i++) { %> <li> <% out.println (cars[i]); } if (!other.equals("") ) out.println("<li>" + other); } else out.println ("none selected"); %> </ul> <br> <hr> <a href="result.txt">Source code</a> <hr> </body> </html> JSP mit JavaBean Dieses Beispiel zeigt, wie man von einer JSP Seite ein JavaBean erzeugt und dann auf die Funktionen der Bean zugreift. Es ist ein kleines Nummern Ratespiel: JSP Seite: //numguess.jsp <!-Number Guess Game --> <%@ page import = "num.NumberGuessBean" %> <jsp:useBean id="numguess" class="num.NumberGuessBean" scope="session"/> <jsp:setProperty name="numguess" property="*"/> <html> <head><title>Number Guess</title></head> <body bgcolor="white"> <font size=4> <% if (numguess.getSuccess()) { %> Congratulations! You got it. And after just <%= numguess.getNumGuesses() %> tries.<p> <% numguess.reset(); %> Care to <a href="numguess.jsp">try again</a>? <% } else if (numguess.getNumGuesses() == 0) { %> Welcome to the Number Guess game.<p> I'm thinking of a number between 1 and 100.<p> <form method=get> What's your guess? <input type=text name=guess> <input type=submit value="Submit"> </form> <% } else { %> Good guess, but nope. Try <b><%= numguess.getHint() %></b>. You have made <%= numguess.getNumGuesses() %> guesses.<p> I'm thinking of a number between 1 and 100.<p> <form method=get> What's your guess? <input type=text name=guess> <input type=submit value="Submit"> </form> <% } %> </font> </body> </html> JavaBean: //NumberGuessBean.java // Number Guess Game package num; import java.util.*; public class NumberGuessBean { int answer; boolean success; String hint; int numGuesses; public NumberGuessBean() { reset(); } public void setGuess(String guess) { numGuesses++; int g; try { g = Integer.parseInt(guess); } catch (NumberFormatException e) { g = -1; } if (g == answer) { success = true; } else if (g == -1) { hint = "a number next time"; } else if (g < answer) { hint = "higher"; } else if (g > answer) { hint = "lower"; } } public boolean getSuccess() { return success; } public String getHint() { return "" + hint; } public int getNumGuesses() { return numGuesses; } public void reset() { answer = Math.abs(new Random().nextInt() % 100) + 1; success = false; numGuesses = 0; } } JSP mit Enterprise Javabeans Dieses Beispiel implementiert einen EJB basierenden Hypothek Berechnugsservice. Ein Browser Client kann die Enterprise Java Bean Funktionalität mit Hilfe der Java Server Pages und einer Bean benutzen. EJB Remote interface: // IMortgage.java public interface IMortgage extends javax.ejb.EJBObject { MortgageResult calculate(double YR, double IR , double LA, double AT, double AI)throws java.rmi.RemoteException; } JavaServerPage: // Mortgage.jsp <html> <body> <%@ page import = "mortgage.MortgageInfo" %> <jsp:useBean id="mort" class="mortgage.MortgageInfo" scope="session" /> <jsp:setProperty name="mort" property="*" /> <FORM NAME="temps"> <P> <%= mort.getMortgage() %> <br> <br> <b><font color="#0000FF" size="+2">Results:</font></b> <P>&nbsp; <div align="center"> <TABLE BORDER=2> <TR> <TD width="222">Monthly Principle <TD width="460"><jsp:getProperty name="mort" property="PI"/> <TR> <TD width="222">Monthly Tax <TD width="460"><jsp:getProperty name="mort" property="MT"/> <TR> <TD width="222">Monthly Ins <TD width="460"><jsp:getProperty name="mort" property="MI"/> <TR> <TD width="222">Total Payment <TD width="460"><jsp:getProperty name="mort" property="MP"/> </TABLE> </div> <HR> </FORM> </body> </html> JavaBean mit der Verbindung zum EJB: //MortgageInfo.java package mortgage; // import necessary classes/packages for the example import java.io.*; import java.util.*; import java.util.Hashtable; import javax.ejb.CreateException; import javax.ejb.RemoveException; import java.rmi.RemoteException; import javax.naming.InitialContext; import javax.naming.NamingException; // needed to work with EJB(MortgageBean) import IMortgage; import MortgageHome; import MortgageResult; /* This Java Bean is used by the JSP to talk to * EJB (MortgageBean). With standard getters, and * setters functions, the values from the user's * input HTML form are set by introspection, and * the results of the computations (from EJB) * are passed to the JSP using the getters * in this file * As per Sun (TM)'s documentation the Java * bean has to be Serializable for use in * the JSP's */ public class MortgageInfo implements Serializable { // the following information comes from the // user's HTML form private double _YR = 0.0; // number of years private double _IR = 0.0; // interest rate private double _LA = 0.0; // loan amount private double _AT = 0.0; // annual tax private double _AI = 0.0; // annual interest // the following are for storing calculations // and storing results private double _MP = 0.0; // monthly total payment private double _PI = 0.0; // monthly premium plus interest private double _MT = 0.0; // monthly tax private double _MI = 0.0; // monthly insurance /* This method is called by the JSP when a user * presses the submit button. The method locates * and calls the EJB for doing computations. * Currently the lookup is happening in every * call, however it can be moved into the * bean constructor */ public String getMortgage () { // calculate the mortgage // let's look for the mortgage EJB in everycall IMortgage mort=null; MortgageHome home = null; try{ javax.naming.Context context = new javax.naming.InitialContext(); Object ref = context.lookup("mortgage"); home=(MortgageHome) javax.rmi.PortableRemoteObject.narrow(ref, MortgageHome.class); mort= home.create(); } catch(Exception e){ System.out.println("exception occured" + e); } try{ MortgageResult result = mort.calculate(_YR, _IR, _LA, _AT, _AI ); _PI = result.PI; _MT = result.MT; _MI = result.MI; _MP = result.MP; } catch (java.rmi.RemoteException e){ System.out.println("RMI exception occured" + e); e.printStackTrace(); } return ""; } /* Below are all the setXXX() calls that are * called by the WEB server automatically for * the named values. For e.g there is an input * field "YR" in the input form Mortgage.html (in current dir) * this function is called by the web server to set that * value in this bean. */ public void setYR (String A) { try { _YR = new Double(A).doubleValue(); } catch (NumberFormatException e) { System.out.println("Number format exception occured" + e); e.printStackTrace(); } } public void setIR (String B) { try { _IR = new Double(B).doubleValue(); } catch (NumberFormatException e) { System.out.println("Number format exception occured" + e); e.printStackTrace(); } } public void setLA (String C) { try { _LA = new Double(C).doubleValue(); } catch (NumberFormatException e) { System.out.println("Number format exception occured" + e); e.printStackTrace(); } } public void setAT (String C) { try { _AT = new Double(C).doubleValue(); } catch (NumberFormatException e) { System.out.println("Number format exception occured" + e); e.printStackTrace(); } } public void setAI (String C) { try { _AI = new Double(C).doubleValue(); } catch (NumberFormatException e) { System.out.println("Number format exception occured" + e); e.printStackTrace(); } } /* all the get functions needed by the JSP (Mortgage.jsp) * to build its output HTML * Please see Mortgage.jsp for the usage of this information * in JSP. */ public double getPI() { return _PI; } public double getMT(){ return _MT; } public double getMI(){ return _MI; } public double getMP(){ return _MP; } } References http://java.sun.com/products/jsp/index.html http://java.sun.com/products/jsp/syntax.pdf http://www.jspin.com/ http://www.jsp-interest.com/ http://www.serverpages.com/Java_Server_Pages/ http://www.infosys.tuwien.ac.at/cetus/oo_javaserver_pages.html http://www.burridge.net/jsp/