Ciao a tutti, sono uno studente di ingegneria e per l'esame di Basi di dati 2, devo realizzare un Dynamic Web Project. Ho già creato un database di supporto utilizzando il dbms Oracle 10g. Adesso devo realizzare la parte applicativa, quindi il portale vero e proprio.
I ferri del mestiere sono Eclipse Indigo for JavaEE Developer e Apache Tomcat 7.0.
Purtroppo, avendo poca esperienza, ho avuto da subito problemi con il login utente.
Di seguito posterò il codice dei file che ho sin qui realizzato, con la premessa che per crearli mi sono basato su degli esempi forniti dal docente. Innanzitutto posto il codice della pagina jsp, all'interno della quale si trova il form nel quale inserire username e password. In particolare qui ho postato soltanto il body, dove è contenuto il form che richiama la servlet Login.
codice:
<body>
<center><font size="5">Benvenuto in MyTicket</font></center>
</p>
Inserisci username e password per effettuare il login.</p>
<form action="Login" method="post">
<table cellspacing="5">
<tr>
<td>Username:</td>
<td><input type="text" name="username" size="25"/></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" size="25"/></td>
</tr>
<tr>
<td> <input type="submit" name="submit" value="Login"/></td>
</tr>
</table>
</form>
</body>
Di seguito è riportata la classe Operatore, nome con il quale identifico la persona che fisicamente accede al sistema. Nel database ho memorizzato una tabella Operatore con i seguenti attributi: ID, Nome, Cognome, Username, Password, Ruolo. Ruolo serve a distinguere i normali Operatori, per così dire "dipendenti", dagli amministratori. Su Ruolo c'è un vincolo Check, cioè l'attributo (di tipo VARCHAR2) può assumere solo due valori: 'Impiegato', 'Amministratore', quindi il login mi indirizzerà in due pagine diverse a seconda del ruolo, oppure in una pagina di errore.
Detto questo posto la classe Operatore.java:
codice:
package myBeans;
public class Operatore {
private int id;
private String nome;
private String cognome;
private String username;
private String password;
private String ruolo;
public Operatore() {
id = 0;
nome = "";
cognome = "";
username = "";
password = "";
ruolo = "";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCognome() {
return cognome;
}
public void setCognome(String cognome) {
this.cognome = cognome;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRuolo() {
return ruolo;
}
public void setRuolo(String ruolo) {
this.ruolo = ruolo;
}
/**
* Override del metodo equals della classe Object.
* @return - restituisce un boolean che e' true quando due utenti hanno la stessa
* chiave; in tutti gli altri casi restituisce false.
*/
public boolean equals(Object anObject)
{
if ( anObject == null )
return false;
if (! (anObject instanceof Operatore) )
return false;
Operatore o = (Operatore) anObject;
if (id != o.id)
return false;
return true;
}
/**
* Override del metodo toString della classe Object.
*/
public String toString(){
String toString = null;
toString = "L'id dell'operatore e' " + id + ",";
toString += " il suo nome e' " + nome + ",";
toString += " il suo cognome e' " + cognome + ".";
toString += " il suo username e' " + username + ",";
toString += " la sua password e' " + password + ",";
toString += " il suo ruolo e' " + ruolo;
return toString;
}
}
Per l'interazione con il database, il prof ci ha consigliato di creare una classe DBManager di supporto, per incapsulare il codice per l'interfacciamento tra portale e web.
Questo è il codice:
codice:
package myUtil;
import java.util.*;
import java.sql.*;
import myBeans.*;
public class DBManager {
String DbDriver;
String DbURL;
String username;
String password;
Connection conn;
/**
* Metododo che restituisce true se la connessione e' aperta.
*/
public boolean isOpen()
{
if (this.conn == null)
return false;
else
return true;
}
/**
* Costruttore della classe. Riceve l'url del driver jdbc, la username e la password
* necessari per la connessione al database.
*/
public DBManager()
{
this.DbDriver = "sun.jdbc.odbc.JdbcOdbcDriver";
this.DbURL = "jdbc:odbc:oracleODBC";
this.username = "myproject";
this.password = "nino";
}
public DBManager(String url, String usn, String psw)
{
this.DbDriver = "oracle.jdbc.driver.OracleDriver";
this.DbURL = url;
this.username = usn;
this.password = psw;
}
private boolean startConnection()
{
if ( isOpen() )
return true;
try
{
Class.forName(DbDriver);// Carica il Driver del DBMS
conn = DriverManager.getConnection(DbURL, username, password);// Apertura connessione
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return true;
}
private boolean closeConnection()
{
if ( !isOpen() )
return true;
try
{
conn.close();
conn = null;
}
catch (SQLException e)
{
e.printStackTrace();
return false;
}
return true;
}
/**
* Metodo che esegue una query di update o delete. Riceve la stringa sql e
* restituisce true se la query viene eseguita correttamente, false altrimenti.
*/
public boolean executeUpdate(String sql)
{
startConnection();
Statement st;
try
{
st = conn.createStatement();
st.executeUpdate(sql);
}
catch (SQLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
closeConnection();
return true;
}
/**
* Metodo che esegue una query di select. Riceve la stringa sql e la stringa che
* indica la tipologia di classe su cui si vuol restituire il vettore dei risultati.
* Restituisce il vettore dei risultati.
*/
public Vector<Object> executeSelect(String sql, String type)
{
startConnection();
Vector<Object> v = new Vector<Object>();
Statement st;
try
{
st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
while( rs.next() )
{
if ( type.equals("Operatore") )
{
Operatore o;
o = new Operatore();
o.setId( rs.getInt("ID") );
o.setNome( rs.getString("NOME") );
o.setCognome( rs.getString("COGNOME") );
o.setUsername( rs.getString("USERNAME") );
o.setPassword( rs.getString("PASSWORD") );
o.setRuolo( rs.getString("RUOLO") );
v.add(o);
}
}
}
catch (SQLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
closeConnection();
return v;
}
}
La classe che segue serve per manipolare gli operatori del database:
codice:
package myBeans;
import java.util.Vector;
import myUtil.DBManager;
public class OperatoreDAO {
DBManager db;
public DBManager getDb() {
return db;
}
public void setDb(DBManager db) {
this.db = db;
}
public Operatore getOperatore(String username)
{
Operatore res = new Operatore();
String query = "SELECT * FROM operatore WHERE username = "+username;
Vector<Object> v =db.executeSelect(query, "Operatore");
res = (Operatore)v.get(0);
return res;
}
public Vector<Operatore> getOperatori()
{
Vector<Operatore> res = new Vector<Operatore>();
String query = "SELECT * FROM operatore";
Vector<Object> supp = db.executeSelect(query, "Operatore");
for(int i=0;i<supp.size();i++)
res.add((Operatore)supp.get(i));
return res;
}
public boolean salvaOperatore(Operatore o)
{
boolean esito;
String query = "INSERT INTO Operatore VALUES ( '?', '?', '?', '?', '?', '?')";
query=query.replaceFirst("[?]", ((Integer)o.getId()).toString());
query=query.replaceFirst("[?]",o.getNome());
query=query.replaceFirst("[?]",o.getCognome());
query=query.replaceFirst("[?]",o.getUsername());
query=query.replaceFirst("[?]",o.getPassword());
query=query.replaceFirst("[?]",o.getRuolo());
esito = db.executeUpdate(query);
return esito;
}
public boolean eliminaOperatore(Operatore o)
{
boolean esito;
String query = "DELETE FROM Operatore WHERE id = " +o.getId();
esito = db.executeUpdate(query);
return esito;
}
/*
* eventualmente inserire altri metodi per la manipolazione degli operatori nel DB
*/
}
E infine, ecco la famigerata servlet che deve realizzare il login.
codice:
package myServlets;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import myBeans.*;
/**
* Servlet implementation class Login
*/
@WebServlet("/Login")
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Login() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
performTask(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
performTask(request, response);
}
public void performTask (HttpServletRequest request, HttpServletResponse response)
{
OperatoreDAO d = new OperatoreDAO();
Operatore o = d.getOperatore(request.getParameter("username"));
try
{
String categoria = request.getParameter("ruolo");
String jspPage = "";
if (o.getRuolo().equals(request.getParameter("ruolo"))){
if ( categoria.equals("Amministratore") )
{
jspPage = "jsp/adminhome.jsp";
}
else if ( categoria.equals("Impiegato") )
{
jspPage = "jsp/emphome.jsp";
}
}
else {
jspPage = "jsp/errore.jsp";
}
request.getRequestDispatcher( jspPage ).forward(request,response);
}
catch(Throwable theException)
{
//theException.printStackTrace();
}
}
}
Per completezza vi posto anche il file web.xml.
codice:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
<servlet>
<servlet-name>Login</servlet-name>
<servlet-class>myServlets.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/Login</url-pattern>
</servlet-mapping>
</web-app>
Ora vi chiederete qual'è il problema. Così il codice non da nessun errore. Il problema è ovviamente quando avvio Tomcat.
Vengo subito indirizzato alla pagina login.jsp, e fin qui tutto ok. Quando però inserisco username e password, o anche quando non inserisco nulla sul form, e clicco il pulsante login, mi da errore.
Ecco l'eccezione che mi viene mostrata:
codice:
java.lang.NullPointerException
myBeans.OperatoreDAO.getOperatore(OperatoreDAO.java:21)
myServlets.Login.performTask(Login.java:52)
myServlets.Login.doPost(Login.java:42)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722
Da quanto risulta nel messaggio di errore, sembra che il problema sia nel richiamo alla connessione effettuato dal bean OperatoreDAO. Precisamente dà errore nel punto in cui viene creato il vettore contenente i dati. Il problema è che non so proprio come rimediare.
Chiedo scusa se il post è lungo ma volevo fornire la migliore visione possibile del problema.
Grazie in anticipo a chi potrà aiutarmi.
EDIT: http://imageshack.us/photo/my-images...magineqje.jpg/
Nell'immagine la struttura del progetto.