Java wybrane technologie spotkanie nr 2 JavaMail 1
Wprowadzenie JavaMail 1.4 (opiera się na JavaBean Activation Framework (JAF) 1.1) odbieranie, tworzenie i wysyłanie wiadomości elektronicznych dla twórców Mail User Agent (MUA), a nie Mail Transfer Agent (MTA) wiele protokołów obsługiwanych w jeden sposób opcjonalny pakiet do Java SE, zawiera się w Java EE od kwietnia 2006 implementacja SUNowska jest dostępna na licencji CDDl jest też otwarta implementacja JavaMail 1.3 na licencji GNU 2
Jak działa poczta? 3
Podział specyfikacji wysyłanie i odbieranie wiadomości w sposób niezależny od konkretnego protokołu podłączanie kolejnych protokołów 4
Protokoły Simple Mail Transfer Protocol (SMTP) nie radzi sobie dobrze z plikami binarnymi (dlatego powstało MIME) nie weryfikuje nadawcy serwer SMTP może wymagać uwierzytelnienia 5
S: 220 www.example.com ESMTP Postfix C: HELO mydomain.com S: 250 Hello mydomain.com C: MAIL FROM:<sender@mydomain.com> S: 250 Ok C: RCPT TO:<friend@example.com> S: 250 Ok C: DATA S: 354 End data with <CR><LF>.<CR><LF> C: Subject: test message C: From: sender@mydomain.com C: To: friend@example.com C: C: Hello, C: This is a test. C: Goodbye. C:. S: 250 Ok: queued as 12345 C: QUIT S: 221 Bye 6
Protokoły c.d. Post Office Protocol (POP) kolejkuje wiadomości dla osób, które nie mogą być bez przerwy w sieci i odbierać poczty przy pomocy SMTP zazwyczaj wiadomości są pobierane i kasowane z serwera i przetwarzane na komputerze klienta (resztę symulują programy pocztowe) każdy list musi być pobierany razem z załącznikami i jego części nie można w łatwy sposób pomijać nie ma możliwości przeszukiwania kolejki jest propozycja POP4 z m.in. podstawowymi folderami i flagowaniem wiadomości Internet Message Access Protocol (IMAP) Multipurpose Internet Mail Extension (MIME) i inne 7
S: <wait for connection on TCP port 110> C: <open connection> S: +OK POP3 server ready <1896.697170952@dbc.mtview.ca.us> C: USER mrose S +OK User accepted C: PASS mrosepass S +OK Pass accepted C: STAT S: +OK 2 320 C: LIST S: +OK 2 messages (320 octets) S: 1 120 S: 2 200 S:. C: RETR 1 S: +OK 120 octets S: <the POP3 server sends message 1> S:. C: DELE 1 S: +OK message 1 deleted C: RETR 2 S: +OK 200 octets S: <the POP3 server sends message 2> S:. C: DELE 2 S: +OK message 2 deleted C: QUIT S: +OK dewey POP3 server signing off (maildrop empty) C: <close connection> S: <wait for next connection> Opracował 8
Najważniejsze klasy z javax.mail Session Message Address Authenticator Transport Store Folder używa się też klasy z javax.mail.internet 9
Wysyłanie wiadomości 10
javax.mail.session zawiera dane konfiguracyjne, np. dostępne klasy transport provider ma prywatne konstruktory, tworzymy przy pomocy Fabryki Properties props = new Properties(); //wypełniamy informacje o serwerze, użytkowniku, haśle, itp. Session session = Session.getDefaultInstance(props, null); lub Properties props = new Properties(); //wypełniamy informacje o serwerze, użytkowniku, haśle, itp. Session session = Session.getInstance(props, null); drugi parametr to obiekt Authenticator zazwyczaj można współdzielić sesję (nawet pracując na wielu skrzynkach); wtedy użytkownika i hasło podaje się podczas komunikacji 11
javax.mail.message klasa abstrakcyjna należy korzystać z javax.mail.internet.mimemessage w nagłówkach należy używać jedynie znaczki US ASCII, chociaż w niektórych inne znaczki są odpowiednio kodowane MimeMessage message = new MimeMessage(session); Message implementuje Part, a MimeMessage implementuje MimePart //message.setcontent("test 1, 2, 3", text/plain ); message.settext("test 1, 2, 3");//skrót dla wiad. tekstowych message.setsubject("wiadomość testowa"); 12
javax.mail.address klasa abstrakcyjna należy korzystać z javax.mail.internet.internetaddress InternetAddress address; //ala = new InternetAddress("ala@mimuw.edu.pl"); ala = new InternetAddress("ala@mimuw.edu.pl", "Ala ma kota"); poprawność podawanych adresów nie jest sprawdzana podajemy zarówno adres od jak i do (większość serwerów obecnie nie pozwala wpisywać dowolnego adresu od) message.setfrom(ala); message.setreplyto(new InternetAddress[] {ala}); message.addrecipient(message.recipienttype.to, ola); message.addrecipient(message.recipienttype.cc, ala); 13
javax.mail.authenticator klasa abstrakcyjna należy ją rozszerzyć i zaimplementować metodę getpasswordauthenticator(), która ma zwracać obiekt PasswordAuthentication zawierający nazwę użytkownika i hasło... odczytywanie z pliku pytanie użytkownika Authenticator przekazuje się jako drugi parametr tworząc sesję 14
javax.mail.transport klasa abstrakcyjna można jednorazowo wysłać pojedynczą wiadomość Transport.send(message); można też wysłać kilka wiadomości utrzymując jedno połączenie Transport transport = session.gettransport("smtp"); transport.connect("students.mimuw.edu.pl", "xx123456", "xxx"); transport.sendmessage(message, message.getallrecipients()); transport.close(); ustawiając session.setdebug(true) można podejrzeć komunikację z serwerem 15
Pobieranie wiadomości 16
javax.mail.store/folder Store store = session.getstore("pop3"); store.connect("poczta.o2.pl", "login", "hasło"); Folder folder = store.getfolder("inbox");//dla imap mogą być inne folder.open(folder.read_only); Message[] messages = folder.getmessages(); //implementacja SUNowska ściąga wiadomości dopiero jak są dotykane for (Message m : messages) System.out.println(m.getContent()); folder.close(false); store.close(); 17
odpowiadanie Istnieje skrót pozwalający wygodnie odpowiadać na wiadomości //parametr wskazuje czy odpowiedzieć do wszystkich (true), czy tylko do wysyłającego (false) MimeMessage reply = (MimeMessage) message.reply(false); reply.setfrom(adres); reply.settext("żadna treść nie jest automatycznie tworzona"); Transport.send(reply); odpowiedź jest stosowanie zaadresowana tytuł odpowiedzi jest poprzedzony przez Re: 18
przekazywanie //analogicznie załączniki //tworzymy widomość Message forward = new MimeMessage(session); //wypełniamy nagłówek forward.setsubject("fwd: " + message.getsubject()); forward.setfrom(new InternetAddress(from)); forward.addrecipient(message.recipienttype.to, new InternetAddress(adresDo)); //wiadomość będzie się składała z kilku części //tworzymy część z dodawaną treścią BodyPart messagebodypart = new MimeBodyPart(); messagebodypart.settext( "Oto oryginalna wiadomość:\n\n"); 19
przekazywanie //tworzymy zlepek części i wstawiamy dodawaną treść Multipart multipart = new MimeMultipart(); multipart.addbodypart(messagebodypart); //tworzymy część z oryginalną wiadomością messagebodypart = new MimeBodyPart(); messagebodypart.setdatahandler(message.getdatahandler()); //dodajemy oryginalną wiadomość do zlepka multipart.addbodypart(messagebodypart); //wstawiamy zlepek do wiadomości forward.setcontent(multipart); //wysyłamy Transport.send(forward); 20
Bezpieczeństwo TLS certyfikaty keytool 21