PDA

Visualizza versione completa : [JSP] Usare form da una JSP inclusa... si può fare?


Alhazred
28-07-2008, 12.30.09
Ho una pagina JSP con un form che funziona correttamente.
Vorrei che un'altra pagina JSP, contenente a sua volta un altro form funzionante, utilizzasse tale form includendo la JSP dove è definito.
Riesco ad includere la JSP con il form (piuttosto banale), ma il form non fa il suo dovere.
Ho idea che il problema sia nel fatto che non sia possibile gestire un form da una pagina diversa da quella in cui è definito a meno di qualche tecnica particolare che non conosco.
Vi propongo il codice che ho scritto, sapete darmi qualche dritta per risolvere il problema?

Pagina con il suo form all'inizio e il form incluso sotto.

<%@ page language="java" contentType="text/html; charset=iso-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ page import="controller.MagController" %>
<%!
static final String[][] TABS = {
{"A","showingrediente.jsp"},
{"B","showingrediente.jsp"},
{"C","showingrediente.jsp"}
<!-- gù fino alla Z -->
}; %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Modifica soglia</title>
<% int soglia_scadenza = MagController.getSoglia(); %>

<SCRIPT LANGUAGE="JavaScript">
<!--
function checkSogliaScadenza(obj) {
//permette solo numeri
scadenza = obj.value.replace(/\D/g,"");
obj.value = scadenza;
}
function checkFormScadenza(obj) {
if(document.modsoglia.scadenza.value <= 0) {
alert("La soglia di scadenza deve essere un intero maggiore di 1");
document.modsoglia.scadenza.value = "";
document.modsoglia.scadenza.focus();
return false;
}

return true;
}
//-->
</script>
</head>
<body>
<center>
<h2>Modifica valori di soglia</h2>
<br><br>
Modifica soglia di scadenza
<form name="modsoglia" action="ModificaScadenza" method="post">
<table width="300" border="0" cellpadding="6">
<tr>
<td width="65%">Soglia per date di scadenza</td>
<td width="35%"> <%= soglia_scadenza %> giorni</td>
</tr>
<tr>
<td>Nuovo valore di soglia</td>
<td><input type="text" name="scadenza" size="3" onChange="checkSogliaScadenza(this)" /> giorni</td>
</tr>
<tr>
<td><%if (session.getAttribute("esito_scadenza") != null)
if (session.getAttribute("esito_scadenza").equals("non_modificata")) {%>
<font color="red">Soglia non modificata!</font> <% } %></td>
<td><input type="submit" name="modsoglia" value="Modifica" onClick="return checkFormScadenza(this)"/></td>
</tr>
</table>
</form>
<br><br><br>
Modifica soglia rimanenze<br>
<form>
<%String which = request.getParameter("which");
if (which==null)
which = TABS[0][0];
String jspToRun = null;
for (int i=0; i<TABS.length; i++) {
String tabLabel = TABS[i][0];
String tabJSP = TABS[i][1];
String CHECKED = "";
if (which.equals(tabLabel)) {
CHECKED = "CHECKED";
jspToRun = tabJSP;
}
%>
<input name="which" type="radio" value="<%=tabLabel %>" <%= CHECKED %> onClick="this.form.submit()" /><%= tabLabel %>
&nbsp;
<%
if (i==12) {%>
<br>
<% }
} %>
<p>
<jsp:include page="<%= jspToRun %>" flush="true" />
</p>
</form>
<br><br><br><br>
<a href="hpmagazziniere.html">Home page</a>
</center>
</body>
</html>

Pagina col form da includere nella precedente:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ page import="controller.IngrController" %>
<%@ page import="java.sql.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Mostra ingredienti per lettera</title>
<SCRIPT LANGUAGE="JavaScript">
<!--
function selezionato(obj) {
//permette solo numeri
nuovaSoglia = obj.value.replace(/\D/g,"");
obj.value = nuovaSoglia;

if(obj.value > 0)
document.modrimanenza.totale_selezionati.value = parseInt(document.modrimanenza.totale_selezionati. value) + 1;
if(obj.value <= 0)
document.modrimanenza.totale_selezionati.value = parseInt(document.modrimanenza.totale_selezionati. value) - 1;
}

