Documente Academic
Documente Profesional
Documente Cultură
Unul dintre cele mai folosite servicii Internet este serviciul Web.
Caracteristici:
Browser-ul:
Generaliti:
Sintaxa general
Tabelul 1.1
PROTOCOL DESCRIERE MOD DE LUCRU
HTTP Protocol de transfer http://host[:port][/cale][?cautare]
hipertexte
FTP Protocol de transfer de ftp://[user[:parola]@]host/cale
fiiere
MAILTO Adresa de E-mail mailto:user@host
NEWS tiri Usenet news:grup-discutii
NNTP tiri Usenet pentru acces nntp:grup/cifre
local NNTP
FILE Acces la fiiere file://host/cale
TELNET Referire la o sesiune telnet://host[:port]
interactiv
Tipuri de URLuri:
Termeni UR*:
Caracteristici:
Este cel mai important i cel mai des folosit protocol al Reelei
Mondiale (Web).
Este un protocol rapid, special proiectat pentru mediul interactiv,
hipermedia din Web.
Este un protocol de nivel aplicaie, ce ofer uurina i viteza
necesare dezvoltrii aplicaiilor hipermedia.
Este un protocol generic, orientat obiect, care poate fi folosit cu
uurin de multe task-uri, cum ar fi servere de nume i sisteme
de management distribuit, cu extensiile cerute de metodele sale.
Permite tiprirea i negocierea reprezentrii datelor, construirea
de sisteme independente de date care vor fi transferate.
Este orientat pe conexiune i asigur recepionarea sigur a
pachetelor de date, oferind i o metod de control al fluxului
ntre hosturile surs i destinaie.
Este construit peste serviciile protocolului TCP/IP, care
garanteaz c datele au fost recepionate corect, nu au fost
pierdute, duplicate sau recepionate n alt ordine fa de cea n
care au fost transmise. Procesul de recepie are controlul asupra
vitezei la care se recepioneaz i se transmit datele, prin
mecanismul de fereastr glisant.
Cnd se starteaz o aplicaie, modulul HTTP al calculatorului-
client i modulul HTTP al calculatorului-server ncep s
comunice unul cu altul.
Aceste dou module (client i server) conin informaii de stare
care definesc un circuit virtual. Acest circuit virtual consum
resursele att ale serverului, ct i ale clientului. Circuitul virtual
este full-duplex, datele pot circula n ambele direcii simultan.
2 FTP i pota electronic
2.1 Serviciul FTP - Transfer de fiiere
Caracteristici:
Permite transferul fiierelor de orice tip (fie ele binare sau de
tip text) ntre dou calculatoare din Internet.
Este bazat pe un sistem de autentificare a utilizatorilor.
Exist servere publice, sau cele care ofer FTP anonim.
Exist un cont special, numit anonymous (sau ftp), care nu
este protejat prin parol i pentru care majoritatea serverelor
moderne cer introducerea ca parol a adresei de pot
electronic a utilizatorului client.
n mod normal, pentru accesul la documentele de pe un server
FTP, un utilizator trebuie s dein un nume de cont i o
parol valid pentru respectivul server.
Parola este transmis n clar prin reea, permind oricrui
utilizator local care are acces la un program de monitorizare a
reelei s o afle. Din acest motiv, transferul de informaii prin
FTP se va efectua doar n zone n care se tie c nu este
posibil monitorizarea reelelor de ctre orice utilizator. O alt
posibilitate este folosirea de clieni sau servere modificate,
astfel nct transferul s se realizeze prin canale sigure (de
exemplu, folosind SSL - Secure Sockets Layer).
Browserele cunosc nativ i protocolul FTP (schema URL este:
ftp://[cont@]server.domeniu/ ).
Protocolul este FTP (File Transfer Protocol) i este specificat
n RFC 454.
Funcioneaz pe modelul client-server.
Caracteristici:
Importana serviciului FTP este indicat i de faptul c toate
sistemele Unix sunt instalate cu un set de programe client i
server.
Reele de calculatoare
Utilizeaz 2 porturi:
portul 21 - pe care se transmit comenzile de la client la
server;
portul 20 - de pe care serverul iniiaz conexiunea pe
care se va face transferul de informaie.
Andrei Bogdan
POP, IMAP
SMTP
SMTP
Agent postal (MTA) Agent postal (MTA)
Cutie postala pentru Andrei Cutie postala pentru Bogdan
folosete o baz de date, din care afl cum trebuie s prelucreze mesajul.
Fiecare intrare n baza de date, numit list potal (mailing list) are propria
sa adres potal i conine o mulime de adrese. La sosirea unei scrisori,
programul examineaz adresa de destinaie i determin dac aceasta
corespunde unei liste potale. Dac da, atunci programul retransmite o copie
a mesajului ctre fiecare adres din list.
Programul de retransmitere consum resurse importante (memorie i
timp). De aceea el este gzduit de un sistem care ofer aceste resurse, numit
poart potal (e-mail gateway). Listele pstrate de porile potale sunt, de
obicei, publice.
Mesajele de pot electronic sunt compuse din trei pri, primele
dou fiind descrise n cadrul RFC 822:
antet: zon care cuprinde informaiile de control ale mesajului
(adresele emitorului i receptorilor, data expedierii, traseul mesajului
etc.);
mesaj: cuprinde mesajul propriu-zis;
fiiere ataate: sunt de regul binare i nsoesc mesajul principal.
Servicii de directoare:
LDAP (Lightweight Directory Access Protocol) - protocol uor de
acces la cataloage.
Serviciul de directoare este folosit, n special, n legtur cu
sistemul de pot electronic deoarece i furnizeaz acestuia att
adrese, ct i certificate necesare pentru criptarea i semnarea
mesajelor de pot.
Se poate construi o agend cu informaii despre persoanele
implicate n sistemul de pot, printr-un serviciu centralizat de
directoare i clieni LDAP (att Netscape, ct i Microsoft au
adoptat LDAP).
Caracteristici MIME:
MIME (Multipurpose Internet Mail Extensions) - standard definit
pe parcursul a mai multor documente RFC: 1521, 2045, 2046,
2047, 2048 i 2049.
Reele de calculatoare
Tipuri/subtipuri MIME
Tabel 2.1
Tip/subtip Tipul informaiei asociate
MIME
text/plain Informaie de tip text care nu necesit interpretri
speciale
text/html Document ce conine o pagin HTML
image/gif Document de tip imagine codificat conform
standardului GIF
image/jpeg Document de tip imagine codificat conform
standardului JPEG
application/octet- Fiier binar, cu tip nespecificat, care trebuie tratat ca un
stream ir de octei
video/mpeg Film codificat conform standardului MPEG
2.3 Exerciii
3.1 Introducere
3.2 IIS
Elemente de securitate:
Administrare:
3.4 NCSA
Caracteristici NCSA:
Exemplu:
3.5 Apache
Caracteristici:
Versiuni sub SO Unix (/var/apache/) i SO Windows
(c:\Apache\); structur de directoare (asemntoare cu NCSA).
Exemplificai pentru Apache sub SO Windows i sub SO Unix.
Fiiere de configurare (asemntoare cu NCSA). Exemplificai
pentru Apache sub SO Windows i sub SO Unix.
Reele de calculatoare
4. Configurare:
a. Vizualizati si modificati fiierul httpd.conf, astfel nct
home-ul pentru utilizatori s fie: c:\stud_document\ (exp:
Alias /users "F:\users" ).
b. Ce module sunt ncrcate? Cum se pot ncrca celelalte? (-V,
-l).
c. Verificai dac este portul 8080 ocupat.
d. Verificai dac programul apache este pornit ca proces sau
serviciu.
e. Vizualizai structura de directori ai serverului apache. Intrai
n directorul bin.
f. Verificai ce opiuni avei din linie de comand pentru
comanda apache (apache -?).
g. Verificai configuraia (apache t). Accesai paginile noului
server.
h. Pornii serverul apache ca proces din linie de comand (nu din
meniu).
i. Testai-l pe default, ct i pentru un alt director.
j. Pornii serverul apache ca serviciu. Verificai existena
serviciului.
k. Punei n cgi-bin un script care s v afieze un contor pe
pagina voastr.
l. Verificai noul server de Web de pe acest port (apache t;
netstat -a).
m. Documentai-v n legtur cu porturile unui sistem, care sunt
ocupate, pe care le putei folosi ca utilizator privilegiat i ca
utilizator obinuit.
n. Creai un nou fiier de configurare (alt nume, alt port). Pornii
serverul cu acest fiier nou i testai-l (f file_name).
o. Intrai cu cont i parol pe directorul vostru virtual.
i. Editai httpd.conf, modificai denumirea fiierelor
.htaccess, .htpasswd:
<Directory "F:\users">
AllowOverride AuthConfig
Options None
Order allow,deny
Allow from all
</Directory>
ii. Atenie la aspectele de securitate:
<Files ~ "^htaccess">
Order allow,deny
Reele de calculatoare
<Directory "F:\users">
AllowOverride AuthConfig
Options None
Order allow,deny
Allow from all
</Directory>
4 Utilitare TCP/IP
Tabel 4.2
Utilitar Descriere
FTP Faciliteaz transferul bidirecional de fiiere ntre un computer
pe care ruleaz Windows i un server FTP (de exemplu,
Windows 2000 Server).
TFTP Faciliteaz transferul bidirecional de fiiere ntre un computer
pe care ruleaz Windows i un server TFTP.
Telnet Ofer o conexiune la un computer ce suport protocolul telnet.
Sistemele de operare Microsoft nu ofer suport dect pentru
clieni telnet.
RCP Copiaz fiiere ntre un computer cu Windows i unul ce ofer
suport pentru RCP (Remote Copy Protocol), de exemplu un
computer pe care ruleaz UNIX.
RSH Ruleaz comenzi pe un computer pe care este instalat UNIX.
REXEC Ruleaz un proces pe un computer aflat la distan.
Utilitarul ipconfig
Ipconfig se folosete pentru verificarea configuraiei protocolului
TCP/IP. Pentru afiarea tuturor informaiilor disponibile, se folosete
parametrul /all.
Rezultatul tastrii comenzii ipconfig /all este urmtorul:
Dac este setat o configuraie valid, este afiat adresa IP i
masca de subreea, precum i gateway-ul implicit, dac este
cazul.
Dac este detectat n reea un duplicat al adresei IP folosite, va
fi afiat adresa IP folosit, dar n dreptul mtii de subreea
se va trece 0.0.0.0.
Dac Windows nu a putut obine o adres IP de la un server
DHCP, va fi afiat adresa alocat prin tehnologia APIPA.
Utilitarul ping
Utilitarul finger
Utilitarul netstat
Utilitarul traceroute
Utilitarul arp
Opiuni:
-a Afieaz toate intrrile din tabele ARP curent
-d nume terge intrrile corespunztoare din tabela
ARP
-s adres host Creaz o nou intrare n tabela ARP folosind o
adres Ethernet
n general, dac acest ultim pas reuete, atunci ceilali pai sunt
inutili. Totui, n cazul n care nu reuete, va trebuie s urmai succesiunea
de pai de mai sus pentru a putea localiza problema.
Utilitare TCP/IP
Caracteristici adrese
Tabel 5.2
Clas Numr de octei-bii Numr de octei-bii Numrul de
utilizai pentru a utilizai pentru a adrese
identifica reeaua identifica interfaa asignabile pe
reea*
24
A 1 (8) 3 (24) 2 -2
B 2 (16) 2 (16) 216 - 2
C 3 (24) 1 (8) 28 - 2
*Exist dou adrese rezervate pentru fiecare reea.
Marje adrese IP
Tabel 5.3
Clas Valoarea Adrese de reea Numr de Numrul de
primului valide adrese de adrese
octet reea valide asignabile pe
reea
A 1 - 126 1.0.0.0 126.0.0.0 27 2 224 - 2
B 128 191 128.1.0.0 214 2 216 - 2
191.254.0.0
C 192 - 223 192.0.1.0 221 2 28 - 2
223.255.254.0
8 24-x x
16 16-x x
24 8-x x
Adresa: 134.141.7.11 1000 0110 1000 1101 0000 0111 0000 1011
Masca de 255.255.255.0 1111 1111 1111 1111 1111 1111 0000 0000
reea:
Rezultatul: 134.141.7.0 1000 0110 1000 1101 0000 0111 0000 0000
innd cont c este vorba despre o adres de clas C, iar masca este
255.255.255.0, rezult c nu se utilizeaz mprirea n subreele.
Adresa: 193.193.7.7 1100 0001 1100 0001 0000 0111 0000 0111
Masca de 255.255.255.0 1111 1111 1111 1111 1111 1111 0000 0000
reea:
Rezultatul: 193.193.7.7 1100 0001 1100 0001 0000 0111 0000 0111
Ruterul A
Ruterul B Ruterul C
Rezolvare
Masca trebuie s aib minim 8 bii pentru host. Dac am avea 7 bii
pentru host ar nsemna c am putea identifica 27 -2 (126) interfee, ceea ce ar
fi insuficient pentru a acoperi necesarul de 200 adrese. Numrul de subreele
necesar este 100, ceea ce implic un numr minim de apte bii rezervai,
deoarece 27 este cea mai mic putere a lui doi mai mare dect 100. Primii
16 bii vor avea valoarea 1, deoarece adresa indicat este de clas B. n
concluzie masca de subreea va avea urmtoarea form:
11111111 11111111 1111111X 00000000
Subreeaua 172.16.2.0/23
Ruterul A
Subreeaua 172.16.10.0/23
Ruterul B Ruterul C
6.1 Introducere
Caracteristici UDP:
Asigur servicii de tip datagram nivelului aplicaie;
Nu este fiabil (nu asigur certitudinea livrrii datagramelor,
nici mecanismele de protecie la pierderea sau duplicarea
datagramelor);
Vitez mare de transmisie;
Este un serviciu fr conexiune (emitorul nu cunoate starea
receptorului n momentul transmisiei);
Pentru transferul datelor folosete nite entiti abstracte,
numite porturi de protocol, identificate prin numere ntregi
pozitive i care au asociate nite cozi de mesaje prin care se
transmit mesajele;
Se utilizeaz pentru mesaje mici (sub 8KB) cu vitez mare;
Comunicaie client-server la nivel de socket
Primitive Descriere
send(socket, data, length, flags) transmite un mesaj
sendto(socket, length, flags, destaddress, transmite un mesaj folosind
addresslen) un socket neconectat
sendmsg(socket, msgstruct, flags)
recv(socket, buffer, length, flags) primete un mesaj
recvfrom(socket, buffer, length, flags, primete un mesaj pe un
sndaddr, saddrlen) socket neconectat
rcvmsg(socket, msgstruct, flags)
struct sockaddr_in
{
short int sin_family;
unsigned short int sin_port;
struct sin_addr;
unsigned char sin_zero[8]; //
};
Membrii:
sin_family corespunde cmpului sa_family din structura
sockaddr;
sin_port identific portul;
sin_addr identific adresa IP;
sin_zero[8] se iniializeaz cu 0.
#include <sys/types.h>
#include <sys/socket.h>
int socket (int domeniu, int tip, int protocol);
Parametrii funciei:
Domeniul de comunicaie poate fi setat cu valori de tipul
AF_ceva, cum ar fi: AF_UNIX stabilete domeniul de
comunicare local UNIX sau AF_INET utilizat pentru
comunicaii ntre procese aflate pe aceeai main sau pe
maini diferite, folosind stiva de protocoale TCP/IP
(domeniul Internet). Pentru exemplele curente vom utiliza
cea de-a doua variant. n acest caz, fiecare socket va avea
asociat o adres format din adresa IP a mainii gazd i un
numr de 16 bii, local gazdei respective, denumit port.
Tipul de socket utilizat: SOCK_STREAM (comunicarea se
va realiza full-duplex, sigur, orientat-conexiune prin flux
de date) sau SOCK_DGRAM (fr conexiune prin
datagrame). Se mai poate folosi i constanta SOCK_RAW care
ofer un acces la protocolul reea (protocolul IP), de nivel
inferior.
Protocol specific protocolul particular care va fi utilizat
pentru transmisia datelor. Acesta poate fi setat pe 0 pentru
ca funcia s-i poat alege protocolul corect automat. De
exemplu, pentru domeniul AF_INET i tipul SOCK_STREAM
se va considera protocolul de transport TCP, iar pentru cazul n
Comunicaie client-server la nivel de socket
getprotobyname ()
socket()
bind() ge thostbyname()
listen() ge tprotobyname()
stabilire conexiune
conne ct()
read() write ()
ce rere
write() read()
rspuns
close() close ()
Clientul apeleaz:
gethostbyname() pentru a converti numele unui calculator n
adresa IP;
getprotobyname() pentru a converti numele unui protocol n
forma binar folosit de sockets;
socket() pentru a crea un socket;
connect() pentru a conecta socket-ul la un server;
Reele de calculatoare
Serverul apeleaz:
getprotobyname() pentru a converti numele unui protocol n
forma binar folosit de sockets;
socket() pentru a crea un socket;
bind() pentru a specifica portul local pentru socket;
listen() pentru a plasa socket-ul n modul pasiv, apoi n bucl;
accept() pentru a accepta o cerere de conectare i a crea un
socket nou pentru aceast conexiune;
send() pentru a trimite date;
close() pentru a nchide noul socket.
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
Parametri:
sockfd este descriptorul de socket
my_addr este un pointer la structura ce conine informaii
referitoare la adres
addrlen poate fi setat la valoarea sizeof(struct sockaddr)
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MYPORT 3490
main()
Comunicaie client-server la nivel de socket
{
int sockfd;
struct sockaddr_in my_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
my_addr.sin_family = AF_INET; // little endian
my_addr.sin_port = htons(MYPORT); // big endian
my_addr.sin_addr.s_addr = inet_addr("10.12.110.57");
memset(&(my_addr.sin_zero), '\0', 8); // iniializare cu 0 a structurii
bind(sockfd, (struct sockaddr *)&my_addr, sizeof (struct sockaddr)) ;
.................
}
Parametri:
sockfd este descriptorul de socket;
backlog reprezint numrul maxim de conecii permise n
coada de ateptare.
Parametri:
sockfd este descriptorul de socket
msg reprezint o zon de memorie n care se afl datele ce
trebuie trimise
len reprezint lungimea datelor n octei
flags este de obicei setat pe 0
Parametri:
sockfd este descriptorul de socket;
msg reprezint o zon de memorie n care se vor copia datele
recepionate;
len reprezint mrimea acestor date n octei;
flags este de obicei 0 sau setat la valoarea MSG_PEEK, dac
datele recepionate trebuie reinute i dup ce sunt
recepionate;
socket() socket()
bind() bind()
cerere
recvfrom() sendto()
rspuns
sendto() recvfrom()
close() close()
Parametrii funciei:
sockfd este descriptorul de socket;
msg reprezint o zon de memorie n care se afl datele ce
trebuie trimise;
flags va fi iniializat cu 0
len reprezint lungimea datelor ce vor fi trimise;
to reprezint un pointer la o structur de tip sockaddr i
conine adresa de IP i portul destinaiei;
tolen va fi iniializat cu valoarea sizeof(struct sockaddr).
Parametrii funciei:
sockfd este descriptorul de socket;
msg reprezint o zon de memorie n care se afl datele ce
sunt primite;
flags va fi iniializat cu 0;
len reprezint lungimea datelor primite;
from reprezint un pointer la o structur de tip sockaddr i
conine adresa de IP i portul sursei;
fromlen va fi iniializat cu valoarea sizeof(struct sockaddr)
6.3 Exemplificri
/* SERVER TCP */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
Comunicaie client-server la nivel de socket
/*Creeaza un socket*/
if ((s=socket(AF_INET, SOCK_STREAM, 0)) <0)
{
perror("Eroare la creare socket");
exit(3);
}
/* CLIENT TCP */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <netdb.h>
/* Confirmare de la server */
if (recv(s, buffer, 32, 0) < 0)
{
perror("Eroare la recepie");
exit(7);
}
close(s);
exit(0);
}
Comunicaie client-server la nivel de socket
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
main()
{
char buffer[32];
struct sockaddr_in client, server; /*adresele client, server*/
int s, rc, namelen;
/*Creeaz un socket*/
if ((s=socket(AF_INET, SOCK_DGRAM, 0)) <0)
{
perror("Eroare la creare socket");
exit(1);
}
printf("A creat socket-ul....\n");
{
perror("Eroare la determinarea portului");
exit(3);
}
namelen = sizeof(client);
close(s);
exit(0);
}
Reele de calculatoare
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <error.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
/* portul folosit */
const int PORT_SERVER = 9001;
/* numarul maxim de clieni acceptai */
const int CLIENTI_MAXIM = 10;
}
shutdown (dc, 2);
exit (errno);
}
/* programul principal */
int main ()
{
struct sockaddr_in server;
/* tratm semnalele */
if (signal (SIGCHLD, semnal) == SIG_ERR)
{
perror ("signal()") ;
exit (errno);
}
if (signal (SIGPIPE, SIG_IGN) == SIG_ERR)
{
perror ("signal()");
exit (errno);
}
/* crem socket-ul */
if ((ds = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket() ") ;
return errno;
}
/* pregtim structurile de date */
bzero (&server, sizeof (server));
server.sin_family = AF_INET;
server.sin_port = htons (PORT_SERVER);
server.sin.addr.s_addr = htonl (INADDR_ANY);
/* atam la port */
if (bind (ds, &server, sizeof (server)) == -1)
{
perror ("bind()");
return errno;
}
if (listen (ds, 5) == -1)
{
perror ("listen() ") ;
return errno;
}
Comunicaie client-server la nivel de socket
Obiecte Java
package tutorials.database.storedprocedure;
import java.io.Serializable;
public class Group implements Serializable {
public int GroupId;
public String Name;
public short Version;
}
package tutorials.database.storedprocedure;
import java.io.Serializable;
public class Student implements Serializable {
public int StudentId;
public String FirstName;
public String LastName;
public short Version;
}
Accesor
package tutorials.database.storedprocedure;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;
public class DataAccessor {
private Connection connection;
public void open(String host, int port, String database,
String user, String password) throws SQLException,
ClassNotFoundException {
Class.ForName("com.microsoft.jdbc.sqlserver.SQLServerDri
ver");
this.connection = DriverManager.getConnection(
Reele de calculatoare
namespace Tutorials.Database
{
internal interface IDatabaseConnection
{
void Open(string host, string database, string
user, string password);
System.Data.DataSet ExecuteQuery(string statement,
string table);
object ExecuteScalar(string statement);
int ExecuteNonQuery(string statement);
void Close();
string Provider
{
get;
}
string Database
{
get;
}
}
}
Reele de calculatoare
namespace Tutorials.Database
{
internal class SQLServerDatabaseConnection:
IDatabaseConnection
{
private System.Data.SqlClient.SqlConnection
connection;
private string database;
public SQLServerDatabaseConnection()
{
}
public void Open(string host, string database,
string user, string password)
{
this.connection = new
System.Data.SqlClient.SqlConnection("data source = " + host +
"; database = " + database + "; user id = " + user + ";
password = " + password);
this.connection.Open();
}
public System.Data.DataSet ExecuteQuery(string
statement, string table)
{
System.Data.DataSet dataSet = new
System.Data.DataSet();
new
System.Data.SqlClient.SqlDataAdapter(statement,
this.connection).Fill(dataSet, table);
return dataSet;
}
public object ExecuteScalar(string statement)
{
return new
System.Data.SqlClient.SqlCommand(statement,
this.connection).ExecuteScalar();
}
public int ExecuteNonQuery(string statement)
{
return new
System.Data.SqlClient.SqlCommand(statement,
this.connection).ExecuteNonQuery();
}
public void Close()
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
{
if(this.connection!=null)
this.connection.Close();
}
public string Provider
{
get
{
return "SQLServer";
}
}
public string Database
{
get
{
return this.database;
}
}
}
}
namespace Tutorials.Database
{
internal class OracleDatabaseConnection:
IDatabaseConnection
{
private System.Data.OracleClient.OracleConnection
connection;
private string database;
public OracleDatabaseConnection()
{
}
public void Open(string host, string database,
string user, string password)
{
this.connection = new
System.Data.OracleClient.OracleConnection("data source = " +
host + "; database = " + database + "; user id = " + user + ";
password = " + password);
this.connection.Open();
}
public System.Data.DataSet ExecuteQuery(string
statement, string table)
{
System.Data.DataSet dataSet=new
System.Data.DataSet();
Reele de calculatoare
new
System.Data.OracleClient.OracleDataAdapter(statement,
this.connection).Fill(dataSet, table);
return dataSet;
}
public object ExecuteScalar(string statement)
{
return new
System.Data.OracleClient.OracleCommand(statement,
this.connection).ExecuteScalar();
}
public int ExecuteNonQuery(string statement)
{
return new
System.Data.OracleClient.OracleCommand(statement,
this.connection).ExecuteNonQuery();
}
public void Close()
{
if(this.connection!=null)
this.connection.Close();
}
public string Provider
{
get
{
return "Oracle";
}
}
public string Database
{
get
{
return this.database;
}
}
}
}
namespace Tutorials.Database
{
internal class MySQLDatabaseConnection:
IDatabaseConnection
{
private ByteFX.Data.MySqlClient.MySqlConnection
connection;
private string database;
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
public MySQLDatabaseConnection()
{
}
public void Open(string host, string database,
string user, string password)
{
this.database = database;
this.connection = new
ByteFX.Data.MySqlClient.MySqlConnection(" data source =
"+host+";database = "+database+";user id = "+user+";password =
"+password);
this.connection.Open();
}
public System.Data.DataSet ExecuteQuery(string
statement,string table)
{
System.Data.DataSet dataSet=new
System.Data.DataSet();
new
ByteFX.Data.MySqlClient.MySqlDataAdapter(statement,this.connec
tion).Fill(dataSet, table);
return dataSet;
}
public object ExecuteScalar(string statement)
{
return new
ByteFX.Data.MySqlClient.MySqlCommand(statement,
this.connection).ExecuteScalar();
}
public int ExecuteNonQuery(string statement)
{
return new
ByteFX.Data.MySqlClient.MySqlCommand(statement,
this.connection).ExecuteNonQuery();
}
public void Close()
{
if(this.connection != null)
this.connection.Close();
}
public string Provider
{
get
{
return "MySQL";
}
}
public string Database
{
get
Reele de calculatoare
{
return this.database;
}
}
}
}
using System;
namespace Tutorials.Database
{
public enum Providers{Oracle, SqlServer, MySql}
public class DatabaseConnection
{
private IDatabaseConnection databaseConnection =
null;
public void Open(Providers provider, string host,
string database, string user, string password)
{
switch(provider)
{
case Providers.Oracle:
this.databaseConnection = new
OracleDatabaseConnection();
break;
case Providers.SqlServer:
this.databaseConnection = new
SQLServerDatabaseConnection();
break;
case Providers.MySql:
this.databaseConnection = new
MySQLDatabaseConnection();
default:
this.databaseConnection = null;
break;
}
if(this.databaseConnection != null)
this.databaseConnection.Open(host, database, user,
password);
}
public System.Data.DataSet ExecuteQuery(string
statement, string table)
{
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
Obiect de serviciu
using System;
namespace Tutorials.Remoting.Common
{
[Serializable]
public class Customer
{
public string FirstName;
public string LastName;
public DateTime DateOfBirth;
}
}
Interfa serviciu
namespace Tutorials.Remoting.Common
{
public interface ICustomerManager
{
Customer[] GetCustomers();
}
}
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using Tutorials.Remoting.Common;
namespace Tutorials.Remoting.Service
{
public class CustomerManager : MarshalByRefObject,
ICustomerManager
{
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
public CustomerManager()
{
Console.WriteLine("CustomerManager.constructor: Object
created");
}
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using Tutorials.Remoting.Service;
namespace Tutorials.Remoting.Server
{
class Server
{
[STAThread]
static void Main(string[] args)
{
HttpChannel channel = new HttpChannel(1979);
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(CustomerManager),
"CustomerManager.soap",
WellKnownObjectMode.Singleton);
Console.ReadLine();
}
Reele de calculatoare
}
}
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Channels;
using Tutorials.Remoting.Common;
namespace Tutorials.Remoting.Client
{
class Client
{
[STAThread]
static void Main(string[] args)
{
HttpChannel channel = new HttpChannel();
ChannelServices.RegisterChannel(channel);
ICustomerManager manager =
(ICustomerManager) Activator.GetObject(
typeof(ICustomerManager),
"http://localhost:1979/CustomerManager.soap");
Console.WriteLine("Client.Main(): Reference
to CustomerManager acquired");
Customer[] customers =
manager.GetCustomers();
foreach(Customer customer in customers)
Console.WriteLine("Customer:\n" +
"First Name:\t" +
customer.FirstName + "\n" +
"Last Name:\t" +
customer.LastName + "\n" +
"Day of Birth:\t" +
customer.DateOfBirth.ToString("dd\\.MM\\.yyyy") + "\n");
}
}
}
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
package tutorials.remoting;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IPrimeNumbers extends Remote {
public int[] getPrimeNumbers(int n)
throws RemoteException;
}
package tutorials.remoting;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class PrimeNumbers extends UnicastRemoteObject
implements IPrimeNumbers {
public PrimeNumbers()
throws RemoteException {
super();
}
public int[] getPrimeNumbers(int n)
throws RemoteException {
boolean[] isNotPrime = new boolean[n + 1];
int found = 0;
for(int i = 2; i <= n - 1; i++)
if(isNotPrime[i] == false)
{
found++;
for(int j = 2; j * i <= n; j++)
isNotPrime[j * i] = true;
}
int[] numbers = new int[found];
int k = 0;
for(int i = 2; i <= n; i++)
if(isNotPrime[i] == false)
numbers[k++] = i;
return numbers;
}
}
Reele de calculatoare
package tutorials.remoting;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
public class Server {
public static void main(String[] args) {
System.setSecurityManager(new
RMISecurityManager());
try {
PrimeNumbers primeNumbers = new
PrimeNumbers();
Naming.rebind("//remoting/PrimeNumbersServer",
primeNumbers);
}
catch(Exception exception) {
System.out.println(exception.toString());
}
}
}
package tutorials.remoting;
import java.rmi.Naming;
public class Client {
public static void main(String[] args) {
try {
PrimeNumbers primeNumbers = (PrimeNumbers)
Naming.lookup("rmi://remoting/PrimeNumbersService");
int n = args.length == 1 ?
Integer.parseInt(args[0]) : 1000;
int[] numbers =
primeNumbers.getPrimeNumbers(n);
String message = "";
for(int i = 0; i < numbers.length; i++)
message += (message.length() > 0 ? ",
" : "") + numbers[i];
System.out.println(message);
}
catch(Exception exception) {
System.out.println(exception.toString());
}
}
}
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
using System;
using System.Xml.Serialization;
namespace Tutorials.ComplexTypeServices.Service
{
[XmlRoot(Namespace = "http://aris.ase.ro/schemas")]
public class Contact
{
[XmlElement("FirstName")]
public string FirstName;
[XmlElement("LastName")]
public string LastName;
[XmlElement("Email")]
public string Email;
}
}
package tutorials.services.complextype;
import java.io.Serializable;
public class Contact implements Serializable
{
public String FirstName;
public String LastName;
public String Email;
}
Serviciu C#
using System;
using System.Collections;
using System.ComponentModel;
Reele de calculatoare
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
namespace Tutorials.ComplexTypeServices.Service
{
[WebService(Namespace = "http://aris.ase.ro/schemas")]
public class ContactService :
System.Web.Services.WebService
{
public ContactService()
{
InitializeComponent();
}
#region Component Designer generated code
private IContainer components = null;
private void InitializeComponent()
{
}
protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion
[WebMethod]
public Contact[] GetContacts()
{
Contact[] contacts = new Contact[2];
contacts[0] = new Contact();
contacts[0].FirstName = "Iulian";
contacts[0].LastName = "Ilie-Nemedi";
contacts[0].Email = "iulian.nemedi@ase.ro";
contacts[1] = new Contact();
contacts[1].FirstName = "Radu";
contacts[1].LastName = "Constantinescu";
contacts[1].Email =
"radu.constantinescu@ase.ro";
return contacts;
}
}
}
package tutorials.services.complextype;
public interface IContactService {
public Contact[] getContacts();
}
Serviciu Java
package tutorials.services.complextype;
public class ContactService implements IContactService {
public Contact[] getContacts() {
Contact[] contacts = new Contact[2];
contacts[0] = new Contact();
contacts[0].FirstName = "Iulian";
contacts[0].LastName = "Ilie-Nemedi";
contacts[0].Email = "iulian.nemedi@ase.ro";
contacts[1] = new Contact();
contacts[1].FirstName = "Radu";
contacts[1].LastName = "Constantinescu";
contacts[1].Email = "radu.constantinescu@ase.ro";
return contacts;
}
}
{
class Client
{
[STAThread]
static void Main(string[] args)
{
ContactProxy.Contact[] contacts = new
ContactProxy.ContactService().GetContacts();
for(int i = 0; i < contacts.Length; i++)
Console.WriteLine("Contact:\n" +
"\tFirst Name: " + contacts[i].FirstName +
"\n" +
"\tLast Name: " + contacts[i].LastName +
"\n" +
"\tEmail: " + contacts[i].Email + "\n");
}
}
}
clientul Java are nevoie de o clas pentru reprezentarea obiectului
complex deserializat; pentru construirea acesteia platforma Glue
Professional ofer utilitarul schema2java;
apelarea din Java presupune importarea pachetelui cu definirea
tipului de date complex i a interfeei serviciu; clasa proxy se
obine prin apelul metodei statice
electric.revistry.Registry.bind:
Client Java
package tutorials.services.complextype;
import electric.registry.Registry;
import electric.registry.RegistryException;
public class Client {
public static void main(String[] args)
throws RegistryException {
IContactService proxy = (IContactService)
Registry.bind(args[0], IContactService.class);
Contact[] contacts = proxy.getContacts();
for(int i = 0; i < contacts.length; i++)
System.out.println("Contact:\n" +
"\tFirst Name: " + contacts[i].FirstName +
"\n" +
"\tLast Name: " + contacts[i].LastName +
"\n" +
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
Serviciu C#
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
namespace Tutorials.AsyncCallService.Service
{
[WebService(Namespace = "http://aris.ase.ro/schemas")]
public class PrimeNumbersService :
System.Web.Services.WebService
{
public PrimeNumbersService()
{
InitializeComponent();
}
Reele de calculatoare
package tutorials.services.asynccall;
public interface IPrimeNumbersService {
public int[] getPrimeNumbers(int n);
}
Serviciu Java
package tutorials.services.asynccall;
public class PrimeNumbersService implements
IPrimeNumbersService {
public int[] getPrimeNumbers(int n) {
boolean[] isNotPrime = new boolean[n + 1];
int found = 0;
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
Metoda clientului C#
this.numbers[i].ToString();
Console.WriteLine(message);
}
this.service.BeginGetPrimeNumbers(n, new
AsyncCallback(this.LoadComplete), null);
Client Java
package tutorials.services.asynccall;
import electric.registry.Registry;
import electric.registry.RegistryException;
public class Client
{
public static void main(String[] args) throws
RegistryException
{
String url =
"jms://AsyncCallService/PrimeNumbersService.wsdl";
IPrimeNumbersService proxy =
(IPrimeNumbersService) Registry.bind(url,
IPrimeNumbersService.class);
int n = args.length == 1 ?
Integer.parseInt(args[0]) : 1000;
int[] numbers = proxy.getPrimeNumbers(n);
String message = "";
for(int i = 0; i < numbers.length; i++)
message += (message.length() > 0 ? ", " :
"") + numbers[i];
System.out.println(message);
}
}
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
Obiectul tranzaciei
using System.Xml.Serialization;
namespace Tutorials.ServicedComponents.Common
{
[XmlRoot("Order", Namespace =
"http://aris.ase.ro/schemas")]
public class Order
{
[XmlElement("Product", typeof(string))]
public string Product;
[XmlElement("Quantity", typeof(int))]
public int Quentity;
}
}
Interfaa de apel
namespace Tutorials.ServicedComponents.Common
{
public interface IDeliveryService
{
bool PlaceOrder(Order order);
}
}
Component de serviciu
using System;
using System.EnterpriseServices;
Reele de calculatoare
namespace Tutorials.ServicedComponents
{
[Transaction(TransactionOption.Required)]
[JustInTimeActivation(true)]
public class DeliveryService : ServicedComponent,
Common.IDeliveryService
{
Descriptor Web
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
namespace Tutorials.ServicedComponents.Client
{
class Client
{
[STAThread]
static void Main(string[] args)
{
try
{
HttpChannel channel = new
HttpChannel();
ChannelServices.RegisterChannel(channel);
Common.IDeliveryService service =
(Common.IDeliveryService)
Activator.GetObject(typeof(Common.IDeliveryService),
"http://localhost/ServicedComponents/DeliveryService.SOAP");
Common.Order order = new
Common.Order();
order.Product = "A Product";
order.Quentity = 1;
Console.WriteLine(service.PlaceOrder(order) ?
"Your order has been placed." :
"Your order has been rejected.");
}
catch(Exception exception)
{
Console.WriteLine(exception.ToString());
}
}
}
}
<load-on-startup>1</load-on-startup>
</servlet>
de asemenea, tot n fiierul web.xml este configurat i procesorul
de servicii SOAPServletContext;
n subdirectorul services din WEB-INF se creeaz cte un
descriptor XML pentru fiecare serviciu gzduit de aplicaia
curent, avnd drept model fiierul sample.xml; n cazul
publicrii unei componente EJB ca serviciu Web fiierul
descriptor are urmtoare form:
<?xml version='1.0'?>
<service>
<constructor>
<class>electric.service.ejb.StatelessSessionBeanService</class
>
<args>
<contextFactory>org.jnp.interfaces.NamingContextFactory</conte
xtFactory>
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
<url>jnp://localhost:1099</url>
<jndiName>ejb/Exchange</jndiName>
<homeInterfaceName>tutorials.ejbstaff.interfaces.ExchangeHome<
/homeInterfaceName>
</args>
</constructor>
</service>
package tutorials.ejbstaff.client;
public interface IExchange {
public double getRate(String county1, String country2);
}
Client Java
package tutorials.ejbstaff.client;
import electric.registry.Registry;
public class Client {
public static void main(String[] args) {
try {
String url = args[0];
IExchange exchange = (IExchange)
Registry.bind(url, IExchange.class);
double rate = exchange.getRate("usa",
"japan");
System.out.println("usa/japan exchange rate
= " + rate);
}
catch(Exception exception) {
System.out.println(exception.toString());
}
}
}
Reele de calculatoare
Client J#
package Tutorials.EjbStaff.NETClient;
public class Client
{
/** @attribute System.STAThread() */
public static void main(String[] args)
{
EjbService.Exchange exchange = new
EjbService.Exchange();
double rate = exchange.getRate("usa", "japan");
System.out.println("usa/japan exchange rate = " +
rate);
}
}
package tutorials.services.virtual;
public class Exchange implements IExchange {
public double getRate(String country1, String country2)
{
return Math.random() * 100;
}
}
package tutorials.services.virtual;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ExchangeHandler implements InvocationHandler {
private IExchange exchange = new Exchange();
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
return method.invoke(exchange, args);
}
}
package tutorials.services.virtual;
import java.rmi.RemoteException;
import electric.xml.Element;
import electric.xml.XPath;
import electric.xml.io.encoded.EncodedWriter;
import electric.SOAP.ISOAPHandler;
import electric.SOAP.SOAPMessage;
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
import electric.util.Context;
public class ExchangeSOAPHandler implements ISOAPHandler {
static final XPath country1 = new XPath("getRate/[1]");
static final XPath country2 = new XPath("getRate/[2]");
public SOAPMessage handle(SOAPMessage request, Context
context)
throws RemoteException, SecurityException {
String arg0 =
request.getBody().getElement(country1).getString();
String arg1 =
request.getBody().getElement(country2).getString();
SOAPMessage response = new SOAPMessage();
Element body = response.addBody();
Element result = body.addElement();
result.setNamespace("n",
"http://tempuri.org/examples.publish.IExchange");
result.setName("n", "getRateResponse");
EncodedWriter writer = new EncodedWriter(result);
writer.writeDouble("Result", Math.random() * 100);
return response;
}
}
package tutorials.services.virtual;
import electric.registry.Registry;
import electric.server.http.HTTP;
import electric.SOAP.virtual.VirtualSOAPHandler;
public class ExchangeSOAPPublish
{
public static void main(String[] args) throws Exception
{
HTTP.startup("http://localhost:8004/glue");
ExchangeHandler invokeHandler = new
ExchangeHandler();
ExchangeSOAPHandler SOAPHandler = new
ExchangeSOAPHandler();
VirtualSOAPHandler exchange = new
VirtualSOAPHandler(IExchange.class,
invokeHandler,
SOAPHandler);
Registry.publish("exchange", exchange);
}
}
Reele de calculatoare
<publish>yes</publish>
<role>denumire_rol</role>
se editeaz fiierul WEB-INF/web.xml n care se precizeaz
metoda de autentificare:
<login-config>
<realm-name>acl</realm-name>
</login-config>
Pentru autentificarea apelului la un serviciu Web securizat se utilizeaz
obiectul ProxyContext care va fi ncrcat cu datele de autentificare ale
utilizatorului declarat n fiierele de configurare, astfel:
ProxyContext context = new ProxyContext();
context.setAuthUser("denumire_rol");
context.setAuthPassword("parol");
ISample sample = (ISample) Registry.bind(ur_wsdll,
ISample.class, context);
Clasa paginii
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;
namespace Tutorials.AspNet
{
public class RoomImage : System.Web.UI.Page
{
private void Page_Load(object sender,
System.EventArgs e)
{
if(this.Request["RoomId"]!=null)
{
this.Response.ContentType =
"image/jpg";
Administrator.AdministratorService
service = new Administrator.AdministratorService();
byte[] image =
service.GetRoomImageData(int.Parse(this.Request["RoomId"]));
if(image == null)
{
FileStream fileStream = new
FileStream(this.Server.MapPath("tmp/admin_no_image.jpg"),
FileMode.Open);
image = new byte[new
FileInfo(this.Server.MapPath("tmp/admin_no_image.jpg")).Length
];
fileStream.Read(image, 0,
image.Length);
fileStream.Close();
}
Reele de calculatoare
this.Response.OutputStream.Write(image, 0,
image.Length);
}
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Load += new
System.EventHandler(this.Page_Load);
}
#endregion
}
}
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import tutorial.interfaces.Fibo;
import tutorial.interfaces.FiboHome;
/**
* @web.servlet name="Compute" display-name="Computation
Servlet"
* description="Servlet that compute Fibonacci
suite"
*
* @web.servlet-mapping url-pattern="/Compute"
*
* @web.ejb-ref name="ejb/Fibo" type="Session"
* home="tutorial.interfaces.FiboHome"
* remote="tutorial.interfaces.Fibo"
description="Reference to the
* Fibo EJB"
*
* @jboss.ejb-ref-jndi ref-name="ejb/Fibo" jndi-
name="ejb/Fibo"
*/
public class ComputeServlet extends HttpServlet {
private FiboHome home;
public ComputeServlet()
{
super();
}
public void init(ServletConfig config)
throws ServletException {
try {
Context context = new InitialContext();
Object ref =
context.lookup("java:/comp/env/ejb/Fibo");
home = (FiboHome)
PortableRemoteObject.narrow(ref, FiboHome.class);
}
catch (Exception e) {
throw new ServletException("Lookup of
java:/comp/env/ failed");
}
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
Reele de calculatoare
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><head><title>");
out.println("Fibonaci Computation");
out.println("</title></head>");
out.println("<body>");
out.println("<h1>");
out.println("Fibonaci Computation");
out.println("</h1>");
try {
Fibo bean = home.create();
int limit = 0;
String value =
request.getParameter("limit");
if (value != null) {
try {
limit = Integer.parseInt(value);
}
catch (Exception e)
{
}
}
double[] result = bean.compute(limit);
bean.remove();
out.println("<p>");
out.print("The ");
out.print(limit);
out.print(" first Fibonacci numbers ");
for (int i = 0; i < result.length; i++) {
out.println("<br>");
out.println(i);
out.println(" : ");
out.println(result[i]);
}
out.println("</p>");
}
catch(Exception e) {
out.println(e.getMessage());
e.printStackTrace(out);
}
finally {
out.println("</body></html>");
out.close();
}
}
}
Implementarea aplicaiilor distribuite pe platformele .NET i J2EE
package tutorials.customtags;
import java.io.IOException;
import java.util.Random;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
public class SimpleRandomTag extends TagSupport {
protected int length;
public int doStartTag() {
try {
JspWriter out = this.pageContext.getOut();
out.print(new
Random().nextInt(this.length));
}
catch(IOException exception) {
System.out.println(exception.toString());
}
return SKIP_BODY;
}
}
<tagclass>tutorials.customtags.SimpleRandomTag</tagclass>
<info>Outputs a random integer.</info>
</tag>
</taglib>
<prefix:tagName />
<customjsp:simpleRandom />
Acest mecanism poate fi extins sub forma unui custom tag cu atribute i
coninut:
se declar n handler-ul tag-ului proprieti pentru fiecare atribut
al su;
setarea unui atribut n cadrul tag-ului echivaleaz cu apelarea
metodei setter a obiectului handler;
se declar atributul n descriptorul tag-ului
Reele de calculatoare
Custom Tag care extinde un tag simplu prin adugarea unui atribut
package tutorials.customtags;
public class RandomTag extends SimpleRandomTag {
public void setLength(int length)
{
this.length = length;
}
}
<tag>
<name>random</name>
<tagclass>tutorials.customtags.RandomTag</tagclass>
<attribute>
<name>length</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
servicii Web:
se remarc drept varianta optim de interoperabilitate pentru
cele mai multe situaii datorit cuplrii slabe, n condiiile
executrii de operaii sincrone, ct i asincrone, fr restricii
de tip Firewall sau conversii de protocoale de comunicaie;
pn n prezent are totui dezavantajul implementrii pariale
a standardelor pentru securitate, dar mai ales pentru tranzacii.
Dezvoltarea modelului GXA (Global XML Web Services
Architecture) intenioneaz s nlture aceste neajunsuri prin
protocoale de tipul WS-Security, WS-Attachement sau
WS-Routing.