JSP Tilstander og synkronisering
Tilstandsinformasjon Fire måter å gjøre det på omskriving av URL cookies hidden fields (gjemte felt) tjenersidelagring (sessions)
se kreativbrukavurl.jsp Kreativ bruk av URL Lager URL som inneholder informasjon (kreative URL er) <a href=min.jsp?farge=hvit> hvit <a href=min.jsp?farge=rød> rød Handler på grunnlag av info i URL String farge = request.getparameter( farge ); if (farge.equals( hvit ) bakgrunn = white ;... <BODY BGCOLOR= <%= bakgrunn %> >
</BODY> </HTML> <% String farge = request.getparameter("farge"); //får tak i fargen valgt String bakgrunnsfarge ="green"; if (farge!= null){ if (farge.equals("white") farge.equals("red") farge.equals("green")){ bakgrunnsfarge=farge; //bestemmer fargen } } %> <HTML> <HEAD></HEAD> <BODY BGCOLOR="<%=bakgrunnsFarge%>"> <H1> Du får den fargen du vil </H1> <A HREF=kreativBrukAvUrl.jsp?farge=white> HVIT </A> <BR> <A HREF=kreativBrukAvUrl.jsp?farge=red> RØD </A> <BR> <A HREF=kreativBrukAvUrl.jsp?farge=green> GRØNN </A> <BR>
Omskriving av URL Skriver om URL en hver gang => dynamisk JSP en <a href= omskrivingurl.jsp?farge= <%=bakgrunnsfarge%> > se omskrivingurl.jsp
omskrivingurl.jsp <% String tmp = request.getparameter("farge"); String bakgrunnsfarge = "green"; %> if (tmp!= null) bakgrunnsfarge = tmp; if (bakgrunnsfarge.equals("green")){ bakgrunnsfarge="red"; }else{ bakgrunnsfarge="green"; } <HTML> <BODY BGCOLOR="<%=bakgrunnsFarge%>"> <H1> Du får den fargen du vil </H1> <A HREF=omskrivingURL.jsp?farge=<%=bakgrunnsFarge%> > SKIFT BAKGRUNNSFARGE </A> </BODY></HTML>
Problemet med omskriving URL Varigheten er dårlig. Lukker nettleser => tilstand borte Må konfigurere på nytt hver gang! Løsning cookies. Her lagres informasjonen på fil på klienten og blir derfor ikke borte hvis nettleseren lukkes.
Cookies Tekstfil som lagres på klienten Sendes med til tjeneren ved hver forespørsel til tjeneren som lagde cookie en Laget av JSP en: http://localhost/test/test.jsp Cookie blir synlig også i underkataloger http://localhost/test/underkatalog/../min.jsp //synlig her Ikke synlig her http://localhost/minkatalog/en.jsp
Spes.tegn hvite tegn samt []()=,/?@:; Lag cookie new Cookie(String navn, String verdi) Cookie kake = new Cookie( navn, verdi ); cookie.setmaxage(3600); // levetid i sekunder cookie.setversion(1); // går bra med spes.tegn response.addcookie(kake); //blir med i HTTPforsend
Les inn cookie String cookienavn = KAKE ; Cookie cookie = null; Cookie[] tabell = request.getcookies(); // henter inn de cookie'ene som kommer fra nettleser // går igjennom cookie'ene og finner vår cookie for (int i=0; i<tabell.length; i++){ cookie = tabell[i]; if (cookie.getname().equals(cookienavn)){ cookiefarge = cookie.getvalue(); } }
Hvordan finne cookie Hvordan finne cookies på maskinen din? Navnet på cookie-filen settes automatisk! Lese innhold => tekstfil =>notepad? Netscape Edit/Preferences/Advanced/Cookies/View Stored Cookies ser også innholdet IE må lete fram til cookies forskjellig fra OS til OS win2000 c:\ Documents and Settings\brukernavn (tomash) XP c:\ Documents and Settings\brukernavn\Cookies win98 c:\windows/cookies
Klient Tjener Bok.html Cookie The Shadow Rising forepørsel Cookie betal.jsp betal.jsp respons betal.jsp Tomas Holt Blåbærv. 11 tomash@idb.hist.no forepørsel resultat.jsp respons
Bruksområder for cookies Identifikasjon av bruker i E-handel inneholder en unik ID Unngå brukernavn og passord lagres i cookie, slipper å skrive disse inn må ikke brukes hvis sikkerhet er viktig!! Skreddersy web-sider personlige innstillinger Spesifisert reklame husker oppførselen til brukeren og kan gi relevant reklame annonsøren får mer valuta for pengene bruker mer fornøyd
Fakta om cookies Nettleser kan settes til å nekte cookies! Kan gi problemer hvis vi lager løsning som kun baserer seg på cookies! Kan bruke omskriving av URL! Nettlesere har begrensninger på hvor mange cookies som aksepteres. Typisk 20 pr. område 300 totalt Størrelsen begrenses til 4 kb. disk fylles ikke opp
Inkludering av filer Hvorfor inkludering? se valgbokser.jsp i leksjon To typer: statisk => direktiv include dynamisk => hendelse include Statisk: inkludering skjer kun en gang! Evt. oppdateringer i inkludert fil vil ikke bli med Dynamisk: inkludering skjer hver gang. Oppdateringer i inkludert fil vises. statisk <%@ include file= relativ URL %> dynamisk : <jsp:include page= logo.html flush= true />
<HTML> <HEAD></HEAD> <BODY> direktiv_include.jsp <%@ include file="logo.html" %> <P><H1> Dette er velkomstsiden </H1> <P> blabla... logo.html <IMG SRC="logo1.bmp" ALIGN=RIGHT BORDER= <A HREF="http://laura.net"> Forsiden </A> <A HREF="mailto:laura@investements.com"> E-post Laura </A> <BR CLEAR=all> </BODY> </HTML> Resulterende servlet Til klient public class KlokkeServlet extends HttpServlet { public void service(httpservletrequest req, HttpServletResponse res) throws IOException, ServletException { res.setcontenttype("text/html"); PrintWriter out = res.getwriter(); out.println( <HTML> <HEAD></HEAD> <BODY> <IMG SRC="logo1.bmp" ALIGN=RIGHT BORDER=1> <A HREF="http://laura.net"> Forsiden </A> <A HREF="mailto:laura@investements.com">E-post Laura </A> <BR CLEAR=all> <P><H1> Dette er velkomstsiden </H1> <P> blabla... </BODY> </HTML> ); } }
<HTML> <HEAD></HEAD> <BODY> direktiv_include.jsp <jsp:include page= logo.html flush= true /> <P> <H1> Dette er velkomstsiden </H1> <P> blabla... logo.html <IMG SRC="logo1.bmp" ALIGN=RIGHT BORDER=1> <A HREF="http://laura.net"> Forsiden </A> <A HREF="mailto:laura@investements.com"> E-post Laura </A> <BR CLEAR=all> </BODY> </HTML> import javax.servlet.http.*; import javax.servlet.*; import java.io.*; Resulterende servlet Til klient public class KlokkeServlet extends HttpServlet { public void service(httpservletrequest req, HttpServletResponse res) throws IOException, ServletException { res.setcontenttype("text/html"); PrintWriter out = res.getwriter(); out.println( <HTML> <HEAD></HEAD> <BODY> <p align=center> REFERANSE</p> <H1 align=center> Dette er velkomstsiden </H1> <p> blabla... </BODY> </HTML> ); }
Konklusjon inkludering Ved statisk inkludering kan en bruke kode fra den andre filen f.eks. metoder. Bruke dynamisk inkludering når du ikke har to JSP er som bruker kode fra hverandre er veldig opptatt av ytelse. Statisk inkludering vil være raskere da inludering skjer en gang og kompileres inn i koden til servlet en.
Sesjoner Tilstandslagring på tjenersiden Kan lagre objekter og tabeller! ikke tilfellet for de andre teknikkene Innebygget objekt i JSP session-objektet Kan med dette objektet ta vare på tilstander for et web-sted web-sted er en samling web-sider som hører sammen (bokhandel)
Klient Web-sted Velkommen.jsp Sessionobjekteter SessionID=1 brukernavn = tomas SesjonsID= 1... SesjonsID= 56 Nyheter.jsp... Klient Musikk.jsp SessionID=56 brukernavn = arne
Bruk av session-objektet SesjonsID <% session.getid() %> Ny eller gammel sesjon <% session.isnew() %> Lagre tilstandsinformasjon <% session.setattribute(string navn, Object obj) %> f.eks. String brukernavn = request.getparameter( navn ); session.setattribute( navn, brukernavn); henter ut verdien med <% session.getattribute(string navn) %> f.eks. session.getattribute( navn );
taimot.jsp <%-- taimot.jsp ; navne-info og lagrer --%> <html><body> <% String navnvar = request.getparameter("navn"); if (navnvar!= null &&!navnvar.equals("")){ //ta vare på navnet til senere session.setattribute("navn",navnvar); out.println("navnet lagret"); }else out.println("ikke noe navn å ta vare på"); %> <p> <a href=./skrivutnavn.jsp> Gå til en skrivut.jsp for å se navnet du oppga </a> </body></html>
skrivut.jsp <%-- skrivutnavn.jsp ; skriver ut lagret navn --%> <html><body> Ditt navn er: <%= session.getattribute("navn") %> </body> </html>
Varighet av en sesjon Varigheten er avhengig av varigheten på klientside og tjenerside Klientside: cookies/omskriving URL På tjenerside har web-tjeneren en default verdi for hvor lang tid det går fra siste livstegn til sessionobjektet slettes. kan sette dette selv i JSP en <% session.setmaxinactiveinterval(5*60); //5 min. %> kan også fjerne session-ojektet eksplisitt <% session.invalidate(); %> kan også fjerne et objekt fra session-objektet <% session.removeattribute( navn ); %>
Sesjoner uten cookies I stedet for cookies kan sesjonsid sendes ved omskriving av URL. egen metode for dette i forb. med sesjoner response.encodeurl( url.jsp ); eksempel: Vanligvis bruker vi <form action= url.jsp > For å støtte omskriving av URL gjør vi <form action= <%= response.encodeurl( url.jsp ) %> > vi gjør dette på alle URL er i JSP en vår => sikret i tilfelle nettleser ikke aksepterer cookies.
Konklusjon sesjoner Sesjoner er et kraftig verktøy Tenk igjennom hvor lenge sesjonsinformasjon skal tas vare på husk denne informasjonen ligger i minnet på tjeneren Får du problemer med ytelsen på tjeneren kan du bruke en av disse metodene cookies omskriving av URL gjemte felt disse tar ikke opp minne i tjeneren!
Application-objektet Er veldig likt session-objektet, men det finnes kun et application-objekt pr. web-sted. Kan her lagre ting som skal være tilgjengelig i alle JSP er for alle klienter f.eks. kanskje vi skal skrive ut en teller på alle websidene på dette web-stedet. Kan også lage teller med bruk av fil ulempe må lese/skriv til fil hele tiden application-objektet er i minnet! Bruk fil ved statisk informasjon. Application-objektet på samme måte som sessionobjektet med setattribute() og getattribute()
Synkronisering Problemer når en får flere oppdateringer av application-objektet samtidig. vis kjøring av application.jsp <% Integer tmpteller = (Integer)application.getAttribute("teller"); int tmp = tmpteller.intvalue(); application.setattribute("teller", new Integer(tmp+1)); //oppdaterer verdien i application-objektet %>
Løsning isthreadsafe Direktivet isthreadsafe <%@ page isthreadsafe=false %> defaultverdi = true nå kjører kun en likedan JSP på en gang (service-metoden til generert servlet) Merk at isthreadsafe ikke hindrer to ulike JSP er (servlets) til å nå application-objektet samtidig!
Synkronisering av applicationobjektet Kan sørge for å synkronisere applicationobjektet slik at kun en forespørsel blir behandlet av det samtidig. <% synchronized(application){ Integer tmpteller = (Integer)application.getAttribute("teller"); int tmp = tmpteller.intvalue(); application.setattribute("teller", new Integer(tmp+1)); //oppdaterer verdien i application-objektet }
Deklarering inne i scriptlet <% int tall = 0 %> Overgang til servlet public class enservlet extends HttpServlet{ public void service(..){ int tall = 0; }
<%! int tall = 0 %> Objektvariabler Overgang til servlet public class enservlet extends HttpServlet{ int tall = 0; public void service( ){... }
Synkronisering av objektvariabler <%! int teller = 0; %> <%= "Oppstart av JSP: " + new java.util.date() %> <BR> <%= "Verdien på telleren ved oppstart " + teller %> <% syncronized(this){ int tmp = teller teller = tmp + 1; } %> <BR> <%= "Ny verdi til teller: " + teller %>
Initialisering av en JSP Vi kan initialisere en JSP-med å lage oss metoden jspinit() i JSP en. Denne metoden vil kun kjøres ved første forespørsel til denne JSP en. Det finnes også en maken jspdestroy() som kan brukes til opprydding i det JSP en (servlet en) fjernes. typisk når web-tjeneren avsluttes.
Eksempel initialisering <%! %> Date dato; public void jspinit(){ dato = new java.util.date(); } <%= Første besøk var: + dato %>