PDA

View Full Version : Tomcat non trova la jsp


boysna
17-04-2006, 00:07
Ciao a tutti ragazzi. Ho un problema con una jsp che viene caricata grazie ha una forward di una servlet. Questa è la servlet:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;


public class RicercaProdotto extends HttpServlet {

public void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

GestioneDB cerca = new GestioneDB();
prodotto p = cerca.cercaProdotto(request.getParameter("marca"), request.getParameter("modello"));
gotoPage("/visualizza_prodotto.jsp?p",request,response);

}

private void gotoPage( String address,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher(address);
dispatcher.forward(request,response);
}
}


Come si vede deve richiamare una jsp visualizza_prodotto che è questa:

<HTML><HEAD><TITLE>BENVENUTO</TITLE></HEAD>


<BODY BGCOLOR="white">

<% prodotto p = request.getParameter("p");
out.println(p.getCategoria());
%>



</BODY>
</HTML>


Questa jsp l'ho messa sia sotto E:\Programmi\Apache Software Foundation\Tomcat 5.5\webapps\esercizio che sotto E:\Programmi\Apache Software Foundation\Tomcat 5.5\webapps\esercizio\work\org\apache\jsp che
E:\Programmi\Apache Software Foundation\Tomcat 5.5\webapps\esercizio\WEB-INF\classes
ma continua a darmi errore "HTTP Status 404 - /visualizza_prodotto.jsp"
"description The requested resource (/visualizza_prodotto.jsp) is not available."

Ho notato che sotto E:\Programmi\Apache Software Foundation\Tomcat 5.5\webapps\esercizio\work\org\apache\jsp sono stati creati dei file nome_jsp e nome_jsp.class per ogni jsp chiamata nome. Non so come le ho create. Comunque sono hsp raggiungibili da se,plici link e non dopo l'elaborazione di una servlet


Mi sa che dovrei creare sotto la cartella org/apache/jsp questi file anche per la jsp visualizza_prodotto, ma come faccio?

PGI-Bis
17-04-2006, 15:31
La cosa potrebbe anche funzionare, con le opportune impostazioni nel descrittore di dispiegamento dell'applicazione web. Ritengo tuttavia che, nel caso in cui lo standard J2EE sia affrontato per la prima volta, si deva seguire un approccio un po' più sistematico al fine di apprendere come funzioni la faccenda.

Nota che tutto quanto sto per dire è giustamente occultato dagli IDE predisposti allo sviluppo di applicazioni web J2EE, trattandosi di operazioni sempre identiche.

La struttura dei file che costituiscono un'applicazione web è questa:

1. una directory di base il cui nome, in assenza di indicazioni specifiche per il server, è considerato il nome della radice del contesto dell'applicazione.

miaapplicazione/

2. la radice contiene le pagine, statiche o dinamiche, pubblicamente accessibili.

miaapplicazione/ documenti o cartelle di documenti pubblicamente accessibili

3. la radice contiene la cartella WEB-INF. Il contenuto della cartella WEB-INF non è pubblicamente accessibile. La cartella WEB-INF contiene il necessario all'applicazione web.

3.1 la cartella WEB-INF puo contenere, ad esempio, pagine jsp, pagine html o cartelle di documenti che tu non voglia rendere pubbliche ma, ovviamente, che ti servano per l'applicazione.

3.2 la cartella WEB-INF contiene il descrittore di dispiegamento dell'applicazione web (web.xml)

miaapplicazione/WEB-INF/web.xml

3.3 la cartella WEB-INF contiene la cartella "classes". La cartella classes contiene le classi Java che definiscono i componenti servlet.

3.4 la cartella WEB-INF contiene la cartella "lib". La cartella lib contiene gli archivi jar delle librerie necessarie ai componenti dell'applicazione web. Ad esempio può contenere i JavaBean usati da servlet e pagine jsp.

Direi che questo è il minimo necessario e sufficiente, sulla struttura, per costruire un'applicazione web J2EE. C'è molto altro, naturalmente.

Faccio un esempio di costruzione di un'applicazione web J2EE che usi JavaBean, servlet, pagine jsp e html, passo per passo.

1. creiamo un cartella per infilare il necessario all'applicazione:

c:\servletsample

