• Nenhum resultado encontrado

Επιτυχία προχωρημένης λειτουργικότητας του Connector/J με τα Servlets

Στο προηγούμενο κεφάλαιο, κοιτάξαμε την χρήση εφαρμογών Connector/J του MySQL, και του

Java, για την πρόσβαση στοιχείων, από το database. Συνήθως οι χρήστες αυτών των εφαρμογών,

προβαίνουν στο πρόγραμμα από τον υπολογιστή τους του (desktop), γραφείου. Εάν σχεδιάζεται

μια εφαρμογή, εν βάσει του διαδικτύου με το Java, είτε εάν αναπτύσσετε ένα σύστημα του

Enterprise JavaBeans (EJB) (το οποίο θα συζητήσουμε στο Κεφαλαιο11, το EJB με το MySQL), ή

εάν χρησιμοποιείτε ένα servlet ή ένα Java ServerPage (JSP). Σε αυτό το κεφάλαιο, θα

εξερευνήσουμε το πώς να προβείτε στο database και από τα δυο, από ένα servlet και από μια

σελίδα του JSP. Για να επιδείξουμε το πώς να χρησιμοποιήσετε ένα servlet, αναπτύσσουμε μια

εφαρμογή, που συμπεριλαμβάνει εικόνες με δακτυλικά αποτυπώματα, μέσα σε λογαριασμό

εφαρμογής, από το προηγούμενο Κεφάλαιο. Επίσης θα δημιουργήσουμε ένα servlet και θα το

σχετίσουμε με το HTML, για να επιθεωρήσουμε τις εικόνες, από το διαδίκτυο.

outprintln("</UL>") ;

outprintln(" </BODY></HTML>") ; rs.close() ;

statement.close() ; connection.close() ; }

catch(ClassNotFoundException e) { out.println(nDriver Error"); } catch(SQLException e) {

out.println(nSQLException: n + e.getMessage());

}}

public void dOPost(HttpServletRequest inRequest, HttpServletResponse outResponse) throws ServletException, IOException {

doGet(inRequest, outResponse);

}} . , ,

Λίστα 6.1 Ο βασικός μας κώδικας του servlet/JDBC

Όταν κτίζετε servlets, πρέπει να ακλουθήσατε ένα συγκεκριμένο σχήμα, το οποίο να καθορίζει τις προδιαγραφές του Java. Αυτές οι μέθοδοι, χειρίζονται τους τύπους μηνυμάτων GET και POST HTML. Είναι μια συνηθισμένη πρακτική η εφαρμογή της μεθόδου doGet() και έχει doPost() doGet0, ώστε να μπορούν να χειριστούν τα ίδια τα στοιχεία.

Ο κώδικας servlet μέσα στο doGet(), αρχίζει θέτοντας τον τύπο απάντησης του text/html, ο οποίος επιτρέπει την browser (δείκτη) του πελάτη να μάθει ότι η πληροφορία πέρασε από το servlet, θα πρέπει να παραδώσει, χρησιμοποιώντας έναν κλητήρα HTML. Το servlet θα γυρίσει σε ενός διαφορετικού τύπου μορφής, εάν χρειαστεί.

Στη συνεχεία μπαίνουμε σε παρεμπόδιση try/catch και αρχίζουμε την πρόσβαση σύνδεσης με το database και να αποκτούμε στοιχεία για να γυρίσουν στον χρήστη. Αφού ένα servlet είναι μια διαδικασία του Java, χρειαζόμαστε τον Connector/J να φορτωθεί, έτσι ώστε να έχουμε τον οδηγό, απαραιτήτως, για την πρόσβαση στη MySQL. Το servlet χρησιμοποιεί την μέθοδο του Class.forName για να φορτώσει τον οδηγό (έτσι όπως όλες οι εφαρμογές στο προηγούμενο κεφάλαιο). Ωστόσο, παρατηρήστε ότι το servlet εκτελεί αυτήν την λειτουργία μόνο του.