//-->
</script>
<%
int i=0;
String lettera = request.getParameter("which");
ResultSet rs = IngrController.getIngrMagPerLettera(lettera);
%>
</head>
<body>
<center>
<form name="modrimanenza" action="ModificaRimanenza" method="post">
<table width="550" cellpadding="2">
<tr>
<td width="25%"><b>Ingrediente</b></td>
<td width="20%"><b>Unit&agrave; di misura </b></td>
<td width="25%"><div align=center><b>Soglia attuale </b></div></td>
<td width="30%"><b>Nuovo valore di soglia </b></td>
</tr>
<% while (rs.next()) { %>
<tr>
<td><%=rs.getString("Nome") %></td>
<td><div align="center"><%=rs.getString("unitaDiMisura") %></div></td>
<td><div align="center"><%=rs.getString("Soglia") %></div></td>
<td><input type="text" name="ingrediente<%= i %>value" size="3" onChange="selezionato(this)"/>
<input type="hidden" name="ingrediente<%= i %>name" value="<%=rs.getString("Nome") %>" /></td>
</tr>
<% i++;
} %>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td><input type="hidden" name="totale_selezionati" value="0"/>&nbsp;</td>
<td><input type="submit" name="modifica" value="Modifica" /></td>
</tr>
</table>
</form>
</center>
</body>
</html>

shadowDK
28-07-2008, 13.21.00
Hai provato, nella pagina col form da includere nella precedente, a togliere html e body? Far diventare la tua pagina così:

<SCRIPT LANGUAGE="JavaScript">
<!--
function selezionato(obj) {
//permette solo numeri
nuovaSoglia = obj.value.replace(/\D/g,"");
obj.value = nuovaSoglia;

if(obj.value > 0)
document.modrimanenza.totale_selezionati.value = parseInt(document.modrimanenza.totale_selezionati. value) + 1;
if(obj.value <= 0)
document.modrimanenza.totale_selezionati.value = parseInt(document.modrimanenza.totale_selezionati. value) - 1;
}


//-->
</script>
<%
int i=0;
String lettera = request.getParameter("which");
ResultSet rs = IngrController.getIngrMagPerLettera(lettera);
%>

<center>
<form name="modrimanenza" action="ModificaRimanenza" method="post">
<table width="550" cellpadding="2">
<tr>
<td width="25%"><b>Ingrediente</b></td>
<td width="20%"><b>Unit&agrave; di misura </b></td>
<td width="25%"><div align=center><b>Soglia attuale </b></div></td>
<td width="30%"><b>Nuovo valore di soglia </b></td>
</tr>
<% while (rs.next()) { %>
<tr>
<td><%=rs.getString("Nome") %></td>
<td><div align="center"><%=rs.getString("unitaDiMisura") %></div></td>
<td><div align="center"><%=rs.getString("Soglia") %></div></td>
<td><input type="text" name="ingrediente<%= i %>value" size="3" onChange="selezionato(this)"/>
<input type="hidden" name="ingrediente<%= i %>name" value="<%=rs.getString("Nome") %>" /></td>
</tr>
<% i++;
} %>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td><input type="hidden" name="totale_selezionati" value="0"/>&nbsp;</td>
<td><input type="submit" name="modifica" value="Modifica" /></td>
</tr>
</table>
</form>
</center>


Cmq, un'altra cosa che non mi convince è il fatto che tu ti trovi due form uno dentro l'altro:

<form>
<%String which = request.getParameter("which");
if (which==null)
which = TABS[0][0];
String jspToRun = null;
for (int i=0; i<TABS.length; i++) {
String tabLabel = TABS[i][0];
String tabJSP = TABS[i][1];
String CHECKED = "";
if (which.equals(tabLabel)) {
CHECKED = "CHECKED";
jspToRun = tabJSP;
}
}%>
<input name="which" type="radio" value="<%=tabLabel %>" <%= CHECKED %> onClick="this.form.submit()" /><%= tabLabel %>
&nbsp;
<%
if (i==12) {%>
<br> <%
}
} %>
<p>
<!--**********jspToRun contiene già un form al suo interno********-->
<jsp:include page="<%= jspToRun %>" flush="true" />
</p>
</form>

e sinceramente non so cosa questo comporti (non saprei come determina dove inviare i dati). Credo il problema principale sia questo...

Questa riga, nella pagina "esterna":
<input name="which" type="radio" value="<%=tabLabel %>" <%= CHECKED %> onClick="this.form.submit()" /><%= tabLabel %>
inoltre, io la scriverei così:
<input name="which" type="radio" value="<%=tabLabel %>" checked="<%= CHECKED %>" onClick="this.form.submit()" /><%= tabLabel %>