2. creiamo una cartella WEB-INF in /servletsample

c:\servletsample\WEB-INF

3. creiamo una cartella /classes e una /lib in WEB-INF

4. creiamo un JavaBean "Prodotto":

package mybeans;

public class Prodotto {
private String nome;
private String categoria;
public String getNome() { return nome; }
public String getCategoria() { return categoria; }
public void setNome(String n) { nome = n; }
public void setCategoria(String c) { categoria = c; }
}

4.1 compiliamo Prodotto.java (javac -d . Prodotto.java) e lo impacchetto in jar (jar cf MyBeans.jar mybeans/).
4.2 copiamo il file MyBeans.jar in c:\servletsample\WEB-INF\lib\

5. creiamo una pagina html d'esempio per invocare un componente Servlet:

<html>
<head><title>Welcome</title></head>
<body>
<h1>Esempio</h1>
<form action="./RicercaProdotto">
<button type="submit">Vai</button>
</form>
</body>
</html>

Triste ma serve allo scopo. L'unica cosa che interessa è che la pagina invoca un che di nome "RicercaProdotto". Salviamo la pagina html nella cartella WEB-INF (diventa quindi "privata") col nome arbitrario "index.html".

6. Creiamo una pagina JSP che mostra un Prodotto:

<html>
<head><title>Risposta</title></head>
<body>
<%
Object value = request.getAttribute("risultato");
if(value != null && value instanceof mybeans.Prodotto) {
mybeans.Prodotto p = (mybeans.Prodotto)value;
out.println("Categoria: " + p.getCategoria());
}
%>
</body>
</html>

o, meglio, la categoria di un Prodotto. Salviamo la pagina JSP in WEB-INF (diventa privata come index.html) col nome arbitrario "pippo.jsp".

7. Creiamo un componente Servlet:

package servletsample;

import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class RicercaProdotto extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
mybeans.Prodotto p = new mybeans.Prodotto();
p.setNome("Acqua");
p.setCategoria("Alimentari");
req.setAttribute("risultato", p);
RequestDispatcher d = getServletContext().getRequestDispatcher("/cartelloneProdotti");
d.include(req, res);
}
}

RicercaProdotto si inventa un prodotto e lo rifila ad un che di nome "cartellone", ipotetica vista dei prodotto.

Compiliamo RicercaProdotto e salviamo il prodotto della compilazione, incluse le cartelle dei package e sotto package, in WEB-INF/classes. Otteniamo:

c:\miapplicazione\WEB-INF\classes\servletsample\RicercaProdotto.class

8. Creiamo il descrittore di dispiegamento dell'applicazione web. Attraverso il descrittore di dispiegamento possiamo collegare i nomi dei componenti ai riferimenti usati nei componenti stessi. Il primo passo è associare un nome ai componenti (servlet e pagine jsp), con l'elemento "servlet":

<servlet>
<servlet-name>gianni</servlet-name>
<servlet-class>servletsample.RicercaProdotto</servlet-class>
</servlet>
<servlet>
<servlet-name>pippo</servlet-name>
<jsp-file>/WEB-INF/pippo.jsp</jsp-file>
</servlet>

Notiamo come il contenuto di "servlet-name" abbia una funzione interna al descrittore: l'associazione tra nomi usati dai componenti e nomi dei componenti si realizzare negli elementi "servlet-mapping". Ad esempio, la pagina di benvenuto ha un pulsante alla cui pressione è invocato un componente il cui percorso, relativamente alla radice dell'applicazioner web, è "RicercaProdotto". Vogliamo collegare questo "nome" al componente "gianni"? Bene, associamo "gianni" a "/RicercaProdotto":

<servlet-mapping>
<servlet-name>gianni</servlet-name>
<url-pattern>/RicercaProdotto</url-pattern>
</servlet-mapping>

Il componente servlet usa un "/cartelloneProdotti"? Associamo il componente che per noi è il fantomatico cartellone prodotti al percorso "/cartelloneProdotti":

<servlet-mapping>
<servlet-name>pippo</servlet-name>
<url-pattern>/cartelloneProdotti</url-pattern>
</servlet-mapping>