Μετά που φορτωθεί ο οδηγός, όλοι οι κώδικες που αποκτούν πληροφορίες από το database είναι το ίδιο όπως το είδαμε στο προηγούμενο κεφάλαιο. Ένα αντικείμενο Σύνδεσης είναι ακαριαίο από τον DriverManager, ένα αντικείμενο αναφοράς δημιουργείται από το αντικείμενο σύνδεσης και τελευταία, ένα αντικείμενο του ResultSet χρίζεται όταν η μέθοδος του Query() εκτελείτε, έναντι του αντικείμενου Statement. Όταν αυτή η διαδικασία συμπληρωθεί, ένα string χρησιμοποιείται για να κινηθεί μέσω του ResultSet και να χτισθεί ένα HTML έγγραφο για την προσπέραση στον browser του πελάτη. Τελευταία, όλα από τα τεμάχια ^ s διαδικασίας, κλείνονται και το HTML προσπέρνα στον browser.

Σημείωση: Ο κώδικας που χρησιμοποιήθηκε από την απόκτηση αποτελεσμάτων των database εντός του servlet, είναι ακριβώς ο ίδιος όπως ο κώδικας που χρησιμοποιείται σε εφαρμογή του Java ή applet. Ωστόσο, θα το βρείτε εύκολο να κτίσετε εφαρμογές του Java και του MySQL.

Συνδέσεις DataSource

Όταν χρησιμοποιείτε τους servlets του Java και τελικά τα beans, θα έχετε έναν εναλλακτικό τρόπο απόκτησης πληροφοριών, γύρω από την σύνδεση της MySQL database. Εναλλακτική είναι η χρήση ενός DataSource και το Java Naming και Directory Interface (JNDI). Το JNDI παρέχει έναν τρόπο να θέτει συγκεκριμένες υλικές πληροφορίες του database στον βοηθό εφαρμογής αντί να θέτει τις πληροφορίες κατευθείαν στην εφαρμογή. Η εφαρμογή στη Λίστα 6.1 αποκτάει μια σύνδεση στον βοηθό του DATABASE με αυτόν τον κώδικα:

Class.forName(“com.mysql.jdbc.Driver”);

connection=DriverManager.getConnection(

“jdbc:mysql://localhost/acc_id”);

stcctement=connection.creccteStcctement();

Όπως βλέπετε, η εφαρμογή είναι πολύ συγκεκριμένη γύρω από το Database που θα κάνει πρόσβαση. Με το JNDI θέτουμε πληροφορίες γύρω από την σύνδεση του DATABASE εντός διαμορφωμένου αρχείου του βοηθού της εφαρμογής. Για παράδειγμα:

<resourse-ref>

<res-ref-name >jdbc/AccountsDB</res-ref-name >

<res-type>javax. sql. DataSourse </res-type >

<init-param driver-name=“org.gjt.mm.mysql.Driver”/>

<init-param url=“jdbc:mysql://localhost:3306/accounts”/>

<init-param user=“”/>

<init-param passw ord=“”/>

<init-param max-connections=“20”/>

<init-param max-idle-time=“30”/>

</resourse-ref>

Αυτή η πληροφορία αρχίζει με το όνομα της πρώτης ύλης, jdbc/AccountsDB, η τάξη που θα χρησιμοποιηθεί όταν χρειαστεί, πρώτες ύλες, το database, το όνομα του οδηγού, το URL για την ανεύρεση του DATABASE, και μετά μερικές πληροφορίες γύρω από τις παραμέτρους που θα περαστούν στον οδηγό, όταν είναι στιγμιαίος. Για να αποκτήσετε αυτήν την πληροφορία σύνδεσης από μια εφαρμογή, αλλάξτε τις προηγούμενες αναφορές σύνδεσης με τα ακόλουθα:

Context ctx=new InitialContextf);

DataSource ds=(Data.Source)ctxAookup(“jcLVŒcomp/env/jdbc/AccountsDB”);

connection=ds.getConnection();

Αυτός ο κώδικας αρχίζει, παίρνοντας το περιεχόμενο της διαμόρφωσης που περιστοιχίζει αυτήν την εφαρμογή. Μετά, κοιτά μέσα στο περιεχόμενο της αναφοράς του ονόματος της πρώτης ύλης.

Τελικά, μια σύνδεση είναι instantiated από το αντικείμενο του DataSource, επιστρέφει από το περιεχόμενο του lookup. Σε αυτό το σημείο, όλοι οι κώδικες που αποκτούν αντικείμενα αναφοράς και εκτελούν ερωτήσεις, είναι ιδία.

