Newsgroup: it.comp.java
Titolo: Chiamata programma Java da form JSP

Ciao a tutti,
ho una form JSP con 4 campi e ho bisogno, una volta effettuato il
submit dei dati, di chiamare un programma Java che prende in input un
array di 4 posti (i quali sono proprio i 4 valori immessi nei campi
della form): sapete come posso fare?
Grazie in anticipo! 
--
Vinci

 della form): sapete come posso fare?
Hmmmm ... Se usi le JSP vuol dire che usi un servlet-container (Quale 
?), e quindi dovresti avere gia' tutto a disposizione ...
-- 
Giambo - Occhio al filtro antispam _e_ alla whitelist !

Utilizzo Apache Tomcat 5.0 come servlet-container: ci sono soluzioni
migliori?
In ogni caso, ho provato ad inserire questa istruzione nella pagina JSP
chiamata come action della form:
<jsp:useBean id="start" scope="request" class="nome_programma" />, dove
nome_programma riceve in input un array di String, i cui valori sono
letti dalla form con questa istruzione:
		<%  String[] richiesta = new String[4];
			richiesta[0] = request.getParameter("nome_primo_campo_form");
			richiesta[1] = request.getParameter("nome_secondo_campo_form");
			richiesta[2] = request.getParameter("nome_terzo_campo_form");
			richiesta[3] = request.getParameter("nome_quarto_campo_form");
		%>

 		%>
Queste istruzioni dovresti implementarle nella servlet che richiami 
quando fai il submit della form. Assieme a tomcat usi struts ?


 quando fai il submit della form. Assieme a tomcat usi struts ?
Sì, queste righe che ho postato sono già nella pagina .jsp che chiamo
quando eseguo il submit della form: a me serve far partire un programma
Java, che prende in input un array di stringhe come quello che ho
creato nella parte di codice che ho postato, soltanto che non funziona:
dove sbaglio?


 dove sbaglio?
Prova a postare le parti salienti del codice ...


 Prova a postare le parti salienti del codice ...
Dunque:
nella pagina PHP c'è solo la form che chiama la JSP, con attributo
method pari a get (ho provato anche con "post" ma non cambia nulla).
La pagina jsp contiene, invece, questo codice:
			<%  String[] richiesta = new String[4];
				richiesta[0] = request.getParameter("Credential");
				richiesta[1] = request.getParameter("Target");
				richiesta[2] = request.getParameter("Path");
				richiesta[3] = request.getParameter("Mode");
			%>
dove Credential, Target, Path e Mode sono i nomi dei 4 campi della
form.
Inoltre, sempre nella JSP c'è un'istruzione per stampare i valori dei
4 posti dell'array..
			<%
				for(int i=0; i<richiesta.length; i++) {
					out.print(richiesta[i] + " ");
				}
			%>
Mi serve chiamare un programma Java che prende in input l'array
"richiesta" creato con l'istruzione sopra..

 "richiesta" creato con l'istruzione sopra..
Quindi devi implementare una servlet e fare in modo che venga chiamata 
al momento del submit.
Qualcosa del genere:
   public class MioServlet extends HttpServlet {
     public void doGet(HttpServletRequest req, HttpServletResponse res)
       throws ServletException, IOException
     {
       String[] richiesta = new String[4];
       richiesta[0] = req.getParameter("Credential");
       richiesta[1] = req.getParameter("Target");
       richiesta[2] = req.getParameter("Path");
       richiesta[3] = req.getParameter("Mode");
     }
   }
Non capisco cosa c'entri la JSP, potresti gia' passare questi valori 
dalla pagina PHP al tuo servlet.


    }
Sto provando, però quando importo il package javax.servlet.* e
javax.servlet.http.* ottengo un errore che mi dice che il package
javax.servlet non esiste... Serve per caso qualche libreria particolare
per usare le servlet?

 per usare le servlet?
Si, nel tuo caso le implementazioni di javax.servlet di tomcat.
Cerca il jar nella directory di tomcat e aggiungilo nel classpath.


Ok, ora compila correttamente..
Adesso devo chiamare il programma della servlet: ho provato a chiamarlo
dall'action della form, però non funziona..

