Servletek, J2EE 2 Több réteg! architektúrák Kommunikációs minták Client- Server 3-Tier Web Application Web Services Hybrid P2P Fractal
3 Web alkalmazások Business Systems DB Server App Server Web Server Browser Client J2EE J2SE/ J2ME Web Application 4 Web services Bus. Sys. DB App Web Browser XML (UDDI, SOAP) Context and Identity (LDAP, Policy, Liberty) J2EE J2SE/ J2ME Web Service
5 Servletek dinamikus html tartalom generálás üzleti alkalmazás web interfészének kialakítása servletek Java technológia webszerver kiterjesztése 6 Servletek vs. CGI Servlet el!nyök Hatékonyság Kényelem Platform és szerver független Session management Request Request CGI1 CGI1 Biztonságos Request CGI2 Request CGI2 Request Request CGI1 CGI1 CGI CGI Based Webserver Child Child for for CGI1 CGI1 Child Child for for CGI2 CGI2 Child Child for for CGI1 CGI1 Request Request Servlet1 Servlet1 Request Request Servlet2 Servlet2 Request Servlet1 Servlet Servlet Based Based Webserver Webserver Servlet1 Servlet1 JVM JVM Servlet2 Servlet2
7 J2EE konténerek Komponensek végrehajtási környezete Egyszer" API Transzparensek Enterprise API biztosítása Applet Container Web Container EJB Container Applet HTTP/ JSP Servlet EJB HTTPS RMI J2SE App Client Container App Client HTTP/ HTTPS JNDI J2SE RMI JNDI JMS RMI/IIOP JMS JDBC JTA JavaMail JAF RMI/IIOP JDBC JNDI JMS JTA JavaMail JAF RMI/IIOP JDBC J2SE J2SE Database 76 8 Servlet m!ködése Server Machine Servlet Java Class Client Machine Web Browser HTML doget or dopost HTML Web Server Init Service HTML HTML doget dopost Destroy
9 Servlet osztályok Servlet Basic Servlet Layer Method: service ServletRequest ServletResponse HttpServlet Methods: Service doget dopost init destroy etc. Http Servlet Layer HttpServletRequest HttpServletResponse MyServlet Methods: doget dopost init destroy etc. Your Servlet Code 10 doget, dopost public void doget(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException public void doput(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException HttpServletRequest kérés paraméterei, http fejléc mez!k, post adatok HttpServletResponse válasz fejléc, html tartalom
11 Servlet output public void doget(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head><title>first Servlet program</title></head>"); out.println("<body>"); out.println("<h1>welcome to Servlets</H1>"); out.println("</body>"); out.println("</html>"); out.close(); 12 Servlet konténerek Apache Tomcat (referencia implementáció) Allaire JRun Gefion LiteWebServer Sun Java Web Server
13 Servlet kód template import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ServletTemplate extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { // Use "request" to read incoming HTTP headers // (e.g. cookies) and HTML form data (e.g. data the user // entered and submitted). // Use "response" to specify the HTTP response status // code and headers (e.g. the content type, cookies). PrintWriter out = response.getwriter(); // Use "out" to send content to browser 14 Servlet példa import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head>"); out.println("<title>hola</title>"); out.println("</head>"); out.println("<body bgcolor=\"white\">"); out.println("<h1> Hi </h1>"); out.println("</body>"); out.println("</html>");
15 A servlet telepítése Context web application <inst.dir>/conf/server.xml <inst.dir>/webapps dir mine mine/web-inf mine/web-inf/classes mine/web-inf/lib mine/web-inf/web.xml <inst.dir>/tomcat-docs/appdev/ web.xml.txt 16 web.xml <display-name>my Web Application</display-name> <description> Examples by Me </description> [...] <context-param> <param-name>webmaster</param-name> <param-value>your@email.address</param-value> <description> The EMAIL address of the administrator to whom questions and comments about this application should be addressed. </description> </context-param> <servlet> <servlet-name>hi</servlet-name> <description> Testing </description> <servlet-class>hi</servlet-class> </servlet> <servlet-mapping> <servlet-name>hi</servlet-name> <url-pattern>/hi</url-pattern> </servlet-mapping>
17 Servlet életciklus // load the servlet class and setup request, response objects Servlet servlet = ServletRequest request = ServletResponse response = // initialise servlet ServletConfig config = servlet.getservletconfig(); servlet.init(config); // service zero or more requests while ( more requests ) // invoke servlet to process request servlet.service(request, service); Call to methods doget(), dopost() in the user defined servlet class // cleanup after service servlet.destroy(); Unlike CGI a single servlet can service several requests. In CGI, server invokes a separate process for each request. Servlets therefore reduce server load CCTM: Course material developed by James King (james.king@londonmet.ac.uk) 18 Inicializálás import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** Example using servlet initialization. Here, the message * to print and the number of times the message should be * repeated is taken from the init parameters. */ public class ShowMessage extends HttpServlet { private String message; private String defaultmessage = "No message."; private int repeats = 1; public void init(servletconfig config) throws ServletException { // Always call super.init super.init(config); message = config.getinitparameter("message"); if (message == null) { message = defaultmessage; try { String repeatstring = config.getinitparameter("repeats"); repeats = Integer.parseInt(repeatString); catch(numberformatexception nfe) { // NumberFormatException handles case where repeatstring // is null *and* case where it is something in an // illegal format. Either way, do nothing in catch, // as the previous value (1) for the repeats field will // remain valid because the Integer.parseInt throws // the exception *before* the value gets assigned // to repeats. <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2// EN" "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd"> <web-app> <servlet> <servlet-name> ShowMsg </servlet-name> <servlet-class> coreservlets.showmessage </servlet-class> <init-param> <param-name> message </param-name> <param-value> Shibboleth </param-value> </init-param> <init-param> <param-name> repeats </param-name> <param-value> 5 </param-value> </init-param> </servlet> </web-app> web.xml
19 Inicializálás (példa) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** Example using servlet initialization and the * getlastmodified method. */ public class LotteryNumbers extends HttpServlet { private long modtime; private int[] numbers = new int[10]; /** The init method is called only when the servlet * is first loaded, before the first request * is processed. */ public void init() throws ServletException { // Round to nearest second (ie 1000 milliseconds) modtime = System.currentTimeMillis()/1000*1000; for(int i=0; i<numbers.length; i++) { numbers[i] = randomnum(); public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); String title = "Your Lottery Numbers"; out.println(servletutilities.headwithtitle(title) +"<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<B>Based upon extensive research of " + "astro-illogical trends, psychic farces, " + "and detailed statistical claptrap, " + "we have chosen the " + numbers.length + " best lottery numbers for you.</b>" + "<OL>"); for(int i=0; i<numbers.length; i++) { out.println(" <LI>" + numbers[i]); out.println("</ol>" + "</BODY></HTML>"); 20 Inicializálás (példa folyt.) /** The standard service method compares this date * against any date specified in the If-Modified-Since * request header. If the getlastmodified date is * later, or if there is no If-Modified-Since header, * the doget method is called normally. But if the * getlastmodified date is the same or earlier, * the service method sends back a 304 (Not Modified) * response, and does <B>not</B> call doget. * The browser should use its cached version of * the page in such a case. */ public long getlastmodified(httpservletrequest request) { return(modtime); // A random int from 0 to 99. private int randomnum() { return((int)(math.random() * 100));
21 HttpServletRequest osztály String getmethod() obtain the HTTP request is it a GET or POST String getparameter(string name) - get a parameter (covered later) String getremotehost() - client s host name String getremoteaddr() - IP address of client String getservername() - servers name int getserverport() - port on which server was initially contacted on (8080 is usually intranet only and not accessible from outside) String getheader("user-agent") - name of client s web browser String getheader("referer") - URL of page that called the servlet some more methods... 22 HttpServletRequest példa import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ServEnvData extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head><title>environment Data</TITLE></HEAD>"); out.println("<body>"); out.println("<h1>servlet Environment</H1>"); out.println("<b>method:</b>"+request.getmethod()+"<br>"); out.println("<b>client Host:</B>"+request.getRemoteHost()+"<BR>"); out.println("<b>client's IP Address:</B>"+request.getRemoteAddr()+"<BR>"); out.println("<b>server Name:</B>"+request.getServerName()+"<BR>"); out.println("<b>server Port:</B>"+request.getServerPort()+"<BR>"); out.println("<b>client's Browser:</B>"+request.getHeader("User-Agent")+"<BR>"); out.println("<b>client's URL:</B>"+request.getHeader("Referer")+"<BR>"); out.println("</body>"); out.println("</html>"); out.close();
23 HttpServletRequest példa (folyt.) 24 HttpServletResponse osztály void response.addcookie(cookie cookie) void response.senderror(int status) - standard HTTP status codes void response.sendstatus(int status) - send HTTP status codes that are not errors void response.sendredirect(string location) - sends a redirect response to the client some more methods...
25 URL és form paraméterek <a href="http://www3.unl.ac.uk:8186/kingj1/servlet/param?p1=hello"> click here for a parameter example! </a> String parameter=request.getparameter("p1"); <a href="http://www3.unl.ac.uk:8186/kingj1/servlet/param? p1=hello&p2=goodbye"> click here for a parameter example! </a> Enumeration p=request.getparameternames(); while (p.hasmoreelements()) { String n=(string)p.nextelement(); String v=request.getparameter(n); out.println("parameter name is "+n+" parameter value" +v+"<br>"); 26 Kiszolgálás több szálon servlet meghívása konkurrens kérésekb!l globális változók kezelése?
27 Nem megfelel" megoldás (pl.) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class multi extends HttpServlet { int count=0; public void doget(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head><title> Thread UNSAFE example </TITLE> </HEAD> "); out.println("<body>"); out.println("<h1> old count is "+count+"</h1>"); count=count+1; try { Thread.sleep(4000); catch (Exception e) { out.println("<h1> new count is "+count+"</h1>"); out.println("</body>"); out.println("</html>"); 28 Megoldások nincsenek globális adatok session és cookie kezelés tárolás kliens oldalon kritikus szakasz megvalósítás szinkronizálás
29 Synchronized (pl.) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class multi extends HttpServlet { int count=0; Object s=new Object(); public void doget(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head><title> Thread UNSAFE example </TITLE> </HEAD> "); out.println("<body>"); synchronized (s) { out.println("<h1> old count is "+count+"</h1>"); 30 Perzisztens adatok Állapot meg!rzése servlet újratöltések és inicializálások között Szerver részér!l meghatározatlan újratöltési id!pontok
31 Probléma (pl.) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class global extends HttpServlet { int count=0; public void doget(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head><title> Global Data Example </TITLE> </HEAD> "); out.println("<body>"); out.println("<h1> old count is "+count+"</h1>"); 32 Megoldás HttpServletContext attribútumok requestben elérhet!k újra fordításkor elveszik
33 Megoldás (pl.) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; public class context extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws IOException, ServletException { Integer count=new Integer(0); response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); out.println("<html>"); out.println("<head><title> Global Data Example </TITLE> </HEAD> "); out.println("<body>"); Date d=new Date(); out.println("current time is "+d); ServletContext s=getservletcontext(); count=(integer)s.getattribute("count"); if (count==null) { count=new Integer(0); s.setattribute("count",count); int c=count.intvalue(); out.println("<h1> old count is "+c+"</h1>"); c=c+1; out.println("<h1> new count is "+c+"</h1>"); count=new Integer(c); s.setattribute("count",count); out.println("</body>"); out.println("</html>"); 34 Kliens oldali állapottárolás session kliens életciklus több kérés-válasz páron keresztül szerver adminisztálja egyedi azonosító törlés, élettartam lejárta
35 Session ID kezelés URL generálás rejtett form mez! cookie SSL session id 36 Cookie HTML header név, érték (URL) Set-cookie: FavColours=Blue; Max-age=60; Domain=.unl.ac.uk ; Path= / ; korlátozások 20 cookie per webszerver 4 KB méret
37 HttpSession nagy mennyiség" struktúrált adat tárolása attribútumok Java objects HttpServletRequest 38 HttpSession (folyt.)... HttpSession s= request.getsession(true); s.setmaxinactiveinterval(60); Integer value=new Integer(0); value=(integer)s.getattribute("value"); if (value==null) { value=new Integer(0); s.setattribute("value",value); out.println("<h1> The session has id "+s.getsessionid()+"</h1>"); out.println("<h1> old value is "+value+"</h1>"); value=new Integer(value.intValue()+1); out.println("<h1> new count is "+ s.getattribute("value") +"</H1>"); s.setattribute("value",value);...
39 Cookie kezelés Lekérdezés public void doget(httpservletrequest request, HttpServletResponse response) {. Cookie cookie = null; Cookie[] cookies = request.getcookies(); if (cookiearr!= null) { for (int i = 0; i < cookies.length; i++) { cookie = cookies[i]; String name = cookie.getname(); if (name.equals( FavColours")) { out.println(cookie.value());. Beállítás cookie = new Cookie( FavColours, Blue ); cookie.setmaxage(600); response.addcookie(cookie); 40 Servlet debuggolás wget curl WebClient