Εκτέλεση περιβάλλοντος

Λοιπόν, πώς ακριβώς εκτελείται ο κώδικας του SERVLET; Θα χρειαστείτε να έχετε έναν βοηθό εφαρμογής διαθέσιμο που στον οποίον θα βάλετε τον κώδικα του servlet του Source.

Πολυάριθμοι βοηθοί είναι διαθέσιμοι, συμπεριλαμβανόμενων το Resin, το Tomcat, και το BOSS, ανάμεσα σε άλλους. Σε αυτό το κεφάλαιο, θα εκτελέσουμε όλα τα παραδείγματα, χρησιμοποιώντας τον Resin, βοηθό εφαρμογών.

Βάσεις Δεδομένων

Αυτό το κεφάλαιο ξεπερνά τις βασικές χρήσεις του Connector/J με το MySQL. Για αυτό, χρειάζεται να προσθέσουμε ένα άλλο DATABASE και έναν πίνακα στον αυξανόμενο μας σύστημα του DATABASE. Υποθέτουμε ότι έχουμε δημιουργήσει τους DATABASE στο προηγούμενο κεφάλαιο. Το νέο μας DATABASE αποκαλείται (identification), και το κτίζουμε με αυτήν την εντολή:

create database identification;

Το σχήμα για τον πίνακα που αποκαλείται thumbnail είναι ο ακόλουθος.

Thumb_id-int-Ένας μοναδικός δείκτης στοιχείων, για τον πίνακα.

Acc_id-int - Ένα ξένο κλειδί για τον πίνακα acc_acc.

Ρΐ^Μ ο^Παρουσιάζει τα δυαδικά στοιχεία για ένα δακτυλικό αποτύπωμα.

sysobject- blob-Ένα διαδοχικό αντικείμενο του Java για ένα δακτυλικό αποτύπωμα.

ts-timestamp-Η αξία της σφραγισμένης ώρας 0, δείχνει ότι είναι πρόσφατο.

acc_ts -timestamp-Η ώρα του τελευταίου εκσυγχρονισμού.

Κτίστε τον πίνακα με αυτήν την εντολή:

create table thumbnail ( thumb_id int not null, acc_id int not null, pic blob,

sysobject blob, ts timestamp, act_ts timestamp,

primary key (thumb_id, acc_id, ts));

Μπορείτε να κατεβάσετε παραδειγματικούς κώδικες βάσεων δεδομένων από το βιβλίο της

ιστοσελίδας στο http: //wilev.com/gradecki/mvsqliava.

Προετοιμασμένες αναφορές

Όπως ξέρετε, από την ανάγνωση της εισαγωγής του κεφαλαίου, μια από τις εφαρμογές που θέλουμε να κτίσουμε είναι ένας συνδυασμός servlet/HTML που θα επιτρέπει έναν απομονωμένο χρήστη να αποκτήσει πληροφορίες από το DATABASE, για κάθε έναν από τους λογαριασμούς μέσα στο δικό μας το DATABASE. Ο κώδικας μας θα πρέπει να επιδεικνύει όλες τις πληροφορίες του λογαριασμού από τον πίνακα acc_acc. Τελικά, σχεδιάζουμε να δέσουμε μέσα στον νέο πίνακα του thumbnail που μόλις δημιουργήσαμε. Με σκοπό, να χρησιμοποιήσουμε την νέα εφαρμογή, οι χρήστες, θα χρειαστεί να χρησιμοποιήσουν ένα browser και να browse σε μια αρχική σελίδα του HTML, όπου θα παρακινηθούν να εισάγουν έναν αριθμό λογαριασμού και να πατήσουν επάνω στο κουμπί Submit. Μετά, θα ειδοποιηθεί και θα χρησιμοποιηθεί ένα SERVLET για να αποκτήσει αποτελέσματα από το DATABASE, και θα επιστρέψει τα αποτελέσματα στον browser του πελάτη.

Το σχήμα 6.1 δείχνει γιατί πράγμα συζητάμε. Μετά που θα κοιτάξουμε στο σχήμα 6.1, θα σαρώσουμε, δια μέσου του κώδικα στην Λίστα 6.2, και 6.3 για να δούμε ένα παράδειγμα, του πώς μοιάζει ο κώδικας.