Nel dotto la dir WEB-INF nel web.xml della tua applicazione inserisci
<servlet>
    <servlet-name>TuaServlet</servlet-name>
    <servlet-class>it.mia.classeservlet.TuaServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>TuaServlet</servlet-name>
    <url-pattern>/TuaServlet</url-pattern>
</servlet-mapping>
nell'action metti "TuaServlet"
prova cosi
ciao


Ho provato e la servlet viene effettivamente chiamata, però, sempre
dalla servlet, devo chiamare il programma (di nome startUp) che riceve
in input l'array di stringhe "richiesta" e, per farlo, ho metto questo
codice nella servlet:
startUp s = new startUp(richiesta); però ottengo questo errore da
Tomcat:
java.lang.NoClassDefFoundError: org/jdom/IllegalAddException
	servlet.doGet(servlet.java:91)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:743)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
Il file .java del programma (così come il suo .class) è inserito
nella medesima cartella del file .class della servlet, ovvero in
WEB-INF/classes


Ho provato e la servlet viene effettivamente chiamata, però, sempre


 	servlet.doGet(servlet.java:91)
La riga 91, dove viene generato l'errore, e' quella che instanzia la tua 
classe "startUp" ?
Ah, ricordati che le servlet sono multithread !


 classe "startUp" ?
Sì, esattamente!
Il fatto che siano multithread influenza molto la chiamata al metodo?

 Il fatto che siano multithread influenza molto la chiamata al metodo?
Se nella servlet usi delle member variable, queste verranno 
lette/scritte da piu' threads (Piu' richeste, piu' gente che "browsa") 
contemporanemente.


 contemporanemente.
Ah ok.. Non credo che sia il mio caso..

 Hai il jar di jdom in WEB-INF/lib ?
Dunque, ho inserito tutti i jar nella cartella WEB-INF/lib e ora non
viene più geneato l'errore, però le variabili del programma startUp
non sono valorizzate..

Vinci wrote:

In StartUp fai qualcosa come System.out.println("...") ?
Non funziona, devi scrivere nella HttpServletResponse:
   PrintWriter out = response.getWriter();
   out.println("<html><body>Hello, World !</body></html>");


    out.println("<html><body>Hello, World !</body></html>");
No, non c'è nessun System.. ho solo out.println o al massimo
out.print.. Non vorrei che quando startUp parte, siccome crea un
documento XML che serve come base agli altri algoritmi, mette questo
documento in una cartella particolare, diversa da quella dove risiede
la pagina php (webapps/ROOT)..
Forse è un po' OT, ma sapete se posso chiamare la servlet Java da
Apache 2 e non da Tomcat e, se sì, come si fa? Servono particolari
configurazioni per leggere la servlet?

 configurazioni per leggere la servlet?
No, non si puo', hai bisogno di una servlet-engine che esegua il codice 
java.


 java.
Ah ok.. E non esiste un altro modo (magari non utilizzando la servlet)
per far partire un programma Java che prende qualcosa in input, sempre
da PHP e Apache2?

 java.
Ho fatto partire un'Applet dalla pagina PHP, usando Apache2.0.54,
però, nella console Java dell'Applet ottengo questo errore:
java.lang.NoClassDefFoundError: org/jdom/IllegalAddException
	at java.lang.Class.getDeclaredConstructors0(Native Method)
	at java.lang.Class.privateGetDeclaredConstructors(Class.java:2328)
	at java.lang.Class.getConstructor0(Class.java:2640)
	at java.lang.Class.newInstance0(Class.java:321)
	at java.lang.Class.newInstance(Class.java:303)
	at sun.applet.AppletPanel.createApplet(AppletPanel.java:712)
	at sun.plugin.AppletViewer.createApplet(AppletViewer.java:1719)
	at sun.applet.AppletPanel.runLoader(AppletPanel.java:641)
	at sun.applet.AppletPanel.run(AppletPanel.java:320)
	at java.lang.Thread.run(Thread.java:595)
java.lang.NoClassDefFoundError: org/jdom/IllegalAddException
	at java.lang.Class.getDeclaredConstructors0(Native Method)
	at java.lang.Class.privateGetDeclaredConstructors(Class.java:2328)
	at java.lang.Class.getConstructor0(Class.java:2640)
	at java.lang.Class.newInstance0(Class.java:321)
	at java.lang.Class.newInstance(Class.java:303)
	at sun.applet.AppletPanel.createApplet(AppletPanel.java:712)
	at sun.plugin.AppletViewer.createApplet(AppletViewer.java:1719)
	at sun.applet.AppletPanel.runLoader(AppletPanel.java:641)
	at sun.applet.AppletPanel.run(AppletPanel.java:320)
	at java.lang.Thread.run(Thread.java:595)
