Creazione servlet

di il
27 risposte

27 Risposte - Pagina 2

  • Re: Creazione servlet

    newutente ha scritto:


    secondo me una volta salvata la pagina (dentro Web Pages), creata la servlet (dentro Source Packages) e modificato il file web.xml bisogna avviare la pagina html creata.
    in questo modo parte l'application server (nel mio caso GlassFish) che non fa altro che "collegare" la pagina html con il file web.xml, che "conosce" la servlet, e da lì inizia l'esecuzione della servlet.
    Ti suggerisco di leggere qualcosa riguardo il "ciclo di vita" delle Servlet. Non ho link utili da fornirti subito in questo momento. Se fai qualche ricerca con google trovi sicuramente anche qualcosa in italiano.
    Potresti anche guardare sulle Servlet Specification (qualunque versione recente, 2.4, 2.5, 3.x) che sebbene è in inglese ti assicuro che perlomeno quella sezione "Servlet Life Cycle" è molto leggibile.
  • Re: Creazione servlet

    Ho cercato maggiori informazioni sul ciclo di vita di una servlet e ora ho le idee più chiare però ho ancora qualche dubbio circa quello che accade proprio a livello di IDE. Cerco di spiegarmi meglio.
    Io ho capito che una volta avviata la servlet per prima cosa viene invocato il metodo init() (praticamente una sorta di metodo main() della servlet) che la inizializza, una volta inizializzata viene invocato il metodo service() che a sua volta richiama, in base alle esigenze, il metodo doGet() o il metodo doPost() ad esempio e per concludere avviene l'invocazione del metodo destroy().
    Questo è il ciclo di vita di una servlet stando a quello che ho capito, il mio dubbio però riguarda proprio quello che accade nell'esempio che avevo fatto prima.
    Inserisco le poche righe di codice così è più facile capire a cosa mi riferisco:

    web.xml
    
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
        <servlet>
            <servlet-name>UnsafeServlet</servlet-name>
            <servlet-class>UnsafeServlet</servlet-class>
            <init-param>
                <param-name>sleep</param-name>
                <param-value>10000</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>UnsafeServlet</servlet-name>
            <url-pattern>/UnsafeServlet</url-pattern>
        </servlet-mapping>
        <session-config>
            <session-timeout>
                30
            </session-timeout>
        </session-config>
    </web-app>
    
    logon.html
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>Una Applicazione Thread Unsafe</title>
      </head>
      <body>
        <h1>Login</h1>
    
        Inserire nei campi sottostanti la propria UserID e Password:
        <form action="UnsafeServlet" method="POST">
        <p><input type="text" name="userID" length="40" /></p>
        <p><input type="password" name="password" length="40" /></p>
        <p><input type="submit" value="Submit" /></p>
        </form>
      </body>
    </html>
    
    UnsafeServlet.java
    
    package unsafeweb;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.ServletConfig;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.PrintWriter;
    
    public class UnsafeServlet extends javax.servlet.http.HttpServlet
            implements javax.servlet.Servlet {
    
        private String userID;
        private String password;
    
        public UnsafeServlet() {
            super();
        }
    
        public void init(ServletConfig config) throws ServletException {
            super.init(config);
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String userID = request.getParameter("userID");
            String password = request.getParameter("password");
    
            this.userID = userID;
            this.password = password;
    
            try {
                String sleeptime = getInitParameter("sleep");
                int sleep = Integer.parseInt(sleeptime);
                Thread.sleep(sleep);
            } catch (Exception exc) {
                log("", exc);
            }
    
            try {
                response.setContentType("text/html");
                PrintWriter writer = response.getWriter();
                writer.println("<html><body>");
                writer.println("<p><u>Valori delle variabili locali al metodo" + " doPost()</u> <br />");
                writer.println("userID=" + userID + "<br/>");
                writer.println("password=" + password + "</p>");
                writer.println("<p><u>Valori degli attributi della Servlet</u><br />");
                writer.println("userID=" + this.userID + "<br />");
                writer.println("password=" + this.password + "</p>");
                writer.println("</body></html>");
                writer.close();
            } catch (Exception exc) {
                exc.printStackTrace();
            }
        }
    }
    
    In poche parole queste semplici righe di codice permettono di ottenere una pagina html dove poter inserire nome utente e password e una volta cliccato sul bottone, dopo 10 secondi, vengono restituiti i dati inseriti.
    Premetto subito che non ho alcun dubbio sul codice ma non riesco a capire cosa accade nel momento in cui avvio il file "logon.html", ok parte GlassFish e deployato il progetto mi viene visualizzata la pagina dove inserire nome utente e password, una volta inseriti e cliccato sul bottone per inviarli in risposta al server mi viene visualizzato questo errore nel browser:
    http://s21.postimg.org/8xfnd0hzb/Immagine.jp
  • Re: Creazione servlet

    newutente ha scritto:


    
    package unsafeweb;
    
    public class UnsafeServlet extends javax.servlet.http.HttpServlet
            implements javax.servlet.Servlet {
    
    Se la classe ha package, allora nel web.xml dovresti mettere

    <servlet-class>unsafeweb.UnsafeServlet</servlet-class>

    Tu invece hai messo:

    <servlet-class>UnsafeServlet</servlet-class>

    Comunque non serve dichiarare l'implementazione di javax.servlet.Servlet ... lo fa già HttpServlet.
  • Re: Creazione servlet

    Ah ecco, grazie.
    ma quella modifica devo farla anche nel tag <url-pattern>?
  • Re: Creazione servlet

    newutente ha scritto:


    ma quella modifica devo farla anche nel tag <url-pattern>?
    No, <servlet-class> è il nome completamente qualificato della classe. <url-pattern> è solo la specifica del url a cui vuoi sia mappato il name che corrisponde poi indirettamente alla servlet.

    In /UnsafeServlet il "/" corrisponde alla context-root. Quindi la servlet risponde a

    http://......../nomecontesto/UnsafeServlet

    Siccome la pagina di logon.html immagino sia anch'essa nella root, allora risponde a

    http://......../nomecontesto/logon.html

    e siccome nel form hai action="UnsafeServlet" che è un path relativo, esso è relativo alla posizione di logon.html e quindi l'url assoluto richiesto al submit è appunto quello della servlet.
  • Re: Creazione servlet

    So che mi hai già detto di lasciar perdere l'organizzazione dei package dell'IDE però vorrei capire questa storia del context-root.
    Stando a quello che ho capito praticamente il context-root, indipendentemente dall'IDE, ha questa struttura:
    
    root ---> "WEB-INF" ---> "classes" ---> classi lato server
        |     	       |
        |   	         ---> "lib" ---> file JAR di librerie
        |   	         |
        |               ---> descrittori XML (es. web.xml, glassfish-web.xml)
        ---> pagine XHTML
    
    quindi dovrebbe corrispondere alla cartella "Web Pages" presente alla creazione del progetto con NetBeans, però vabbè per il momento tralasciamo questa cosa.
    Il file .java della servlet in realtà è presente nella cartella "Source Packages" all'interno del suo package e quindi il tutto in NetBeans ha questa struttura:

    hosting immagini

    Stando a quello che dici dal punto di vista teorico la struttura del mio progetto è questa:
    
    root ---> "WEB-INF" ---> web.xml
         |     	            
         ---> logon.html
         |
         ---> "unsafeweb" ---> UnsafeServlet.java
    
    Giusto?
  • Re: Creazione servlet

    Stavo rivedendo le servlet dopo un po' di tempo e mi è venuto un dubbio.
    Supponiamo di avere una web application che permette di visualizzare il contenuto di un album di foto, quindi c'è un client (browser) si collega all'application server dove ci sono 3 servlet (una per visualizzare il contenuto dell'album, una per visualizzare la singola foto a pagina intera e una per rimuovere una determinata foto).
    Ogni foto ha un suo specifico indice e qui viene il dubbio che ho.
    Questa è la servlet che si occupa di visualizzare la foto:
    
    import java.io.*;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    @WebServlet(name = "DisplayPhotoServlet",
    		    urlPatterns = {"/DisplayPhotoServlet"})
    
    public class DisplayPhotoServlet extends HttpServlet {
    	@Override
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		String indexString = request.getParameter("photo");
    		int index = (new Integer(indexString.trim())).intValue();
    		response.setContentType("image/jpeg");
    		OutputStream out = response.getOutputStream();
    		try {
    			ServletContext myServletContext = request.getServletContext();
    			PhotoAlbum pa = PhotoAlbum.getPhotoAlbum(myServletContext);
    			byte[] bytes = pa.getPhotoData(index);
    			for (int i = 0; i < bytes.length; i++) {
    				out.write( bytes[i]);
    			}
    		} finally {
    			out.close();
    		}
    	}
    }
    
    nel momento in cui si clicca su una foto viene avviata la servlet in questione (poichè è mappata con il parametro "urlPatterns" ed è impostata per soddisfare richieste di tipo GET).
    Il dubbio che ho è relativo all'indice della foto. Come fa la servlet a riconoscere quale foto visualizzare? Ok, c'è il parametro "photo" estrapolato dalla richiesta, ma come fa questo parametro ad essere settato all'interno della richiesta?



    EDIT: giusto per completezza vi posto il contenuto della classe PhotoAlbum:
    
    import java.util.*;
    import javax.servlet.ServletContext;
    
    public class PhotoAlbum {
    	public static String ATTRIBUTE_NAME = "Photo_Album";
    	private List<byte[]> photoDataList = new ArrayList<byte[]> ();
    	private List<String> names = new ArrayList<String>();
    
    	public static PhotoAlbum getPhotoAlbum(ServletContext servletContext) {
    		if (servletContext.getAttribute(ATTRIBUTE_NAME) == null) {
    			PhotoAlbum pa = new PhotoAlbum();
    			servletContext.setAttribute(ATTRIBUTE_NAME, pa);
    		}
    		return (PhotoAlbum) servletContext.getAttribute(ATTRIBUTE_NAME);
    	}
    
    	public synchronized void addPhoto(String name, byte[] bytes) {
    		this.photoDataList.add(bytes);
    		this.names.add(name);
    	}
    
    	public synchronized byte[] getPhotoData(int i) {
    		return (byte[]) photoDataList.get(i);
    	}
    
    	public synchronized String getPhotoName(int i) {
    		return (String) names.get(i);
    	}
    
    	public synchronized int getPhotoCount() {
    		return photoDataList.size();
    	}
    
    	public synchronized void removePhoto(int i) {
    		photoDataList.remove(i);
    		names.remove(i);
    	}
    }
    
  • Re: Creazione servlet

    newutente ha scritto:


    Il dubbio che ho è relativo all'indice della foto. Come fa la servlet a riconoscere quale foto visualizzare? Ok, c'è il parametro "photo" estrapolato dalla richiesta, ma come fa questo parametro ad essere settato all'interno della richiesta?
    http://blabla..../nomecontesto/DisplayPhotoServlet?photo=1234
  • Re: Creazione servlet

    Ok ma quel 1234 come viene settato?
  • Re: Creazione servlet

    newutente ha scritto:


    ok ma quel 1234 come viene settato?
    Dipende ... puoi scrivere tu a mano l'url nel browser per vedere direttamente una certa foto oppure l'url può essere in una pagina html in un tag <img> magari generato dinamicamente a fronte di un'altra richiesta.
  • Re: Creazione servlet

    Questo è il codice del metodo displayAlbum() presente nella servlet che visualizza tutte le foto dell'album:
    
    private void displayAlbum(PhotoAlbum pa, String label, PrintWriter writer) {
    	writer.write("<h3 align='center'>" + label + "</h3>");
    	writer.write("<table align='center'>");
    	for (int j = 0; j < pa.getPhotoCount(); j++) {
    		writer.write("<td>");
    		writer.write("<a href='./DisplayPhotoServlet?photo=" + j + "'>");
    		writer.write("<img src='./DisplayPhotoServlet?photo=" + j + "' 
    		                            alt='photo' 
    		                            height='120' 
    		                            width='150'> ");
    		writer.write("</a>");
    		writer.write("</td>");
    	}
    	...
    }
    
    il parametro "photo" viene inizializzato semplicemente passando un indice di volta in volta (da zero fino alla dimensione della lista di array di byte dove sono contenute le immagini) ma quello che non capisco è come fa la servlet a capire che all'indice 0 ad esempio deve corrispondere una certa immagine.
    Provo a rispondermi da solo, nel momento in cui si clicca sulla foto viene avviata la servlet "DisplayPhotoServlet" che nella richiesta GET (o è POST poichè si invia un parametro?) segnerà l'indice di quella foto, giusto?
  • Re: Creazione servlet

    newutente ha scritto:


    quello che non capisco è come fa la servlet a capire che all'indice 0 ad esempio deve corrispondere una certa immagine.
    Se viene fatta la richiesta GET http://blabla..../nomecontesto/DisplayPhotoServlet?photo=1234, viene invocato il doGet di DisplayPhotoServlet. index vale quindi 1234 e getPhotoData verrà invocato con 1234. Se in photoDataList c'è lo stream di byte a quel indice ... bene. Altrimenti male, e tra l'altro si schianta con una eccezione.
  • Re: Creazione servlet

    Ok ora ho capito. grazie.
Devi accedere o registrarti per scrivere nel forum
27 risposte