Newsgroup: it.comp.java
Titolo: Passaggio dati JSP -> Servlet e viceversa

Allora, stando a quanto dice la Sun una pagina jsp deve contenere meno
codice java possibile ed interfacciarsi per l'eleborazione dei dati di una
form ad esempio ad una servlet.
Ok, ciò si può fare mettendo come action della form una servlet. Ma i dati
che la servlet restituisce, come possono essere ripassati ad una pagina jsp,
ovvero quali istruzioni la servlet deve mandare sull'output della response
per indicare al client di andare ad una determinata pagina?


ad esempio puoi utilizzare dei JavaBean
-- 
Ciao,     |   And the devil in black dress watches over
 Matteo   |   My guardian angel walks away
          |   Life is short and love is always over in the morning
          |   Black wind come carry me far away

> ad esempio puoi utilizzare dei JavaBean
So come usare javabean all'interno di e tra pagine jsp, ma da servlet a jsp
come avviene il passaggio di bean?


Piu` o meno allo stesso modo: la servlet puo` metterlo in sessione e la
jsp prelevarlo utilizzando il tag <jsp:useBean >. Non so` se esistono
altri modi, ma questo funziona e mi sembra abbastanza semplice.
Prendi il caso di una servlet che puo` riscontrare situazioni di errore
(ad esempio nell'input dell'utente). In questo caso potresti fare una
redirect su una pagina statica di errore, generarne una al volo (o
magari generare solo un'intestazione javascript contenente la parte
"dinamica" della pagina e aggiungervi la parte statica prelevandola da
un file gia` pronto). In alternativa puoi fare una redirect su una jsp e
passargli un bean contenente una stringa che descriva l'errore (o
qualcosa del genere).
La servlet istanzia e inizializza il bean, lo pone in sessione,
dopodiche` passa il controllo alla jsp. Questa controlla se esiste un
bean con un determinato id, e nel caso preleva da questo la stringa di
errore da mostrare. Magari puoi passare alla servlet come parametro di
avvio l'identificativo da utilizzare per il bean, di modo da poter
cambiare idea senza ricompilare.
Provo a scriverti al volo un esempietto:
// questa e` il tipo di javabean utilizzato da jsp e servlet
public class MsgBean {
    private String message = "";
    public MsgBean() {
       super();
    }
    public String getMessage() {
       return message;
    }
    public void setMessage( String message ) {
       this.message = ( message != null )? message : "all ok!";
    }
}
// questa e` la servlet
/* ...inserisci tutti gli import del caso... */
public class DoSomethingServlet extends HttpServlet {
 
   /** url to redirect to if all works ok */  
   private String redirectURL = "";
   /** url to redirect to if something goes wrong */
   private String redirectErrorURL = "";
   /** bean's id */
   private String beanInstanceName = "";
   /**
    * Initializes the servlet.
    */
   public void init() {
      redirectURL = this.getInitParameter( "redirectURL" );
      redirectErrorURL = this.getInitParameter( "redirectErrorURL" );
      beanInstanceName = this.getInitParameter( "beanInstanceName" );
   }
   /**
    * Process incoming HTTP GET requests: just call performTask()
    */
   public void doGet( HttpServletRequest req, HttpServletResponse res )
     throws ServletException, IOException
   {
        performTask( req, res );
   }
   /**
    * Process incoming HTTP POST requests: just call performTask().
    */
   public void doPost( HttpServletRequest req, HttpServletResponse res )
     throws ServletException, IOException
   {
        performTask( req, res );
   }
   /**
    * Performs the requested task, creates a MsgBean with the output
    * to be show to user, put this JavaBean in session and redirect
    * to the JSP that will show this informations. If error occours,
    * a MsgBean is inserted in session to pass the error message to
    * the JSP that will show it.
    */
   public void performTask( HttpServletRequest req,
                            HttpServletResponse res )
   {
     // user's current session	
     HttpSession session = req.getSession();
     try {
       boolean error = false;
       String output = null;
 
       /*
        * ...do something:
        * set error=true if error occurs
        * set the "output" string if needed...
        */
       // put the resulted information in a JavaBean and insert it
       // in session to be used by JSP
       MsgBean msgBean = new MsgBean();
       listBean.setMessage( (error)?"Error executing task!" : output );
       session.putValue( beanInstanceName, msgBean );
       /*
        * OSS: in caso di successo si puo` pure scegliere di
        *      non inserire alcun bean in sessione: in questo
        *      caso la JSP si trovera` ad istanziarne una nuovo
        *      quando provera` ad accedervi, e il messaggio che
        *      ci trovera` sara il default di MsgBean: "all ok!".
        */
       // redirect to JSP
       if( error )
         res.sendRedirect( redirectErrorURL );
       else
         res.sendRedirect( redirectURL );
     } catch( Exception e ) {
	// insert error's description into javabean, insert
        // the javabean in session so it can be showed by jsp
	MsgBean errBean = new MsgBean();		
	errBean.setMessage( /*e.getMessage()*/ e.toString() );
	session.putValue( beanInstanceName, errBean );
	// redirect to JSP
	try { res.sendRedirect( redirectErrorURL ); }catch(IOException e2){}
     }
   }
}
a questo punto, posto che l'id del bean sia "beanID", sia nella jsp di
errore, che in quella cui la servlet punta in caso di successo, puoi
inserire due righe del tipo:
   <jsp:useBean id="beanID" scope="session" class="MsgBean" />
   <H3><jsp:getProperty name="beanID" property="message"/></H3>
per visualizzare il contenuto del javabean nella pagina.
o se ti piacciono le finestre di alert:
   <SCRIPT language="JavaScript">
     message = "<jsp:getProperty name="beanID" property="message"/>";
     if (message.length>0) alert(message);
   </SCRIPT>
Per completezza ti conviene poi rimuovere il bean dalla sessione,
oppure "ripulirlo" con un
   <jsp:setProperty name="beanID" property="message" value=""/>
subito prima della chiusura del BODY.
Di nuovo: non so` se esistono altri modi, io di solito uso questo...
Saluti ...e scusa la risposta probabilmente troppo lunga!
(...e il pessimo inglese nei commenti!! ;-)


 
ehm... no: il default era la stringa vuota "", ma vabbe`, non cambia poi
molto... ;-)


