|
JSP
informasjon
|
| oppdatert: Tirsdag 14. januar 2003
|
| JSP (Java Server Page)
|
JSP gjør det mulig å skrive Java kode rett inn i HTML-dokumentet. JSP gir en mulighet til aksesser java-kode på følgene måter:
- Java kode direkte i HTML
- Java kode i egne filer
- Beans
- Tagger for aksess av javakode
- MVC
Listen er sortert slik at alternativer for komplekse applikasjoner kommer til slutt. Hvert av punktene er omtalt i egne avsnitt nedenfor. Avslutningsvis vil vi gjennomgå våre to kode eksempler "Form to mail" og "SQL-form". Dette kapittelet baserer seg på at du er kjent med Java Servlet.
Et lite eksempel på jsp-kode
Trykk her for å vise siden.
<html>
<head><title>Demo.jsp</title></head>
<body>
<%= "Denne teksten er skrevet av et servlet som er automatisk
generert ved hjelp av \"Demo.jsp\"" %>
</body>
</html>
|
Java kode er her skrevet inne i et JSP-element som begynner med <%= og slutter med %>. Hele dokumentet blir automatisk omgjort til et servlet der html-koden blir skrevet ut ved bruk av write/print-metoden. Ved programering av servlet plassere en vanligvis utskrift av HTML-koden i doGet eller doPost metoden i Servlet-klassen. JSP plasserer write/print setningene i _jspService metoden. Denne metoden kalles ved både GET og POST type HTTP oppslag.
Hvor skal jeg plasserere mine JSP-filer i webhotellet?
I din hjemmekataloger på webhoteller har vi installert katalogen "webapps/". JSP-filer må plasser i webapps-katalogen og egendefinerte underkataloger til denne.
Hvilke filrettigheter kan jeg sette på JSP-filene?
For at tomcat-serveren skal kunne aksessere dine JSP-filer trenger du kun å være lese for deg (chmod 600), se FTP- og SSH-protokollen for forklaring filrettigheter på Linux og hvordan disse settes.
Hvordan aksesserer jeg JSP-filer?
JSP-filer aksesseres som på vanlig måte der katalogstruktur på webhotellet postfikser domenenavnet. F.eks. har du domenenavnet "servlet.no" og jsp-filen med stien "webapps/jsp/demo.jsp" relativt til din hjemmekatalog bllir URL "http://servlets.no/webapps/jsp/demo.jsp".
Hvordan laster jeg JSP-filer inn i Tomcat?
Det blir automatisk laget nytt servlet av JSP-fil ved aksess av filen. Ved aksess av JSP-filen sjekkes tidsstemplet på filen mot eventuell eksisterende klasse-fil. Ved avik generes nytt servlet som lastes inn i Tomcat.
|
| Java kode direkte i HTML
|
Java-kode kan inkluders i HTML-dokumentet ved hjelp av tre ulike JSP-elementer:
- <%= %>
alternativt
<jsp:expression> </jsp:expression>
- <% %>
alternativt
<jsp:scriplet> </jsp:scriplet>
- <%! %>
alternativt
<jsp:deklaration> </jsp:deklartion>
JSP Expression
JSP Expression benyttes til å skrive ut java-variabler/utrykk.
JSP Scriplets
JSP Scriplets benyttes når plasserer flere linjer med java-kode i HTML-dokumentet. Java-koden kan skrive til HTML-dokumentet ved hjelp av out-klassen, f.eks:
out.println("tekst som ønskes inkludert på HTML-siden"); |
Java-koden i scriplets vil uforandret bli plassert i _jspService metoden. Siden alle HTML-kode også plasseres i _jspService metoden, kan en blande HTML og Java-kode på følgende måte:
<% if (Math.random()<0.5){ %>
JSP er lett
<% } else { %>
JSP er vanskelig
<% } %> |
JSP Deklarasjoner
JSP Deklarasjon benyttes til å deklarere variabler og metoder som kan benyttes i JSP Expression og JSP Scriplet. Innholdet i taggen blir plassert direkte i servlet-klassen, utenfor _jspService-metoden.
To metoder som kan være nyttig å overskrive er jspInit og jspDestoy som kalles ved oppstart og avslutning av kodegenering ved hjelp av JSP.
Forhånds deklarerte variabler
Følgende variabler er forhåndsdeklarert og tilgjengelig i JSP expression og JSP scriplet, men ikke i JSP deklarasjoner. Variablene er kun tilgjengelig innenfor _jspService, men JSP deklarasjoner defineres på utsiden av denne metoden.
- request Instans av klassen HttpServletRequest, som innholder HTTP-request metode (GET, POST) og hodefelt tilhørende weboppslaget.
- out Instans av klassen JspWriter som er buffered versjon av Writer. JSP generert innhold på web-siden skrives til "out". Vanligvis lagrer "out" innholdet i et buffer før det sendes til klient.
- response Instans av klassen HttpServletRespons. Innholder HTTP-respons status og hodefelt. Ved buffering av "out" kan kan verdier i response-klassen endres hvor som helst i JSP Scriplet koden, men benyttes ikke bufferet "out" må respons verdier setter før en skriver til "out".
- session Instans av HttpSession. Session blir automatisk laget i JSP
- application Instans av ServletContext som returneres av getServletContext. Servlet og JSP kan benytte metodene setAttribute og getAttribute til å lagre og lese verdier i web.xml-filen i WEB-INF katalogen. Verdiene i web.xml-filen er tilgjengelig for alle servlet og JSP.
- config Instans av SevletConfig. jspInit leser verdier fra instansen.
- pagContext Instans av PageContext. Benyttes til å lagre variabler tilknyttet siden. Hvis en metode trenger aksess til mange variabler tilhørende siden kan en angi pageContect isteden for hver enkel variabel.
- page Dette er kun en this-peker og benyttes ikke.
|
| Direktiver
|
Direktiver påvirker hvordan JSP blir oversatt til servlet-kode. Dirktiver benyttes bl.a. til å importere Java pakker og inkludere Java kode fra andre filer. Direktiver skrives direkte i HTML-koden og har følgende syntaks:
- <%@ direktiv attributt1="verdi1" attributt2="verdi12" . . . %>
- <jsp:direktiv attributt1="verdi1" attributt2="verdi12" . . . />
De to alternative syntaksene har ekvivalente betydning, men kun den siste er på XML-format. Direktivene kan plasseres på et tilfeldig sted i HTML-koden. Det finnes følgende 3 direktiver:
- page
- include
- taglib
Direktivene include og tablib er omtalt i egen avsnitt under (Java kode i egne filer, Tagger for aksess av Java kode). Her vil vi se nærmere på page-direktivetet som tar følgende atributter.
- import
Verdien til atributtet er en java-klasse eller pakke. Dette er det eneste page-atributtet som er lovlig å gjenta flere ganger. JSP vil automatisk importere: java.lang.*, javax.servlet.*, javax.servlet.jsp.*, javax.servlet.http.*. Egne klasser som skal importeres må lagres servlet-katalogen webapps/WEB-INF/classes/.
- contentType<
Benyttes til å sette HTTP ContentType hodefelt i respons-meldingen. Default verdi er "text/html" og karaktersett ISO-8859-1 (Latin-1) (default for servlet er "text/plain").
- isThreadSafe
Tar verdiene "true" eller "false" (default er "true). Ved verdien "false" vil systemet enten lage en kø av requester som en av gangen aksesserer java-koden eller eller lave en pool av instanser av java-koden slik at hver request får en en unik instans. Det anbefales å skrive threadsafe Java-kode ved å instansere synchronized-klassen.
- session
Tar verdien "true" eller "false".
Atributtet bestemmer Session API bli støttes. Ved bruk av session blir cookies formidlet mellom server og og klient for identifisere bruker og datastruktur innholdene informasjon om forbindelsen/brukeren opprett på serveren.
- buffer
Atributtet angir størrelsen på buffer som benyttes når skriver til "out". Eksempel på kode
<%@ page buffer=#64kb" %> |
- autoflush
Tar verdien "true" eller "false". Bestemme om buffer skal sendes til klient når det er fult eller om det skal gis exception.
- extends
Atributtet angir hvilken servelet classe som skal extendes. Dette er aktuelt hvis en har en egenutviklet servlet-klasse en ønsker JSP-koden skal ekstende.
- info
Informasjon som kan lese i Java-koden ved hjelp av getServletInfo.
- errorPage
Angir hvilken side som skal benyttes til skrive ut feil-meldinger (exception-meldinger). Ønsket feilmelding-side må har atributtet isErrorPage="true". Feil-melding side kan også angis web.xml-filen og vil da ha gyldighet for alle JSP-sider.
- isErrorPage
Tar verdiene "true" eller "false". Atributtet angir om siden kan benyttes en feil-meldings side for andre JSP-sider
- pageEncoding
Atributtet angir karaktersett som skal benyttes. Default er ISO-8859-1 (latin-1).
|
| Java kode i egne filer
|
For å inkludere JSP kode fra andre filer kan en enten benytte include-direktivet eller jsp:include-taggen. Disse har følgende syntaks
- <%@ include file="relative-url" %>
- <jsp:include page="relative-url" flush="true" >
<jsp:param name="navn" value="verdi" />
</jsp:include >
Tidspunktet for når filene blir inkludert er ulikt i tilfellen over. Ved bruk av direktivet (tilelle 1) vil filen bli inkludert når det lages servlet av JSP-siden direktivet står i. Endringer i ettertid på filen som blir inkludert vil vanligvis ikke oppdater sider den er inkludert i. Ved bruk av include-taggen (tilfelle 2) vil filen som skal skal inkluders bli til eget servlet og hva dette servlet skriver til "out" blir inkludert i hoved-siden. Det inkluderte servlet vil automatisk ha de samme parameter i request-objektet som som hoved-siden. En kan i tillegg gi inkludert servelet ytterligere parametere ved bruk av jsp:param-taggen.
|
| Beans
|
Beans er Java-klasser som kan gjenbrukes av flere JSP-sider og kan aksesseres ved hjelp av XML-tagger. For at en Java-klasse skal kunne aksesser som et beans må den tilfredstille følgende kriterier.
- Klassen må enten ikke ha konstruktør eller en konstruktør uten parameter. Det er altså ikke mulig initsiere instanser av klassen med parametere.
- Klassen må ikke ha "public" variable. Variabler som er ment å aksessers fra utsiden beans-property.
- Endring av beans-property skjer gjennom kalle på metodene set- og get-Property (her Property er navnet på egeneskapen).
Her følger eksemple på en bean-klasse med en property: minMelding.
package mineServlet;
public class MittBean{
private String minMelding="Ingen tekst angitt";
public String getMinMelding{ return (minMeldining);}
public void setMinMelding(String minMelding){ this.minMelding=minMelding;}
} |
Bean-klassen plasser i samme katalog som servlet, webapps/WEB-INF/classe/. For å lage instans av dette bean med navn "nyMelding" kan følgende tag benyttes:
<jsp:useBean id="nyMelding" class="mineSerlvet.MittBean" />
For å oppdatere bean-property "minMelding" kan følgend tagg benyttes:
<jsp:setProperty id="nyMelding" property="minMelding" value="Dette er min melding" />
For å lese bean-property kan følgende tagg benyttes:
<jsp:getProperty id="nyMelding" property="minMelding" />
Sette levetid
Ved å angi en av følgende verdier til scope atributt i jsp:useBean kan en bestemme levetiden til beans.
- page
Dette er default verdi. Beans er akesserbart innenfor siden. Referanse til bean klassen blir inkludert i PageContext. Variablen pageContext i "tag handler class", som er omtalt nedenfor, referer til pageContext. Ved å kall på pageContext.getAttribute("id") vil en kunne hente fram referanse til beans. Tilsvarend kan en hent ut request-objektet ved pageContext.getRequest().
- application Beans er aksessbart av alle servlet (begrenset av samme Web application) Referanse til beans plasseres i ServletContext og kan leses ved bruk av metoden getServerletContext.getAttribute() metoden.
- session Beans er akessesbart av alle sider innenfor samme sesjon. Referanse til bean lese ut ved bruk metoden getSession().getAttribute("id") i HttpRequest intansen.
- request Beans er aksessesbart av alle servlet som behandler requesten. Referanse til beans leses ut ved bruk av metoden getAttribute()i HttpRequest instansen.
I tilleg plasseres alltid en referanse til beans i _jspService metoden ved bruk av taggen jsp:useBeans. Initsering av nye bean ved jsp:useBean skjer bare hvis det ikke eksistrerer en bean med samme id og scope fra før. For hindere at bean bli reinsisert om det eksistrer fra før kan en dette initsiering plassers inne i jsp:useBean elementet, f.eks:
- <jsp:useBean id="nyMelding" class="mineSerlvet.MittBean" scope="application" >
- <jsp:setProperty id="nyMelding" property="minMelding" value="Dette er min melding" />
- </jsp:useBean >
|
| Tagger for aksess av Java kode
|
|
En viktig egenskap ved JSP er muligheten for å lage egen JSP-tagger. Her vil første se på et lite eksempel på hvordan en Java-klasse (tag handler class) kan bindes til en JSP-tagger i filen: tag libary descriptor file. Til slutt ser vi hvordan en kan benytte taggen i selve JSP-siden.
Tag handler class
Tag handler class må ekstende TagSupport-klassen i javax.servlet.jsp.tagext;
package mineServlet.tags;
import javax.servlet.jsp.*;
import javax.servelt.jsp.tagext.*;
import java.io.*;
public class MinTagg extends TagSupport{
public int doStartTag(){
try {
JspWriter out=pageContext.getOut();
out.print("Min nye tagg");
}
catch (IOException e){
System.out.println("Error in ExampleTag: "+e);
}
return(SKIP_BODY);
}
} |
Tag handler klassen blir ikke automatisk kompilert. Etter kompilering må en restart Tomcat for laste inn klassen.
Tag library discriptor file
XML-formatert fil som binder tagnavn til "tag handler class".
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/wb-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversin>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>mine-tagger</shortname>
<info>Min tagg</info>
<tag>
<name>mintagg</name>
<tagclas>mineServlet.tags.MinTagg</tagclass>
<bodycontent>empty</bodycontent>
<info>Test på tagg</info>
</tag>
</taglib> |
I selve JSP-siden kan taggen benyttes som følger:
<%@ taglib uri="minetagger.tld" prefix="egen" %>
<egen:mintagg />
|
I dette eksemplet må TLD-filen ligge i samme katalogen som jsp-filen å hete "minetagger.tld". Generelt sett kan relativ adresse til TLD-filen angis (ikke absolutt url)
Tagger med atributter
For alle atributter en ønsker å spesifisere i taggen må en definere en tilsvarende metode i "tag handler class". F.eks ønkser en å angi atributtet "farge" i taggen må "tag handle class" innholde metoden
public void setFarge(String verdi){
etterEllerAnnet(verdi);
} |
Legg merke til skifte mellom liten og stor forbokstav fra atributt til metode-navn.
I TLD-filen må det for hvert enkelt atributt spesifiseres et eget attribute-element innenfor tag-elementet. Attribute-elementet kan innholde følgende 5 elementer der kun de to første er obligatoriske:
:
<tag>
<name>mintagg</name>
<tagclas>mineServlet.tags.MinTagg</tagclass>
<bodycontent>empty</bodycontent>
<info>Test på tagg</info>
<attribute>
<name>farge</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>String</type>
<example><mintagg farge=<%=var.color%>></example>
</attribute>
</tag>
:
|
Atributt verdier må oppgis som tekst i taggen, men ved å sette rtexprvalue-elementet til true, i TLD-filen, kan atributtet ta en JSP-expression som verdi. I kombinasjon med rtexpvalue elementet er det også mulig å benytte type-elementet i tag-elementet til typecast av atributt-verdien.
Tagger med kropp
For lage tagg med kropp må følgende gjøres
- TLD-filen må bodycontent-elementet innholdet "JSP" (default verdi om elemenet utelates)
- "Tag handle class" må ekstende BodyTagSupport
- En må også deklarere doEndTag-metoden
- Retur verdi i metoden doStartTag må endres som følger:
:
:
public class MinTagg extends BodyTagSupport{
public int doStartTag(){
.....
return(EVAL_BODY_INCLUDE);
}
public int doEndTag(){
.....
return(EVAL_PAGE);
} |
Returner doStartTag SKIP_BODY vil kroppen til taggen overses og returnerer doEndTag SKIP_PAGE vil JSP-sidena abortere etter taggen.
Les ut og endre innholdet i kroppen på taggen i "tag handler class"
For å manipulere kroppen til taggen må "tag handler class" extende BodyTagSupport, istedet for TagSupport. BodyTagSupport extender TagSupport slik at metodene doStartTag() og doEndTag() kan overskrives som før og tillegg kan doAfterBody() overskrives. For å maninipulere kroppen til taggen overskrives metoden doAfterBody(). Hvis denne metoden returner SKIP-BODY vil hva som skrives ut i metoden erstatte eksisterende kropp til taggen. Returner metoden EVAL_BODY_TAG vil det bli utført en nytt kall på doAfterBody().
BodyTagSupport innholder metode getBodyContent(). Metoden henter ut BodyContent objekt som innholder informasjon om kroppen til taggen. BodyContent innholder bl.a. følgende tre metoder.
- getEnclosingWriter Returner JspWriter
- getReader Returner Reader som kan benyttes til å lese kroppen til taggen
- getString Returnerer en string innholdene hele kroppen til taggen
Nestede tagger
Det er mulig å neste JSP-tagger slik tagger. Variabler kan lagres i omsluttende tagg og kan leses ut tagger i kroppen ved hjelp av metoden findAcestorWithClas(this,Omsluttende.class);. Metoden returnerer instansen av klassen Omsluttende.class som reprenterer foreldre-elementet. Metoden er tilgjengelig i både TagSupport og BodyTagSupport.
|
| MVC (Model View Controller)
|
MVC-arkitekturen benytter et servelet til å svare på requesten. Ut fra informasjon i kropp og hodefelt i HTTP-request eller eventuelt lagret informasjon i bean- og session-objekter kan servletet bestemme hvilken side weboppslaget skal omdirigeres til. Selve omdirigeringen utføres ved å hente en referanse til instanst RequstDispatcher-klassen fra ServletContext. Deretter kan en kalle på metoden forward() i RequestDispatcher-klassen, se følgende kode:
public woid doGet(HttpServletRequest request, HttpServletRespons respons)
throw SevletException, IOException {
if (request.getParameter("gul")){
RequestDispatcher dispatcher=getServletContext().getRequestDispatcher("gulside.jsp");
dispatcher.forward(requet,respons);
}
else {
RequestDispatcher dispatcher=getServletContext().getRequestDispatcher("brunside.jsp");
dispatcher.forward(requet,respons);
}
}
|
|
| Eksempel: Form to mail
|
|
|
| Eksempel: SQL-form
|
|
|
|