Σχήμα 6.1 Το servlet/HTML μας

<HTML> <BODY>

<TITLE>see Account Information</TITLE>

Enter account number to view:<BR>

<form

action="http://localhost:8080/ca/seeAccount'' method="Post">

<input name="account">

<input type="submit" name="submit" value="submit">

</ form>

</BODY>

</HTML>

Λίστα 6.2 Το HTML παράδειγμα μας

import java.io.*;

import java.sql.*;

import j avax. servlet. * ; import javax.servlet.http.*;

public class SeeAccount extends HttpServlet {

public void doGet(HttpServletRequest inRequest, HttpServletResponse outResponse) throws ServletException, IOException {

printWriter out = null;

Connection connection = null; PreparedStatement statement = null; Resul tSet rs, rs2 ;

try { outResponse.setContentType{"text/html") ; out = outResponse.getWriter();

Class. forName (" com. mysql. j dbc . Driver") ; connection = DriverManager.getconnection(

"jdbc:mysql://localhost/accounts") ; if (connection != null) {

if (inRequest. get Parameter (" submit") . equals (" submit")) {

statement = connection.prepareStatement( "SELECT * FROM acc acc " +

"LEFT JOIN ace add " +

"on acc acc.acc_id = acc_add.acc_id " +

"WHERE acc_acc.acc_id = ? AND acc acc.ts = 0"); if (statement ! = null) { statement.setInt(l, Integer.parseInt( inRequest.getParameter("account"»)) ; rs = statement.executeQuery();

if (! rs. next () {

out.println("<HTML>No Account Found for # " + inRequest.getParameter{"account"J + "</HTML>"); } else { out.println{"<HTML><HEAD><TITLE>Thumbnail

Identification Record</TITLE></HEAD>"); out.println{"<BODY>") ; out.println(IIAccount Information:<BR>"); out.println(II<table>") ; out.println(II<form method= 'UpdateAccount, method='post'>") ;

out.println("ctr>ctd>"); out.println("Account: cinput name='acc_id' vaIue='" + rs.getString("acc_acc.acc_id") + II I ><BR> ") ;

out. print In ("Name: cinput name=' username' vaIue='" + rs.getString("acc_acc.username") + II I ><BR> II)

;

out.println("Addressl: <input name= , addressl, vaIue='" + rs.getString("acc_add.addressl") + 1I'><BR>");

out.println("Address2: cinput name= , address2, vaIue='" + rs.getString("acc_add.address2") + II I ><BR>

It) ;

out.println("Address3: cinput name='address3' vaIue='" + rs.getString("acc_add.address3") + E11><BR>II)i out.println("City: cinput name='city' vaIue='" + rs.getString("acc_add.city") + "'>cBR>"); out.println("State:

cinput nam e-state' va lu e-" + rs.getString("acc_add.state") + "'>cBR>"); out. println (" Zip: cinput name=' zip' value='" + rs.getStrlng("acc add. zip") + "'>cBR>"); out.println("cinput type='submit' value= 'update , name='submit'>"); out.println("c/form>") ; out.println("c/td>");

out .printIn ("ctd>thumbnail") ; out.println("c/td>c/tr>"); out.println("c/table>") ; out.println(" c/BODY>c/HTML>") ;

} } else {

out.println("cHTML>Statement is NULLc/HTML>");

} } else { lido update

statement = connection.prepareStatement( "UPDATE accounts.acc acc SET username = ? WHERE accounts.acc_acc.acc_id = ?"); statement.setString(l, inRequest.getParameter(

"username"» ;

statement.setlnt(2, Integer.parselnt( inRequest.getParameter("acc id"»); int i = statement. executeUpdate ()

;

statement = connection.prepareStatement("UPDATE accounts.acc_add SET addressl=?, address2=?, " +

"address3=?, city=?, state=?, zip=? WHERE accounts.acc_add.acc_id = 7") ; statement.setString(l, inRequest.getParameter( "addressl"» ;

statement.setString(2, inRequest.getParameter( "address2") ) ; statement.setString(3, inRequest.getParameter( "address3") ) ; statement.setString(4, inRequest.getParameter( "city") ; statement.setString(5, inRequest.getParameter( "state"» ; statement.setString(6, inRequest.getParameter( "zip"» ; statement.setIntI7, Integer.parseInt(

inRequest.getParameter("acc_id"))) ; int j = statement.executeUpdate();

out. print In I "<HTML>") ;

out.println("Update to acc_acc = " + i + "<BR>"); out.println("Update to acc_add =" + j + "<BR>");

out.println("</HTML>") ; }

} else {

out.println("<HTML>Connection is NULL</HTML>");

} }

catchlClassNotFoundException e) { out. println ( "Dri ver Error");

}

catchlSQLException e) {

out. print In ( " <HTML> " ) ; out.println("SQLException: " + e.getMessage(» ; out.println("</HTML>") ; }

catch(Exception e) { e.printStackTrace() ; } }

public void doPost(HttpServletRequest inRequest, HttpServletResponse outResponse) throws ServletException, IOException { doGetlinRequest, outResponse) ;

} } , ,

Λίστα 6.3 Το παράδειγμα servlet μας για PreparedStatements

Ο κώδικας παραδείγματός μας στη λίστα 6.2 παρουσιάζει το HTML με το οποίο η μηχανή

αναζήτησης πελατών θα συνδέσει αρχικά για να δει έναν απολογισμό. Το αποτέλεσμα του HTML

στη μηχανή αναζήτησης πελατών παρουσιάζεται στο σχήμα 6.2. Όταν ο χρήστης βάζει έναν αριθμό

απολογισμού στη γραμμή εισαγωγής μορφής και κλικάρει στο submit κουμπί, το servlet στη λίστα

6.3 ενεργοποιείται και οι πληροφορίες που παρουσιάζονται στο σχήμα 6.3 επιστρέφονται στο

χρήστη. Εκτός από την άδεια του χρήστη για να δουν οι πληροφορίες στη βάση δεδομένων, ο

κώδικας αφήνει την αλλαγή χρηστών οι πληροφορίες. Μετά από να υποβάλει τη νέα

χρησιμοποίηση πληροφοριών εκδώστε τις γραμμές που επιδεικνύονται στο σχήμα 6.3, ο χρήστης

χτυπά στο κουμπί αναπροσαρμογών. Το ίδιο servlet στη λίστα 6.3 καλείται, και ο διαφορετικός κώδικας εκτελείται για να ενημερώσει και το acc_acc και acc_add τους πίνακες. Το σχήμα 6.4 παρουσιάζει την παραγωγή πότε οι πίνακες ενημερώνονται επιτυχώς.

File Edit View Favorites

- e x

a S e e Account Information - Microsoft Internet Explorer

Earthlink

0°N

POP UP B lr X K O g C:\data\books\mysql and java\software\chapter 6\seeaccounts.html

Acciess

Links β ] Customize links g ] Free Hotmail g ] Windows

Enter account number to view:

s u b m it

j1034055|

S J My Computer e ] D o n e

Σχήμα 6.2 Αρχική ιστοσελίδας HTML μας

Σχήμα 6.3 Οι πληροφορίες επιστρέφονται από τη βάση δεδομένων μας

Σχήμα 6.4 Η αναπροσαρμογή ήταν επιτυχής

Σύνδεση με τη Βάση Δεδομένων

Κοιτάξτε προσεκτικά το σχήμα του 6.3, 6.4 , και θα παρατηρήσετε ότι χρειαζόμαστε να πάρουμε πληροφορίες και από τους δύο τους πίνακες, το acc_acc και το acc_add, με σκοπό, να παρουσιάσουμε τις απαραίτητες πληροφορίες στην επιστρεφόμενη σελίδα της HTML. Ευτυχώς, και οι δυο από αυτούς τους πίνακες είναι καθορισμένοι εντός των λογαριασμών του DATABASE στον δικό μας βοηθό της MySQL. Έτσι, θα συνδεθούμε με τον βοηθό και θα αλλάξουμε, ή θα χρησιμοποιήσουμε τον λογαριασμό του DATABASE. Ο κώδικας της πλήρης σύνδεσης, βρίσκεται σε δύο αναφορές:

Class.jorName(“com.mysql.jdbc.Driver”);

connection = DriverManager.getConnectiorL(

“jdbc:mysql://localhost/ accounts ”);