Grazie mille per l'esauriente risposta!
A dire il vero però, il passaggio tramite bean non mi piace molto (anche se
magari è l'unico!) cercavo un metodo che permettesse di passare i parametri
da servlet a jsp tramite get o post (in modo tale che nella pagina jsp posso
gestire tutto solo tramite l'oggetto request, indipendentemente se la pagina
sia stata "chiamata" tramite un forward, una action di un'altra pagina o una
servlet).
Tramite Get si potrebbe fare mettendo nella servlet un'istruzione del tipo
res.sendRedirect(pagina.jsp?par1=...&par2=...), ma se volessi usare il Post?

    <H3><jsp:getProperty name="beanID" property="message"/></H3>
cioč senza bisogno di riprendere il bean dalla sessione con un'istruzione
esplicita tipo beanID = (MsgBean)session.getValue(beanInstanceName) ?


sendRedirect, a quanto ne so` e` per l'apertura di nuove pagine, quindi
esegue solo delle GET. per i POST... ammetto di non averlo mai fatto
anche se sono sicuro ci sia qualcosa a riguardo nella documentazione
(che ovviamente al momento non ho sottomano! :-P)
...cmq puoi cercare con deja o simili un thread passato dal nome
"chiamare una servlet da un'altra servlet" (...o qualcosa del genere!
;-) che se non ricordo male ti puo` essere utile.
-- 
Ciao,    |  I can see tomorrow   I can see the world to come
 Matteo  |  I can see tomorrow   Hear the pandemonium 
         |                     -- Killing Joke (Pandemonium)


l'istruzione esplicita "e` implicita nel tag <jsp:useBean >" ! :-)


 (che ovviamente al momento non ho sottomano! :-P)
che dire, ho cercato ma non ho trovato nulla di interessante a riguardo...
l'unica idea malsana che mi č venuta in mente č quella di far generare alla
servlet una pagina html con una form contenente action=pagina.jsp, poi campi
hidden contenenti i dati da passare, e mettere nel body l'evento
onload=document.forms[0].submit()... ma rabbrividsco all'idea di una
soluzione del genere!