Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    17

    Salvataggio su file alla chiusura della servlet

    Salve a tutti,
    sto progettando una servlet che utilizza dei file,
    questi vengono letti all'apertura (nel metodo init() ) ed i dati presi e memorizzati su un database;
    i dati possono nel frattempo essere modificati sul db e vorrei, a questo punto, che quando la servlet termina il servizio/si stoppa il server i dati del database vengano salvati su dei file.
    Ho provato a mettere nel metodo destroy() la chiamata ad un metodo della classe che gestisce il db e che dovrebbe fare questo, ma quando stoppo il server (uso eclipse per java ee) non succede nulla ed i file non sono aggiornati.

    questo è il metodo nella servlet:
    codice:
    	public void destroy() {				// ---> non viene chiamato !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    		System.out.println("sono nel destroy");
    		FileOutputStream fosCalendarioA = null, fosCalendarioB = null, fosCalendario1A = null;
    		FileOutputStream fosCalendario1B = null, fosCalendario2A = null, fosCalendario2B = null;
    		try {
    			fosCalendarioA = new FileOutputStream("/WEB-INF/File_del_Server/Calendario_A_1314.txt", true);
    			fosCalendarioB = new FileOutputStream("/WEB-INF/File_del_Server/Calendario_B_1314.txt", true); // throws FileNotFoundException
    			fosCalendario1A = new FileOutputStream("/WEB-INF/File_del_Server/Calendario_1A_1314.txt", true); // throws FileNotFoundException
    			fosCalendario1B = new FileOutputStream("/WEB-INF/File_del_Server/Calendario_1B_1314.txt", true); // throws FileNotFoundException
    			fosCalendario2A = new FileOutputStream("/WEB-INF/File_del_Server/Calendario_2A_1314.txt", true); // throws FileNotFoundException
    			fosCalendario2B = new FileOutputStream("/WEB-INF/File_del_Server/Calendario_2B_1314.txt", true); // throws FileNotFoundException
    		}
    		catch (FileNotFoundException e) {
    			e.printStackTrace();
    		}
    		synchronized (servletContext){
    			boolean esitoChiusura = DbHandler.salvaNeiFile(fosCalendarioA, fosCalendarioB, fosCalendario1A, fosCalendario1B, fosCalendario2A, fosCalendario2B);
    			if(esitoChiusura)	System.out.println("Salvataggio sui file eseguito");
    			else	System.out.println("Salvataggio sui file non eseguito");
    		}		
    	}
    la scritta "sono nel destroy" non viene visualizzata dopo che premo stop sul server, sbaglio qualcosa?

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Premetto che io non uso Eclipse e che, comunque, non uso un servlet container integrato nell'ambiente di sviluppo.

    Sono molte le considerazioni da fare su quel codice, che comunque è sbagliato.

    1) Dove dovrebbe essere visualizzato il messaggio "sono nel destroy"?
    Mandare messaggi su System.out dall'interno di una servlet fa sì che tali messaggi vengano redirezionati ad un file di log (che dipende dalla configurazione del servlet container, che dovrebbe essere Tomcat nel tuo caso). Hai verificato sui file di log di Tomcat se c'è quel messaggio? Tieni presente, inoltre, che quel messaggio viene inviato al log se e solo se la servlet viene effettivamente istanziata (cioè, se c'è stata almeno una richiesta per quella servlet), altrimenti il servlet container non ha nulla da dismettere in fase di shutdown, quindi nulla verrà inviato al file di log.

    2) Questa riga di codice (e tutte quelle dopo, molto simili) è logicamente sbagliata

    codice:
    fosCalendarioA = new FileOutputStream("/WEB-INF/File_del_Server/Calendario_A_1314.txt", true);

    Quando si scrivono web-applications e si intendono usare dei file su file-system bisogna sempre riferirsi a loro tramite il metodo getRealPath() fornito da ServletContext... perchè quel percorso punta ad una directory chiamata "WEB-INF" che si trova nella rood del disco fisso e non nella root dell'applicazione (come invece dovrebbe essere). Presumo che nella root del tuo disco fisso (posso immaginare che tu stia usando Windows e che il disco dove gira Tomcat sia il disco C: ) non vi sia nessuna directory "C:\WEB-INF". Sicché quel percorso è sbagliato. Quando si vuole ottenere un percorso "relativo alla root della web-app" bisogna appoggiarsi al ServletContext, che è l'unico a sapere quale sia la posizione assoluta della web-app. Quindi, tutti quei percorsi andrebbero modificati in questo modo:

    codice:
    ServletContext ctx = getServletContext();
    fosCalendarioA = new FileOutputStream(ctx.getRealPath("/WEB-INF/File_del_Server/Calendario_A_1314.txt"), true);

    E via via per tutti gli altri percorsi "simili".

    3) Il blocco di codice che effettua la scrittura dei file dovrebbe trovarsi all'interno del blocco try/catch in cui questi vengono creati, in modo da prevedere il meccanismo di chiusura dei file alla fine:

    codice:
    FileOutputStream fos = null;   // dichiaro gli oggetti
    try {
       // Creo gli output-streams
       fos = new FileOutputStream( ... );
    
       // Uso gli output-streams
       DbHandler.salvaNeiFile( ... );
    
       // Effettuo un flush, per assicurarmi che la scrittura venga fatta
       fos.flush();
    } catch(Exception e) {
       e.printStackTrace();
    } finally {
       if (fos != null) {
          // Se il file è stato correttamente aperto, mi assicuro di chiuderlo!
          try { fos.close(); } catch (Exception e) { }
       }
    }

    Ciao.
    Ultima modifica di LeleFT; 15-01-2014 a 14:41
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    17
    grazie della risposta!
    1) il System.out.println l'ho messo per me per vedere che "da la ci passa" e vengono visualizzati sulla console di eclipse, in altri punti della servlet faccio lo stesso e ciò funziona tranquillamente; in questa parte no.

    2) hai totalmente ragione, avevo preso "esempio" da del codice che ho trovato in giro e ne avevo qualche dubbio, l'ho così modificato:
    codice:
     fosCalendarioA = new FileOutputStream(getServletContext().getRealPath("/WEB-INF/File_del_Server/Calendario_A_1314.txt"), true);
    3) allo stesso modo mi sembrava strano che non fosse necessario il try catch ma di solito l'ide lo chiede sempre mentre in questo caso no

    anche così non cambia niente, sembra proprio che il destroy non venga chiamato
    Ultima modifica di aledpa; 15-01-2014 a 17:15

  4. #4
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    17
    L'ho modificato un pò ma ancora nulla,
    questa è la chiamata nella servlet:

    codice:
    -------------------  compreso tra try catch ----------------------
    fos = new FileOutputStream(getServletContext().getRealPath("/WEB-INF/File_del_Server/Calendario_" + serie +"_1314.txt"), true);
    -----------------------------------------------------------------
    esito = DbHandler.salvaNelFile(fos, s, g, sC, sFC, r);
    il metodo nella classe DbHandler è:

    codice:
    public static boolean salvaNelFile(FileOutputStream fos, String serie,
    			String giornata, String squadraCasa, String squadraFuoriCasa,
    			String risultato) {
    		Connection con = getHsqlDbConnection();
    		ResultSet res = null;
    		boolean result = false;
    		try {
    			ObjectOutputStream oos=new ObjectOutputStream(fos); // throws IOException
    			String intestazioniGiornate = "Giornata 1\nData\tIncontro\tRisultato";
    			String query = "select * from CALENDARIO" + serie + " WHERE 1=1 ORDER BY _id";
    			res = con.createStatement().executeQuery(query);
    			System.out.println(intestazioniGiornate);
    			oos.writeObject(intestazioniGiornate);
    			int conteggio = 0,  numGiornata = 1;
    			while(res.next()){
    				if(serie.equals("A") && conteggio == 10 ||
    						serie.equals("B") && conteggio == 11 ||
    						serie.equals("1A") && conteggio == 9 ||
    						serie.equals("1B") && conteggio == 8 ||
    						serie.equals("2A") && conteggio == 9 ||
    						serie.equals("2B") && conteggio == 9) {
    					conteggio = 0;
    					oos.writeObject("");
    					numGiornata++;
    					intestazioniGiornate = "Giornata " + numGiornata + "\nData\tIncontro\tRisultato";
    					System.out.println(intestazioniGiornate);
    					oos.writeObject(intestazioniGiornate);
    				}
    					String d = res.getString("Data");
    					String c = res.getString("Casa");
    					String o = res.getString("Ospiti");
    					String r = res.getString("Risultato");
    					int posizioneTrattino = r.indexOf("-");
    					String risCasa = "";
    					String risOspiti = "";
    					if(posizioneTrattino != -1){		// c'è il trattino
    						risCasa = r.substring(0, posizioneTrattino);
    						risOspiti = r.substring(posizioneTrattino + 1);
    					}
    					String nuovaRiga = d + "\t" + c + "\t" + o + "\t" + risCasa + "\t" + risOspiti;
    					System.out.println("nuovariga= Serie " + serie + " " + nuovaRiga);
    					oos.writeObject(nuovaRiga); // throws IOException
    					conteggio++;
    			}
    			oos.flush();
    			oos.close();
    			result = true;
    		}
    		catch (Exception e) {
    			e.printStackTrace();
    			result = false;
    	    }
    		finally{
    			if (connection != null) closeDb();
    		}
    		return result;
    	}
    questa volta le operazioni le esegue (mi aiuto con le System.out.println) ma i file non vengono scritti mai, c'è sempre quello che c'era prima (quando vengono letti per intenderci) e non mi viene dato nessun errore.
    Qualche consiglio?

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Quote Originariamente inviata da aledpa Visualizza il messaggio
    Qualche consiglio?
    Aggiungi queste due righe di codice:

    codice:
    String path = getServletContext().getRealPath("/WEB-INF/File_del_Server/Calendario_" + serie +"_1314.txt");
    System.out.println("Percorso fisico: " + path);

    E verifica dove viene creato quel file e con che nome.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  6. #6
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    17
    mi viene restituito questo:
    codice:
    Percorso fisico: C:\Program Files\eclipse2\workspace_Eclipse\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\ApplicazioneCalcioItaliaServer\WEB-INF\File_del_Server\Calendario_A_1314.txt

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    17
    ho notato andando in questo percorso indicato che esistono delle copie dei file messi nella cartella WEB-INF/File_del_Server
    e nel caso del file Calendario_A_1314.txt il suo contenuto è esattamente quello che mi aspettavo (a parte una disposizione non corretta e alcuni simboli strani), come mai non vengono modificati quelli in WEB-INF/File_del_Server come ci si sarebbe aspettati?

    usare nella servlet qualcosa del tipo:
    FileWriter fw = new FileWriter(file,true);
    BufferedWriter bw = new BufferedWriter(fw);
    bw.write(s.getID());
    bw.newLine();

    potrebbe andare anche bene?

  8. #8
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    17
    usare nella servlet qualcosa del tipo:
    FileWriter fw = new FileWriter(file,true);
    BufferedWriter bw = new BufferedWriter(fw);
    bw.write(s.getID());
    bw.newLine();

    potrebbe andare anche bene?
    mi auto rispondo, si! ora fa proprio quello che doveva fare!
    l'unica cosa che ora non capisco è perché le modifiche si vedono nei file nella cartella: C:\ProgramFiles\eclipse2\workspace_Eclipse\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\ApplicazioneCalcioItaliaServer\WEB-INF\File_del_Server\Calendario_A_1314.txt
    e non in quella che mi sarei aspettatto:
    C:\ProgramFiles\eclipse2\workspace_Eclipse\ApplicazioneCalcioItaliaServer\WEB-INF\File_del_Server\Calendario_A_1314.txt

  9. #9
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Quote Originariamente inviata da aledpa Visualizza il messaggio
    mi auto rispondo, si! ora fa proprio quello che doveva fare!
    l'unica cosa che ora non capisco è perché le modifiche si vedono nei file nella cartella: C:\ProgramFiles\eclipse2\workspace_Eclipse\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\ApplicazioneCalcioItaliaServer\WEB-INF\File_del_Server\Calendario_A_1314.txt
    e non in quella che mi sarei aspettatto:
    C:\ProgramFiles\eclipse2\workspace_Eclipse\ApplicazioneCalcioItaliaServer\WEB-INF\File_del_Server\Calendario_A_1314.txt
    Perchè, appunto, Eclipse per mandare in esecuzione il tuo progetto ne crea una copia dentro alla sua cartella di lavoro (ovvero, ne fa il deploy nella cartella in cui gira il suo server Tomcat), che non è la cartella del tuo progetto (ovvero, quella con i sorgenti e quant'altro). Ed è corretto.

    Quando farai il build del progetto otterrai un WAR, che andrà deployato all'interno di un server Tomcat... e lì dentro girerà la tua web-app.

    Questo è il motivo per cui io non uso mai il "web server" integrato nell'ambiente di sviluppo: se voglio avere sempre tutta la situazione sotto controllo, è bene eseguire i programmi (che siano programmi stand-alone o webapps) al di fuori dell'ambiente di sviluppo.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  10. #10
    Utente di HTML.it
    Registrato dal
    Dec 2013
    Messaggi
    17
    quindi non c'è modo che le modifiche avvengano nei file "originali" nella cartella del progetto giusto?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.