INFITT01 – Internettechnologie WEEK 2
Programma • • • •
Contexts Listeners Scope/Attributes Thread safety
Taken container Een servlet ‘draait’ in een container (servlet container). De container, die ten dienste van de servlets staat, heeft veel taken waaronder: • Initialiseert een ServletConfig per servlet • Initialiseert één ServletContext voor alle servlets • Instantieert listeners • Coordineert de ‘lifecycle’ van attributen binnen een bepaalde scope • en meer taken (zie les 1)
ServletConfig Een object, aangemaakt door de container, waarin informatie voor een specifieke servlet kan worden meegegeven. Stel in servlet A wil je in de response een bepaalde naam terug geven om te tonen: protected void doGet(HttpServletRequest req, HttpServletResponse res) ...{ ... out.println("Mijn naam is Piet"); ... } De naam 'Piet' staat nu hard gecodeerd in de servlet en kan alleen veranderd worden door deze te wijzigen en de servlet opnieuw te compileren.
ServletConfig In web.xml: <webapp .....> <servlet> <servlet-name>hello <servlet-class>test.HelloServlet
<param-name>name <param-value>Piet <servlet-mapping> <servlet-name>hello
/hello In servlet uitlezen met: getServletConfig().getInitParameter("name");
ServletContext Een object, aangemaakt door de container, waarin informatie voor alle servlets in de webapp kan worden meegegeven. In web.xml: <webapp ...>
<param-name>name <param-value>Piet <servlet ...
Aanroep: getServletContext().getInitParameter("name");
ServletConfig & ServletContext ServletContext
Servlet A
Servlet B
Servlet C
JSP
ServletConfig: elke servlet/JSP z'n eigen ServletConfig
ServletContext & ServletConfig De ServletContext en ServletConfig worden slechts één keer geladen, bij het initialiseren van de servlet. Je kunt deze parameters dus niet wijzigen zolang de webapp draait. De parameters zijn altijd String objecten. Hoe bijvoorbeeld een DataSource object initialiseren?
Listeners Een listener = een object dat geïnstantieerd wordt als een bepaalde gebeurtenis (event) binnen de webapp zich voor doet. Bijv. een webapp wordt gedeployed (= event dat één keer op treedt). javax.servlet.ServletContextListener = een interface
die door een class geïmplementeerd moet worden en heeft twee methodes: • •
public void contextInitialized(ServletContextEvent sc); public void contextDestroyed(ServletContextEvent sc);
Listeners declareer in web.xml: <webapp ...> ... <listener> <listener-class> com.example.MijnServletContextListener ...
Deze class wordt in WEB-INF/classes gezet (vergeet niet de package structuur aan te maken)
Scope In een webapp zijn 4 soorten scope. Een scope is een bepaald gebied binnen een webapp. Application scope (hele webapp) Session scope (meerdere requests) Request scope (= threadsafe) Page scope
Scope en attributen In een scope kunnen zelf gemaakte objecten (attributen) worden gecreëerd die informatie doorgeven. Een attribuut is een soort bulletinbord waar informatie op geprikt is om aan een ander (servlet) door te geven. vragen: • Wie heeft toegang tot deze attributen? • Wat is de scope van deze attributen? ( m.a.w. hoe lang ‘leven’ ze?)
Scope en attributen – application scope Servlet A en Servlet B kunnen application attribute “name” uitlezen
Context attributes
Servlet A Attribute …
Attribute … Attribute name Servlet B
Scope en attributen – session scope Als servlet A en Servlet B requests verwerken die in dezelfde sessie zijn gecreëerd als het attribuut “name” dan hebben beide toegang tot “name”. Webapp, container Sessie 1
Servlet A attribute name
Sessie 2 attribute email
Servlet B
Scope en attributen – request scope Servlet A geeft een request waarin een attribuut staat door aan servlet B. B heeft toegang tot dit attribuut.
Request attribute address
Servlet A
Servlet B
Scope en attributen • Application scope – objecten globaal toegankelijk voor alle servlets (en dus ook JSP's) in de webapp
• Session scope – objecten toegankelijk voor servlets die requests ‘verwerken’ die gecreëerd zijn in dezelfde sessie als de objecten – in principe zolang de gebruiker is ingelogd of bijv. een winkelwagentje
• Request scope – objecten alleen toegankelijk voor servlets die dezelfde request verwerken – zodra request eindigt in een response wordt object verwijderd.
• Page scope – objecten alleen toegankelijk binnen een bepaalde servlet/JSP
attributen operaties Doorgeven/zetten: • •
void setAttribute(String lookupName, Object value) bijv. request.setAttribute("mijnreqattribuut", object)
Verkrijgen: • •
Object getAttribute(String lookupName) bijv. session.getAttribute("mijnsesattribuut")
Verwijderen: • •
void removeAttribute(String lookupName) bijv. application.removeAttribute("mijnappattribuut")
Thread safety De container start een nieuwe thread voor elk request. Als meerdere requests dezelfde servlet.doGet() methode aanroepen dan zijn alle variabelen gedeclareerd binnen de methode thread safe (variabelen kunnen niet door andere thread gewijzigd worden).
Thread safety Alle scopes/variabelen die toegankelijk zijn voor meerdere requests zijn NIET threadsafe! Voorbeeld: een attribuut in application scope. • User A start en roept servlet A aan met de request parameter “getal” met waarde “10” (in application scope staat al waarde “2”) • Met behulp van de volgende berekening in de servlet
𝑔𝑒𝑡𝑎𝑙 = ℎ𝑢𝑖𝑑𝑖𝑔𝑒 𝑤𝑎𝑎𝑟𝑑𝑒 𝑔𝑒𝑡𝑎𝑙 ∗ 𝑛𝑖𝑒𝑢𝑤𝑒 𝑤𝑎𝑎𝑟𝑑𝑒 𝑔𝑒𝑡𝑎𝑙
• •
wordt een response gegeven met waarde “20”. Deze uitkomst wordt in de application scope gezet. User B doet ook een request met getal=“5”. In de application scope komt nu “100” te staan. User A doet weer een request met getal=“1”. Hij zou nu “20” verwachten, maar krijgt “100” terug. De thread van User B heeft de waarde gewijzigd.
Vraag: Is de session scope threadsafe?
Thread safety Sessies zijn nog niet behandeld, maar ze zijn er om 'conversational state' tot stand te brengen tussen één client en een server (= één request per keer) ... dus geen andere thread die een object in jouw sessie kan wijzigen ... dus threadsafe ... toch?
Vraag: Is het mogelijk om vanaf één client meerdere requests tegelijkertijd naar de servlet te sturen?
Thread safety
Alleen de request scope is threadsafe!