Web-fejlesztés NGM_IN002_1 Dinamikus tartalom 2. Servletek
Java Servletek Szerver oldali alkalmazások Java nyelven szerver funkcionalitásának kiterjesztése dinamikus és interaktív tartalom el!állításra Web-tier komponens web-konténer run-time environment http protokoll servlet framework életciklus menedzsment URL leképezés Servletek vs. CGI Servlet el!nyök Hatékonyság Kényelem Platform és szerver független Session management Biztonságos Request Request CGI1 CGI1 Request Request CGI2 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
Servletek támogatása J2EE platform egyik összetev!je Servlet API-csomagok Servlet konténerek Önálló Apache Tomcat W3C Jigsaw Gefion LiteWebServer Beépül! J2EE platform 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 RMI EJB HTTPS J2SE App Client Container App Client HTTP/ HTTPS JNDI JMS JTA J2SE RMI JNDI JMS RMI/IIOP JDBC JavaMail JAF RMI/IIOP JDBC JNDI JMS JTA JavaMail JAF RMI/IIOP JDBC J2SE J2SE Database 76
Kérés kezelése servlettel Server Machine Servlet Java Class Client Machine Web Browser HTML doget or dopost Web Server Init Service HTML HTML HTML doget dopost Destroy 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 Példa
A Servlet telepítése Webalkalmazás rögzített könyvtár szerkezet.war fájlok konfiguráció Könyvtár szerkezet <inst.dir>/webapps dir mine mine/web-inf mine/web-inf/classes mine/web-inf/lib mine/web-inf/web.xml Példa Servlet életciklus Általában egy JVM Javaban írt szerver egyprocesszes szerver többprocesszes szerver (küls! JVM) Kérések közötti élet (perzisztencia) er!forrás takarékos perzisztenciát kívánó m"ködési logika
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) Inicializálás Primer osztálybetölt! szerver mag, classpath Egyedi osztálybetölt!k betöltés módosulás esetén Teljes környezet újratöltése servlet módosulása esetén kompatibilitás Példa 1 Példa 2
Kérések és válaszok HttpServletRequest kérés paraméterei, http fejléc mez!k, post adatok Példa HttpServletResponse válasz fejléc státusz, cookie, stb. html tartalom Kiszolgálás több szálon servlet végrehajtása konkurrens kérésekb!l globális változók, kritikus szakasz kezelése? nincsenek globális adatok session és cookie kezelés tárolás kliens oldalon kritikus szakasz megvalósítás szinkronizálás Példa
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 HttpServletContext attribútumok requestben elérhet!k újra fordításkor elveszik Példa Session kezelés Session több http kérés-válasz páron át tartó munkamenet szerver adminisztálja egyedi azonosító törlés, élettartam lejárta
HttpSession Rövidtávú session kezel! API nagy mennyiség" struktúrált adat tárolása attribútumok Java objects Elérés HttpServletRequesten keresztül Automatikus életciklus kezelés lejárati id! SessionID kezelés Cookie vagy URL újraírás Példa Session ID kezelés URL generálás rejtett form mez! cookie SSL session id
HelloWorld import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { public void doget(httpservletrequest req, HttpServletResponse res) throws ServletException, IOException { res.setcontenttype("text/html"); PrintWriter out = res.getwriter(); out.println("<html>"); out.println("<head><title>hello World</TITLE></HEAD>"); out.println("<body>"); out.println("<h1>hello World</H1>"); out.println("</body></html>"); 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>
Inicializálás 1. 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/webapp_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> Inicializálás 2. 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>");!! /** The standard service method compares this date!! * against any date specified in the If-Modified-Since!! * request header. */! public long getlastmodified(httpservletrequest request) {!! return(modtime);!! // A random int from 0 to 99.! private int randomnum() {!! return((int)(math.random() * 100));!
HttpServletRequest 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(); Szinkronizálás
Szinkronizálás 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>"); Szinkronizálás 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>"); count=count+1; try { Thread.sleep(4000); catch (Exception e) { out.println("<h1> new count is "+count+"</h1>"); out.println("</body>"); out.println("</html>");
Perzisztens adatok 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>"); HttpSession... 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);...