Per caso Apache2 non legge la libreria Jdom.jar? Se sì, sapete dove va
messa?

 messa?
Apache gioca un ruolo marginale: Riceve una richiesta e la reindirizza o 
ad una pagina html statica, o ad uno script PHP o a Tomcat che eseguira' 
una servlet.
Se l'errore proviene da tomcat (Non mi pare), allora il jar non e' in 
WEB-INF. Se l'errore proviene dall'applet, allora il jar non viene 
trovato dall'applet che gira nel browser.


 trovato dall'applet che gira nel browser.
Dunque, Tomcat non lo sto usando più, di conseguenza mi verrebbe da
dire che il problem risiede nell'applet che non trova il jar di JDOM,
considerando che l'errore è un o (in tal caso come farglielo
trovare?)..
Ho provato a far partire una classe molto semplice (inizio.class) e
l'applet viene caricata correttamente.. Ecco qui la classe:
public class inizio extends javax.swing.JApplet{
	public static String richiesta0, richiesta1, richiesta2, richiesta3;
	public void init(){
		richiesta0=getParameter("Credential");
		richiesta1=getParameter("Target");
		richiesta2=getParameter("Path");
		richiesta3=getParameter("Mode");
		setBackground(Color.yellow);
	}
	public static void main(String[]args) {
		String[]richiesta = new String[4];
		richiesta[0]=richiesta0;
		richiesta[1]=richiesta1;
		richiesta[2]=richiesta2;
		richiesta[3]=richiesta3;
		inizio i = new inizio();
		startUp s = new startUp(richiesta);
		arEvaluation a = new arEvaluation(richiesta);
	}
}
In questo caso l'applet si avvia però le classi startUp e arEvaluation
non partono..

 non partono..
Ho provato ad inserire l'attributo "archive" nel codice dell'Applet per
farle riconoscere il jar di JDOM, e il programma startUp sembra
partire: premessa, startUp contiene un blocco di istruzioni del tipo:
			source = new FileInputStream(richiesta[1]);
			xmldoc = db.parse(source);
			xmldoc.getDocumentElement().normalize();
			root = xmldoc.getDocumentElement();
ovvero si prende il nome del file passato in input nel secondo campo
della form, lo si parsa e se ne estrae la radice: successivamente si
fanno le medesime istruzioni anche per un altro documento XML (tutti i
documenti XML sono presenti nella stessa cartella della pagina
contenente il codice dell'Applet e il .class che questa avvia).
Eseguendo l'Applet sul web (non in localhost perchè ho problemi di
permessi di scrittura sulla cartella) ottengo però il seguente errore:
java.security.AccessControlException: access denied
(java.io.FilePermission organization.xml read)
	at
java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
	at
java.security.AccessController.checkPermission(AccessController.java:427)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
	at java.lang.SecurityManager.checkRead(SecurityManager.java:871)
	at java.io.FileInputStream.<init>(FileInputStream.java:100)
	at java.io.FileInputStream.<init>(FileInputStream.java:66)
	at startUp.<init>(startUp.java:149)
	at inizio.init(inizio.java:25)
	at sun.applet.AppletPanel.run(AppletPanel.java:374)
	at java.lang.Thread.run(Thread.java:595)
dove organization.xml è il file che startUp deve leggere e parsare,
inizio è la classe che contiene l'Applet e la riga 149 di startUp è
quella che ho postato qualche riga sopra, ovvero
			source = new FileInputStream(richiesta[1]);

 (java.io.FilePermission organization.xml read)
Gli applet hanno un accesso ridotto alle risorse della macchina sulla 
quale girano. Se cosi' non fosse, la rete sarebbe farcita di applet che 
vanno a leggerti la dichiarazione dei redditi :-)
Purtroppo le mie conoscienze in campo Applet sono decisamente ridotte, 
ragione per la quale passo :)


 ragione per la quale passo :)
