Bonjour,
Je tiens tous d'abord à vous remercier d'avance pour l'aide que vous m'apporteriez.
Je suis étudiant en IUT. Je dois monter un gros projet : un site internet communautaire (Content Management Systems) comportant une base de donnée. J'utilise un pont JDBC-ODBC pour me connecter à ma base.
Je n'arrive pas à établir la connexion à partir de mon application java à ma base de données.
Mon infrastructure réseau:
Serveur :
- Basé physiquement dans l'IUT et logiquement sur le réseau de l'IUT et sous-réseau de la filière SRC (10.0.0.46.src.iut-velizy.uvsq.fr)
- Accessible depuis l'extérieur via tunnel SSH utilisant un alias interne "emotion" redirigeant vers le serveur (IP=10.0.0.46 sur le réseau de l'IUT).
NB : Ici le tunnel SSH marche sans aucun problème avec mes identifiants.
J'utilise PuTTY configuré de la façon suivante :
SESSION = port: 22 (sftp), hôte: monlogin@res.iut-velizy.uvsq.fr et mon mdp pour me connecter à ma session sur le reseau de l'IUT.
TUNNEL SSH = port source: 5000, serveur: emotion:80
Ma BDD:
Type = MySQL
Nom = freez
Localisation = localhost (celui de mon serveur)
Utilisateurs MySQL = admin [tous les droits], hote [droits restreints à l'écriture / lecture / modification / suppression de données] (chaque utilisateur ne pourra modifier que les entrées correspondants à son id)
Le pont ODBC-JDBC
J'ai installé l'interface ODBC sur mon serveur Linux (Debian) [Note aux linuxiens = j'utilise mandriva et ubuntu personnellement donc pas de réflexions "ubuntu c'est mieux ou autre!" merci ;)]
Je l'ai configurée en console grâce à ce tuto : http://www.linuxplusvalue.be/mylpv.php?id=118
Voici les fichiers de config:
/etc/odbcinst.ini
[MySQL]
Description = ODBC Driver for MySQL
Driver = /usr/lib/odbc/libmyodbc.so
Setup = /usr/lib/odbc/libodbcmyS.so
FileUsage = 1
CPTimeout =
CPReuse =
/etc/odbc.ini
[MySQL-test]
Description = MySQL database test
Driver = MySQL
Server = localhost
Database = freez
Port = 5000
Socket =
Option =
Stmt =
J'ai testé l'interface ODBC sur le serveur grâce à la commande isql MySQL-test admin mdp
J'arrive à me connecter.
Mon Client JAVA
Après toutes ces informations pré requises, voici le code du client java :
Ce dernier est séparé en 3 classes :
Appli [Principale],
PanneauConfig et
PanneauPhrase.
Appli
Cette classe contient l'interface dans le constructeur (des zones de textes correspondants aux instructions select, from, where, group, order qui seront insérées dans les requêtes SQL grâce à la classe PanneauPhrase), charge le driver "sun.jdbc.odbc.JdbcOdbcDriver", établit la connection à la BDD selon les paramètres retournés par la classe PanneauConfig, envoie les requêtes à la base et affiche le résultat dans la zone de texte "resultat".
import java.awt.Frame;
import java.awt.Button;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.sql.*;
class Appli extends Frame
{
PanneauPhrase select, from, where, group, order;
TextArea resultat;
Button send;
PanneauConfig pc;
public Appli ()
{
super("e-motion - Connection à la BDD Freez");
setLayout (new GridLayout (8, 1));
add (pc = new PanneauConfig ());
add (select = new PanneauPhrase ("SELECT"));
add (from = new PanneauPhrase ("FROM"));
add (where = new PanneauPhrase ("WHERE"));
add (group = new PanneauPhrase ("GROUP BY"));
add (order = new PanneauPhrase ("ORDER BY"));
add (resultat = new TextArea (3,25));
add (send = new Button ("Envoi"));
send.addActionListener (new ActionListener (){
public void actionPerformed(ActionEvent e){
envoiRequete ();}});
addWindowListener (new WindowAdapter ()
{public void windowClosing(WindowEvent e)
{
setVisible (false);
dispose ();
System.exit (0);
}});
pack ();
setVisible (true);
}
void envoiRequete()
{
try
{
String nomDriver = "sun.jdbc.odbc.JdbcOdbcDriver";
try
{
Class.forName(nomDriver);
}
catch(ClassNotFoundException cnfe)
{
System.out.println("La classe "+nomDriver+" n'a pas été trouvée");
cnfe.printStackTrace();
}
Connection db;
ResultSet rs;
Statement s;
String requete;
{
ResultSetMetaData rsmd;
int nCol;
db = DriverManager.getConnection(pc.getURL (), pc.getUser (), pc.getPasswd ());
s = db.createStatement ();
/* -----------------------------------------
Ici on utilise la méthode getPhrase de nos objets
pour constituer une requete a la place de la requete
suivante :
----------------------------------------- */
requete = select.getPhrase()+from.getPhrase()+where.getPhrase()+group.getPhrase()+order.getPhrase()+";";
System.out.println(requete);
rs = s.executeQuery (requete);
rsmd = rs.getMetaData ();
nCol = rsmd.getColumnCount();
resultat.setText ("");
while (rs.next ())
{
String tmp= "";
for (int i = 1; i <= nCol ; ++i)
{
switch (rsmd.getColumnType (i))
{
case Types.INTEGER:
tmp = ""+rs.getInt (i);
break;
case Types.CHAR:
tmp = ""+rs.getString (i);
break;
default:
System.out.println("Type non implémenté");
break;
}
resultat.append (tmp+"\t");
}
resultat.append ("\n");
}
db.close ();
}
}
catch (SQLException ex)
{
System.out.println("Exception: " + ex.toString());
ex.printStackTrace() ;
}
} /* envoiRequete */
public static void main(String argv[])
{
new Appli ();
}
}
PanneauPhrase
Cette classe récupère le contenu des champs textes select, from, where ... pour retourner une requête toute faite.
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.Label;
class PanneauPhrase extends Panel
{
private TextArea phrase;
private String req, espace=" ";
public PanneauPhrase (String Nom)
{
req = Nom;
add (new Label (Nom));
add (phrase = new TextArea (2, 30));
}
String getPhrase()
{
String tmp = phrase.getText ();
if (tmp.equals(""))
return tmp;
else
return espace+req+espace+tmp;
} /* getPhrase */
}
PanneauConfig
Cette classe contient l'interface (des champs textes affichant les paramètres de connexion), et retourne l'utilisateur, le mot de passe et l'URL de la base de données utilisés par la méthode
DriverManager.getConnection()
de la classe Appli.
import java.awt.Panel;
import java.awt.TextField;
import java.awt.GridLayout;
class PanneauConfig extends Panel
{
private TextField tf, base, user, mdp;
public PanneauConfig ()
{
Panel tmp;
setLayout (new GridLayout (2, 1));
// Cette boite contient l'URL de la base
tmp = new Panel ();
tmp.add (tf = new TextField ("jdbc:odbc://localhost:5000", 20));
tmp.add (base = new TextField ("/freez"));
add (tmp);
// Celle ci contient le nom de l'utilisateur
tmp = new Panel ();
tmp.add (user = new TextField ("hote"));
// et son mot de passe.
tmp.add (mdp = new TextField (""));
add (tmp);
}
/** Retoune l'URL de la base */
public String getURL ()
{
System.out.println("URL "+tf.getText ()+base.getText ());
return tf.getText ()+base.getText ();
}
/** Retoune le nom de l'utilistateur de la base */
public String getUser ()
{
return user.getText ();
}
/** Retoune le mot de passe de l'utilistateur de la base */
public String getPasswd ()
{
return mdp.getText ();
}
}
Diagnostique
La compilation du code s'effectue normalement.
L'exécution de la classe Appli s'effectue normalement.
Lorsque j'essaye d'envoyer une requête en remplissant le champ select avec
* et le champ from avec
utilisateurs (cela correspond à afficher toutes les entrées de la table utilisateurs de la BDD freez), j'ai les messages d'erreurs en console suivants :
URL jdbc:odbc://localhost:5000/freez
Exception: java.sql.SQLException: [Microsoft][Gestionnaire de pilotes ODBC] Sour
ce de donnÚes introuvable et nom de pilote non spÚcifiÚ
java.sql.SQLException: [Microsoft][Gestionnaire de pilotes ODBC] Source de donnÚ
es introuvable et nom de pilote non spÚcifiÚ
at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
at sun.jdbc.odbc.JdbcOdbc.SQLDriverConnect(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcConnection.initialize(Unknown Source)
at sun.jdbc.odbc.JdbcOdbcDriver.connect(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at Appli.envoiRequete(Appli.java:65)
at Appli$1.actionPerformed(Appli.java:32)
at java.awt.Button.processActionEvent(Unknown Source)
at java.awt.Button.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
NB : Ce code est tiré d'un programme qui à l'origine marchait sur une base de donnée postgreSQL mais située en local sur le serveur de l'IUT. Seuls le chargement du driver, et les paramètres de connexion diffères!
Mais il faut prendre en compte le fait que j'utilise un tunnel SSH pour tester ce client (PuTTY est lancé).
Si vous lisez ces lignes, je vous remercie déjà d'avoir lu ce petit roman, et je vous remercie d'avance pour toute piste que vous pourriez me donner! Merci.
Configuration: Windows Vista
Firefox 2.0.0.12