shadowDK
28-07-2008, 13.29.39
Googleggiando un po', leggo che i form annidati non si possono gestire, oppure lo si può fare colo con soluzioni non standard che è meglio evitare quindi...sono sempre più convinto che il problema della tua jsp sia quello!

Alhazred
28-07-2008, 14.16.19
Bene le cose sono migliorate.
Seguendo il tuo consiglio ho modificato la jsp esterna ed è diventata così

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ page import="controller.IngrController" %>
<%@ page import="java.sql.*" %>

<SCRIPT LANGUAGE="JavaScript">
<!--
function selezionato(obj) {
//permette solo numeri
nuovaSoglia = obj.value.replace(/\D/g,"");
obj.value = nuovaSoglia;

if(obj.value > 0)
document.modrimanenza.totale_selezionati.value = parseInt(document.modrimanenza.totale_selezionati. value) + 1;
if(obj.value <= 0)
document.modrimanenza.totale_selezionati.value = parseInt(document.modrimanenza.totale_selezionati. value) - 1;
}

//-->
</script>
<%
int i=0;
String lettera = request.getParameter("which");
ResultSet rs = IngrController.getIngrMagPerLettera(lettera);
%>

<center>
<form name="modrimanenza" action="ModificaRimanenza" method="post">
<table width="550" cellpadding="2">
<tr>
<td width="25%"><b>Ingrediente</b></td>
<td width="20%"><b>Unit&agrave; di misura </b></td>
<td width="25%"><div align=center><b>Soglia attuale </b></div></td>
<td width="30%"><b>Nuovo valore di soglia </b></td>
</tr>
<% while (rs.next()) { %>
<tr>
<td><%=rs.getString("Nome") %></td>
<td><div align="center"><%=rs.getString("unitaDiMisura") %></div></td>
<td><div align="center"><%=rs.getString("Soglia") %></div></td>
<td><input type="text" name="ingrediente<%= i %>value" size="3" onChange="selezionato(this)"/>
<input type="hidden" name="ingrediente<%= i %>name" value="<%=rs.getString("Nome") %>" /></td>
</tr>
<% i++;
} %>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td><input type="hidden" name="totale_selezionati" value="0"/>&nbsp;</td>
<td><input type="submit" name="modifica" value="Modifica" /></td>
</tr>
</table>
</form>
</center>

Inoltre ho spostato la chiusura del form coi radio button sopra la chiamata alla pagina esterna in modo da non avere i 2 form annidati.
Il miglioramento è che ora il form incluso fa il suo lavoro, quando inserisco un valore e clicco sul pulsante submit parte la servlet e il db viene aggiornato, torna alla jsp con tutti i form, ma se clicco di nuovo su un radio button per far apparire la lista di altri ingredienti ottengo un errore da Tomcat, il quale dice che il metodo Get non è supportato... credo si riferisca al form coi radio button, ma se così fosse il problema dovrebbe darmelo sempre, o no?

EDIT: Questo è il messaggio d'errore completo
HTTP Status 405 - HTTP method GET is not supported by this URL

type Status report

message HTTP method GET is not supported by this URL

description The specified HTTP method is not allowed for the requested resource (HTTP method GET is not supported by this URL).

Alhazred
28-07-2008, 14.27.21
Altra cosa strana, senza modificare nulla, di tanto in tanto quando faccio il submit nel form importato ottengo questo errore:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.NumberFormatException: For input string: ""
java.lang.NumberFormatException.forInputString(Unk nown Source)
java.lang.Integer.parseInt(Unknown Source)
java.lang.Integer.parseInt(Unknown Source)
frontend.ModificaRimanenza.doPost(ModificaRimanenz a.java:37)
javax.servlet.http.HttpServlet.service(HttpServlet .java:710)
javax.servlet.http.HttpServlet.service(HttpServlet .java:803)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.16 logs.

frontend.ModificaRimanenza.doPost(ModificaRimanenz a.java:37) contiene questa istruzione:
if(Integer.parseInt(request.getParameter("ingrediente"+aux+"value")) > 0)
sembra che la conversione di request.getParameter("ingrediente"+aux+"value") (che contiene un numero) in intero a volte fallisca.

shadowDK
28-07-2008, 15.27.41
Altra cosa strana, senza modificare nulla, di tanto in tanto quando faccio il submit nel form importato ottengo questo errore:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.NumberFormatException: For input string: ""
java.lang.NumberFormatException.forInputString(Unk nown Source)
java.lang.Integer.parseInt(Unknown Source)
java.lang.Integer.parseInt(Unknown Source)
frontend.ModificaRimanenza.doPost(ModificaRimanenz a.java:37)
javax.servlet.http.HttpServlet.service(HttpServlet .java:710)
javax.servlet.http.HttpServlet.service(HttpServlet .java:803)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.16 logs.