Capisco! :)
Vedendo che con l'Applet non sembra risolversi molto, sono tornato alla
servlet, ma ho un dubbio: è necessario dichiarare anche il metodo main
(nella servlet o nelle classi)? (se sì è occorre inserire come
parametri String[] args o String[] argv ?)
Al momento la servlet è questa:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class servlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse res)
	throws ServletException, IOException{
		String[] richiesta = new String[4];
		richiesta[0] = req.getParameter("Credential");
		richiesta[1] = req.getParameter("Target");
		richiesta[2] = req.getParameter("Path");
		richiesta[3] = req.getParameter("Mode");


 parametri String[] args o String[] argv ?)
No. La vita di una servlet e' piu' o meno la seguente:
1) La prima volta che viene richiamata, la servlet-engine instanzia la 
classe e chiama il metodo init()
2) Tutti i successivi requests verranno "serviti" dai metodo doGet() e 
doPost() di questa istanza della servlet[1]. Quindi: Una sola istanza 
della classe per tutte le richieste (Multithreading) !
3) Una servlet puo' venir distrutta dalla servlet engine in casi 
"speciali". Viene quindi richiamato il metodo destroy().
Un corso accelerato lo trovi qui: 
http://www.nakov.com/inetjava/lectures/part-3-webapps/InetJava-3.4-Servlet-lyfecycle-Sessions-Cookies.html
[1] Non e' esatto al 100%, ma quasi :)


 "speciali". Viene quindi richiamato il metodo destroy().
Ho appena dato un'occhiata al link che mi hai segnalato e ho modificato
la servlet, aggiungendo il metodo init(), ma non funziona ancora..
Ecco il codice della servlet..
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class servlet extends HttpServlet {
	String[] richiesta;
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		richiesta = new String[4];
	}
	public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException{
		//metti codice per generare pagina HTML
		richiesta[0] = req.getParameter("Credential");
		richiesta[1] = req.getParameter("Target");
		richiesta[2] = req.getParameter("Path");
		richiesta[3] = req.getParameter("Mode");
		new startUp(richiesta);
		new arEvaluation(richiesta);
	}
}
Nel metodo doGet ho provato anche a chiamare le classi startUp e
arEvaluation creando un oggetto nella maniera classica
startUp s = new startUp(richiesta);
arEvaluation a = new arEvaluation(richiesta);
ma il risultato è lo stesso.. startUp e arEvaluation, che, quando
vengono chiamate, devono creare un file XML, non creano nulla..
Sapete dirmi se la servlet è corretta e, in tal caso, se è magari un
problema di permessi relativo ad Apache Tomcat?

 problema di permessi relativo ad Apache Tomcat?
Puo' darsi. Sistema UNIX ? Controlla dove viene creato il file e 
eventualmente i permessi.


 eventualmente i permessi.
Sì, lo uso prevalantemente da UNIX, ma anhe da Windows non funziona..
In ogni caso, parlo di UNIX, la cartella dove risiede la pagina JSP è
webapps/ROOT, mentre quella dove risiede il .class della servlet è
webapps/ROOT/WEB-INF/classes e in entrambe le cartelle ci sono tutti i
permessi..

 the classpath.
A quanto pare la classe "startup" (In java le classi cominciano con la 
maiuscola !) non e' nel package/directory giusta.


 maiuscola !) non e' nel package/directory giusta.
Ma startUp è nella stessa cartella della pagina..così come il suo
.class E la classe startUp l'ho definita io e facendola partire da riga
di comando va tutto a buon fine..

 di comando va tutto a buon fine..
Il messaggio d'errore parla chiaro:
"cannot access org.apache.jsp.startUp"
Non riesce ad accedere alla tua classe "startUp"
"
bad class file:
/srv/www/tomcat5/base/webapps/ROOT/WEB-INF/classes/org/apache/jsp/startUp.class
class file contains wrong class: startUp
"
A quanto pare il class non e' giusto. Non capisco inoltre perche' 
appartiene al package org.apache.jsp
"
Please remove or make sure it appears in the correct subdirectory of
the classpath.
"
A che package appartiene la tua classe startUp ?



Tu non hai la + pallida idea di cosa sia una servlet, ammettilo.

 A che package appartiene la tua classe startUp ?
La classe startUp non appartiene ad alcun package..

Vinci wrote:

Forse questo e' il problema !