Non resta che la nostra pagina di benvenuto, quella automaticamente presentata dal server quando si tenti l'accesso al contesto dell'applicazione web. La nostra pagina di benvenuto è in WEB-INF/index.html. Qui associamo il percorso reale alla funzionalità "pagina di benvenuto":

<welcome-file-list>
<welcome-file>/WEB-INF/index.html</welcome-file>
</wecome-file-list>

L'intero descrittore di dispiegamento assume la forma:

<?xml version="1.0"?>
<web-app>
<servlet>
<servlet-name>gianni</servlet-name>
<servlet-class>servletsample.RicercaProdotto</servlet-class>
</servlet>
<servlet>
<servlet-name>pippo</servlet-name>
<jsp-file>/WEB-INF/pippo.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>gianni</servlet-name>
<url-pattern>/RicercaProdotto</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>pippo</servlet-name>
<url-pattern>/cartelloneProdotti</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/WEB-INF/index.html</welcome-file>
</welcome-file-list>
</web-app>

e, ripeto, è salvato in "/WEB-INF/web.xml"

Adesso si arriva al dispiegamento. Impacchetta tutto in un WAR, usando il programma jar o uno zipper o quello che vuoi purche crei un archivio zip con estensione "war". Ricorda che qui il nome dell'archivio corrisponderà alla radice dell'applicazione:

jar cf ssample.war WEB-INF/ [invio]

A questo punto lanci tomcat e copi il file ssample.war in:

TOMCAT_HOME/webapps/

attendi qualche secondo e vedrai comparire una cartella "ssample" gestita in toto dal server e di cui ti disinteresserai totalmente: la tua applicazione è nello zip "war".

A questo punto puoi provare l'applicazione accedendo al server tomcat in locare (tipo localhost:8080/) e usando il nome del "war" come punto di partenza (localhost:8080/ssample).

A questo punto si dovrebbe spiegare perchè io abbia detto "la cosa potrebbe anche funzionare", all'inizio di questo tremendo messaggio. Il descrittore di dispiegamento ti consente, relativamente alla radice dell'applicazione web, di spargere i file un po' dove ti pare, sebbene esistano dei punti "consigliati" nelle specifiche servlet 2.4. I componenti servlet, ad esempio, potrebbero benissimo essere impachettati in un jar e finire in /lib. Le pagine JSP possono annidarsi a piacere o diventare pubbliche (direttamente o in via ulteriormente annidata).

Cerca sempre di affidare al server un pacchetto war, in modo tale da non dover litigare con le cartelle del server ma con le tue. E tieni sempre presente la relatività dei percorsi e dei nome nonchè la funzione tracciante del descrittore di dispiegamento.

Spero di non aver abusato della tua attenzione.

boysna
18-04-2006, 00:46
Grazie mille della immensa pazienza. In qualche modo ora Tomcat trova la jsp però mi da errori nel visualizzarla:

An error occurred at line: 5 in the jsp file: /VisualizzaProdotto.jsp
Generated servlet error:
Prodotto cannot be resolved to a type.

La servlet è questa, la riposto con qualche modifica rispetto la precedente:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;


public class RicercaProdotto extends HttpServlet {

public void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

GestioneDB cerca = new GestioneDB();
Prodotto p = cerca.cercaProdotto(request.getParameter("marca"), request.getParameter("modello"));
request.setAttribute("prodotto", p);
gotoPage("/VisualizzaProdotto.jsp",request,response);

}

private void gotoPage( String address,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher(address);
dispatcher.forward(request,response);
}
}



E questa è la jsp che dovrebbe visualizzare l'attributo categoria del bean passato dalla sevlet:

<HTML><HEAD><TITLE>Visualizza PRODOTTO</TITLE></HEAD>

<BODY BGCOLOR="white">

<%
Prodotto p = (coreservlets.Prodotto)request.getAttribute("prodotto");
out.println("Categoria: " + p.getCategoria()+"<br>");
%>


</BODY>
</HTML>

PGI-Bis
18-04-2006, 10:56
Una svista. Come hai fatto nella conversione esplicita, usa il nome pienamente qualificato del tipo Prodotto anche nella dichiarazione della variabile p:

coreservlets.Prodotto p =
(coreservlets.Prodotto)request.getAttribute("prodotto");

Alternativamente importa il package "coreservlets" con una direttiva jsp.