frontend.ModificaRimanenza.doPost(ModificaRimanenz a.java:37) contiene questa istruzione:
if(Integer.parseInt(request.getParameter("ingrediente"+aux+"value")) > 0)
sembra che la conversione di request.getParameter("ingrediente"+aux+"value") (che contiene un numero) in intero a volte fallisca.
su questo non saprei aiutarti, bisogna fare un po' di debug dalla servlet...sembra che a volte il parametro "ingrediente"+aux+"value" arrivi come stringa vuota...bisogna capire quando e perchè si verifica questo problema...

per il tuo problema con il tomcat, invece, ho una cosa da chiederti: ma il parametro action del tag form non è obbligatorio? non è che omettendolo magari ti crea dei problemi?

Alhazred
28-07-2008, 20.22.54
Allora, ecco le novità.
Faccio il primo inserimento nel form importato e tutto va a buon fine, l'errore appare sistematicamente quando seleziono di nuovo una lettera per far apparire la tabella, mi da subito errore la servlet associata al form che deve apparire, come se si premesse sul pulsante submit e non si selezionasse nessun valore per i campi ingrediente<%= i %>value.
Adesso li ho inizializzati tutti a 0, ma niente da fare, non funziona ancora.
Ho messo nella form senza action un action="" ed anche un method="post"... niente.
Il fatto strano è che cliccando su un radio button l'errore lo dia la servlet associata al form sottostante, quello imporato, e io non clicco sul submit di quel form.

Questo è il doPost del servlet associato al form importato:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int daModificare = Integer.parseInt(request.getParameter("totale_selezionati")); //numero di ingredienti con quntità scelta > 0
int j = 0; //conta gli ingredienti con quantità > 0 trovati
int aux = 0; //cicla su tutti gli ingredienti nel form
String[][] ingrediente = new String[daModificare][2];

while (j < daModificare) { //finché il numero di ingredienti con quantità > 0 trovati non raggiunge il valore conosciuto
if(Integer.parseInt(request.getParameter("ingrediente"+aux+"value")) > 0) {
ingrediente[j][0] = request.getParameter("ingrediente"+aux+"name");
ingrediente[j][1] = request.getParameter("ingrediente"+aux+"value");
j++;
aux++;
}
else
aux++;
}

IngrController.modificaSogliaRimanenza(ingrediente ,daModificare);

RequestDispatcher dispatcher = request.getRequestDispatcher("/modificasoglia.jsp");
dispatcher.forward(request, response);
}

shadowDK
29-07-2008, 10.49.16
Prova a mettere al form del radio button action="#"...

Per questo invece
Faccio il primo inserimento nel form importato e tutto va a buon fine, l'errore appare sistematicamente quando seleziono di nuovo una lettera per far apparire la tabella, mi da subito errore la servlet associata al form che deve apparire, come se si premesse sul pulsante submit e non si selezionasse nessun valore per i campi ingrediente<%= i %>value.
ho letto il tuo codice della jsp e sinceramente non mi ricordo come funziona la dichiarazione di una variabile con <%! ecc ecc...mi ricordo che mi dicevano di non utilizzarla, di fare attenzione ma non ricordo perchè...se non sei più che sicuro potrebbe essere quello...

senti, ma posso chiederti una cosa? perchè non provi ad utilizzare jstl e struts? semplificano molto la vita (struts 2, struts 1 era un casino) e non sono così difficili da usare...la navigazione con struts 2 viene tutta gestita a livello di xml di configurazione ed è molto più semplice in nquesto modo secondo me!
ti consiglierei anche hibernate come tool di persistenza per il db, ma credo che tu abbia già fatto tutto con normali accessi jdbc quindi non è il caso di mettersi a cambiare tutto (oltre tutto io trovo hibernate abbastanza ostico da configurare, anche se una volta fatto viene tutto più facile)...

Alhazred
29-07-2008, 11.31.48
Per adesso ho provato ad apportare la modificha action="#", ma non ha risolto la situazione.
<%! l'ho usato perché la variabile TABS è dichiarata come final e non può essere messa tra i tag <% %>, ho comunque provato a non dichiararla final e metterla tra questi ultimi tag, il risultato non è cambiato.

Ora proverò a dare un'occhiata a jstl e struts come mi hai consigliato.

Grazie :)