Nach mehr als 10 Jahren in der Java-Weiterbildung wiederholen sich doch die Fragen. Die Klassiker: „Wie haben Sie Java gelernt?“, „Wie bilden Sie sich weiter?“, „Was für Java-Bibliotheken nutzen Sie?“, „Wie verbreitet ist eigentlich XZY?“ Aus diesen Anfragen heraus möchte ich eine neue Rubrik „Die wöchentliche Dosis Java“ vorstellen. Die Idee ist, die kontinuierliche Weiterbildung von Software-Entwicklern zu fördern. In der (hoffentlich) wöchentlichen Rubrik stelle ich Technologien, Bibliotheken, Tools, Sprachupdates, … vor, in der sich Programmierer in einer Woche beschäftigen können und somit ein neues Gebiet kennenlernen. Der Bereich umfasst dabei die gesamte Java-Landschaft. Mal werden es Sprach-Erweiterungen sein, mal XML-Technologien, dann wieder etwas von Swing und Gui-Frameworks, dann REST, Web-Toolkits oder Open-Source Bibliotheken.
Java-API für Google-Calendar/Google Documents
Mit der Google Java API (http://code.google.com/apis/gdata/javadoc/) lässt sich leicht auf die Dokumente oder Kalender zurückgreifen. Ein erstes Beispiel für eine Liste der Google-Calender ist schnell formuliert:
import java.net.URL;
import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.client.docs.DocsService;
import com.google.gdata.data.calendar.CalendarEntry;
import com.google.gdata.data.calendar.CalendarFeed;
import com.google.gdata.data.docs.DocumentListEntry;
import com.google.gdata.data.docs.DocumentListFeed;
public class GoogleExample
{
public static void main( String[] args ) throws Exception
{
String user = „user@gmail.com“, pass = „pass“;
CalendarService calService = new CalendarService( „Mein Kalender“ );
calService.setUserCredentials( user, pass );
CalendarFeed resultFeed = calService.getFeed(
new URL( „http://www.google.com/calendar/feeds/default/allcalendars/full“ ),
CalendarFeed.class );
for ( CalendarEntry entry : resultFeed.getEntries() )
System.out.println( entry.getTitle().getPlainText() );
DocsService service = new DocsService( „Meine Dokumente“ );
service.setUserCredentials( user, pass );
DocumentListFeed feed = service.getFeed(
new URL( „http://docs.google.com/feeds/documents/private/full“ ),
DocumentListFeed.class );
for ( DocumentListEntry doc : feed.getEntries() )
System.out.println( doc.getId() + „/“ + doc.getTitle().getPlainText() );
}
}
Die notwendigen Java-Archive nimmt man aus dem lib-Verzeichnis des Archivs http://gdata-java-client.googlecode.com/files/gdata.java-1.15.2.zip. Um auf die Dokumente zurückzugreifen (oder auch nur aufzulisten), ist mail.jar ebenfalls nötig.
Mikroformate mit JAXB in XML abbilden
Die Informationen von Mikroformaten lassen sich mit JAXB relativ leicht in XML konvertieren:
import java.util.*;
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;
public class MicroformatViaJaxb
{
public static void main( String[] args ) throws JAXBException
{
Microformat mf = new Microformat();
mf.elements.add( new Element( "name", "Christian Ullenboom" ) );
mf.elements.add( new Element( "address", "tutego Allee" ) );
mf.elements.add( new Element( "phone", "2873568956928" ) );
JAXBContext context = JAXBContext.newInstance( Microformat.class );
Marshaller m = context.createMarshaller();
m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
m.marshal( mf, System.out );
}
}
@XmlRootElement( name = "div" )
class Microformat
{
@XmlAttribute( name = "class" )
public String key = "person";
@XmlElement( name = "span" )
public List<Element> elements = new ArrayList<Element>();
}
class Element
{
@XmlAttribute( name = "class" )
public String key;
@XmlValue
public String value;
public Element() { }
public Element( String key, String value )
{
this.key = key;
this.value = value;
}
}
Got all this abbreviations?
XML HK2 WSIT ESB JMS SSO SAO JSR JAX-RS JCP DOJO AJAX WSDP jBMP RIFE RAILS MC4J CAPS SAML WS-* WSRP SAW JXTA HTTP URL IIOP ORB JMX TCP/IP WSDL MEX XWSS MTOM XSD SMTP WSA SOAP JBI JCA CMT LDAP BMT CMPI VJM CDDL GPL BSD API JAX-B StAX JSP JSTL EJB JPA TCK JDBC JDK JRE JAXP XOP REST POJO SQL GUI URI XMLDSig JAAS GSSAPI META-INF NIO ACL JNL CORBA CDC CLDC MIDP ACID SSL DRDA UML SAX DOM XOM XML-RPC MVC XSLT DAO SVG COM FTP PDF JNA ANTLR SLF4J
Alles klar?
Unterlagen von Sun Tech Days Dezember 2007 online
Die PDFs sind zwar schon länger online, aber für Interessierte noch der Link: http://de.sun.com/sunnews/events/2007/20071203/agenda_frankfurt.jsp#agenda-2:
Sun Microsystems Country Manager Introduction:Donatus Schmid, Marketing Director Germany
Download PDF
Demo. Showcase: Tomorrow’s Technologies in action Today
Sang Shin, Simon Ritter, Sridhar Reddy, Carol McDonald, Philip Torchinsky, Joey Shen, Inyoung Cho
Sun Spot
Java EE, GlassFish and their Future
Daniel Adelhardt
Download PDF
Java SE 6 Top 10 Features, Java SE 7 and OpenJDK
Inyoung Cho
Download PDF
What Makes Solaris Interesting?
Frank Curran
Download PDF
Oracle Sponsor Session: Discover Oracle
Wolfgang Ehrenthaler
Download PDF
Easy Deployment: Leaner and Meaner Runtime
Simon Ritter
Download PDF
New Security Features in Solaris and OpenSolaris
Scott Rotondo
Download PDF
Sun Keynote – James Gosling
Download PDF
Java DB: The Multi-tier Database
Dag H. Wanvik
Download PDF
A Rich Application Platform: JavaFX
Sridhar Reddy
Download PDF
Building High Performance Applications on Multicore Systems Using Sun Studio Compilers and Tools
Vijay Tatkar
Download PDF
Solaris Virtualization for Systems Administrators
Philip Torchinsky
Download PDF
Rapid Development with Ruby, JRuby and Rails
Joey Shen
Download PDF
Real-time Java
Simon Ritter
Download PDF
Performance Tuning With Sun Studio Analyzer, Race Detection Tools, Dtrace (D-Light)
Boris Ivanovsky
Download PDF
Efficient System Administration Using Sun’s System Management Technologies
Juergen Fleischer
Download PDF
Developing Applications Using Spring and JPA
Eberhard Wolff
Download PDF
Effective Concurrency for the Java Platform
Sang Shin
Download PDF
Let SMF Deal With That
Detlef Drewanz
Download PDF
Java Persistence API: Further Simplifying Persistence
Simon Ritter
Download PDF
Isolating Performance Bottlenecks and Memory Leaks
Jaroslav Bachorik
Download PDF
Enterprise Database Inside: The PostgreSQL In Your Solaris
Paul van den Bogaard
Download PDF
Sun Community Keynote: Developing in a Polyglot World by Craig McClanahan
Download PDF
Ajax and Web 2.0 Related Frameworks and Toolkits
Carol McDonald
Download PDF
Programming for Cool Devices using the Open Source Java ME PhoneME Stack
Terrence Barr
Download PDF
ZFS – Using Its Full Potential
Uli Graef
Download PDF
Building Rich Web Applications using jMaki
Joey Shen
Download PDF
More Concurrency: The Ten Unofficial Laws
Heinz Kabutz and Kirk Pepperdine
Download PDF
NFS and pNFS: High Performance Shared Data Stores for HPC Applications
Guenter Herbert
Download PDF
AMS GmbH Sponsor Session: jBEAM – A Framework for Desktop and Web Based Analysis and Reporting Systems
Dr. Bernhard Sünder
Download PDF
OpenSolaris Testing
Joaquim Rosell &
Sean McGrath
Download PDF
AMD Sponsor Session: Optimizing for Quad-core Solaris Systems based on AMD platforms
Raj Kharran
Download PDF
Metro and REST: Everyday Web Services
Harold Carr and Carol McDonald
Download PDF
Web Services Security, OpenSSO and Access Management for SOA
Abdi Mohammadi
Download PDF
Intel Technical Session: What are we doing to optimize Solaris on Intel Architecture?
Download PDF
Java ME GUI Makeover with Ajax Mashup
Terrence Barr
Download PDF
Performance Tuning Applications: GC Friendly Java Programming
Simon Ritter
Download PDF
How to Develop Solaris Parallel Applications
Leonid Lenyashin
Download PDF
DTrace Web 2.0 Applications, JavaScript, PHP, Java and the SAMP Stack
Peter Karlsson and Philip Torchinsky
Download PDF
SOA Using OpenESB, BPEL and NetBeans
Armin Wallrab
Download PDF
Get Your Parallel Applications Onto The Grid With Sun Grid Engine
Guenter Herbert
Download PDF
Code style: Remove unnecessary statements and keywords
|
Bad |
Good |
|
import java.lang.*; |
|
|
import java.util.*; import java.util.Scanner; |
import java.util.*; |
|
class MyClass extends Object { } |
class MyClass { } |
|
class MyClass { int i = 0; boolean b = false; char c = ‚\u0000‘; String s = null; double d = 0.0; } |
class MyClass { int i; boolean b; char c; String s; double d; } |
|
class MyClass { MyClass() { super(); } } |
class MyClass { MyClass() { } } |
|
interface MyInterface { public abstract void foo(); } |
interface MyInterface { void foo(); } |
|
void lollipop() { return; } |
void lollipop() { } |
|
java.lang.String s; |
String s; |
|
Object[] param = new Object[ 1 ]; param[ 0 ] = i; |
Object[] param = { i }; |
Something missing?
Uff: Noch mehr Einkäufe. Oracle holt sich Bea
Das gibt’s ja nicht: Sun kauft MySQL
Details dazu gibt es hier: http://blogs.sun.com/jonathan/entry/winds_of_change_are_blowing
Verzeichnisstrukturen für Java-Projekte
In den Java-Projekten haben sich unterschiedliche Verzeichnisstrukturen durchgesetzt. Je nach Komplexität ist eine einfache ausreichend oder eine starke Strukturierung gibt eine Vorgabe.
Eine einfache Vorgabe ist, die Order mit dem Quellcode und den übersetzten Klassendateien zu trennen. Die üblichen Ordnernamen für Java SE-Projekte sind src und bin. Entwicklungsumgebungen wie Eclipse übersetzten Java-Typen aus dem src- in den bin-Ordner und kopieren Ressourcen wie Bilder und Übersetzungsdateien bei jedem Build ebenfalls in den bin-Ordner. Eclipse unterstützte diesen Aufbau standardmäßig, wenn beim Dialog für ein neues Java-Projekt unter „Project Layout“ die Option „Create separate folders vor source and class files“ aktiviert ist.
Unter NetBeans ist die Standardstruktur etwas anders und eng mit dem Build-Tool Ant verbunden. Der Ordner src enthält die Standard-Klasen und Ressourcen, ein zweiter Ordner test die Test-Klassen und Ressourcen. Die übersetzten Java-Klassen nimmt der Ordner build/classes auf. Das Ergebnis des Builds, eine Jar-Datei im Fall eines einfachen Java-Projekts, steht im Ordner dist.
Einen deutlichen Schritt weiter geht die Anregung vom Build-Manager Maven. Es schlägt zwei Hauptordner src und target vor. Der src-Ordner enthält alle Quellen und Ressourcen und ein build übersetzt das Projekt in den target-Ordner. Maven empfiehlt, den src-Ordner weiter nach Artefakten zu unterteilen: main (eigentliche Applikation oder Bibliothek), test (Testfälle), demo (Beispiele). Unter diesen Artifakten-Ordnern folgenden weitere Unterordner. Der wichtigste Ordner ist für Java-Projekte java. Es kommen optional hinzu: ressources (für Ressourcen), config (Konfigurationsdaten), webapp (Dateien einer Web-Applikation). Für den Ausgabeordner target wiederum sieht Maven die Unterteilung in classes (übersetze Klassen aus src/main/java und Kopie aus src/main/resources), javadoc (Java-Doc von src/main/java), test-classes (Test-Klassen aus src/test/java und Kopie aus src/test/resources).
Inconsistent lower/uppercase abbreviations in Java type names
|
Library |
Uppercase Variant |
Lowercase Variant |
Special Case |
|
Java SE |
GZIPOutputStream |
ZipOutputStream |
HttpURLConnection |
|
DGC |
MidiSystem |
StAXSource |
|
|
AWTError |
JdbcRowSet |
|
|
|
HTML |
Clob, Blob, NClob |
|
|
|
ImageIO |
|
|
|
|
JAXBContext |
|
|
|
|
JMXConnector |
|
|
|
|
JPEGImageWriteParam |
|
|
|
|
PBEKey |
|
|
|
|
RMIClassLoader |
|
|
|
|
RSAKey |
|
|
|
|
SAXParser |
|
|
|
|
SOAPElement |
|
|
|
|
SQLException |
|
|
|
|
SSLContext |
|
|
|
|
UIDefaults |
|
|
|
|
URI, URL, PrinterURI |
ReferenceUriSchemesSupported |
|
|
|
Java EE |
XMLEvent |
XmlElement |
W3CDomHandler |
|
XMLOutputFactory |
XmlSchema |
|
|
|
XMLType |
XmlType |
|
|
|
EJB |
Xid |
|
|
|
ELResolver |
JspTag |
|
|
|
HTTPBinding |
HtmlMessage |
|
|
|
JAXBElement |
SqlResultSetMapping |
|
|
|
JDBCStats |
HttpServlet |
|
|
|
JMSSessionStats |
|
|
|
|
JVMStats |
|
|
|
|
SAAJResult |
|
|
|
|
SOAPBinding |
|
|
|
|
URIValidator |
|
|
|
|
XAConnection |
|
|
|
|
Spring |
MessageEOFException |
JmsException |
|
|
OC4JJtaTransactionManager |
JmxUtils |
|
|
|
SQLErrorCodes |
SqlCall |
|
|
|
SQLExceptionTranslator |
SqlFunction |
|
|
|
URIEditor |
UrlResource |
|
|
|
|
JndiRmiClientInterceptor |
|
|
|
|
JpaTemplate |
|
|
|
|
JstlView |
|
|
|
|
MimeMailMessage |
|
|
|
|
SimpleJaxWsServiceExporter |
|
|
|
|
XmlBeanFactory |
|
|
|
Apache Commons |
NTPUDPClient |
NtpUtils |
HttpURL |
|
FTPClient, POP3Client |
HttpClient |
|
|
|
SimpleSMTPHeader |
|
|
|
|
NTLMScheme |
|
|
|
|
RFC2965Spec |
|
|
|
|
URI |
|
|
What is your favourite example or inconsistent usage?
Werbung: Wir haben neue Java-Seminare!
Buchkritik: Beautiful Code: Leading Programmers Explain How They Think
Beautiful Code: Leading Programmers Explain How They Think
Andy Oram, Greg Wilson. O’Reilly. 2007. 618 Seiten
Bekannten Autoren und Software-Architekten geben in 33 Kapiteln viele Beispiele ihrer Kunst, und Einblicke in ihr Schaffen. Doch sehr spezielle Beispiele in diversen Programmiersprachen machen es für Java-Programmierer schwer, hier „schönen Code“ zu entdecken. Unter dem Strich bleibt nicht viel für Java-Entwickler über, wenn Programmiersprachen wie C, Ruby, LISP ihren Platz finden und Algorithmen vorgestellt werden, die für die allermeisten kaum relevant sind. Interessant ist es allemal, und wer sich viel Zeit für die Einarbeitung nimmt, wird auch sicherlich viel entdecken, zumal das Design einen größeren Stellenwert einnimmt, als der Quellcode an sich. Bei den wenigen Java-Programmen gibt leider etwas zu bemängeln. Einmal ein einfacher Fehler auf Seite Seite 478, in dem die Klammerung falsch ist:
class Sample {}
public static void main(String[] argv) {
System.out.println("Hello World");
}
Der zweite Hammer haut aber stärker rein und ist definitiv kein Beispiel für „Beautiful Code“. Seite 332 stellt eine EJB Session-Bean FileReaderBean vor, die über eine FileInputStream Daten vom Dateisystem holt – das ist nun wirklich nicht in Ordnung. Toll finde ich, dass die Erlöse an Amnesty International gehen: „All royalties from this book will be donated to Amnesty International.”. Das nette Kapitel Code in Motion ist online verfügbar.
Google Android und die nicht-JVM
Google Android ist der Versuch von Google, ein quelloffenes und freies SDK für mobile Endgeräte zu etablieren. Nach ein paar Monaten gibt es die ersten Stimmen aus dem Netz, die nicht so positiv sind. Insbesondere werden die mangelhafte Dokumentation (damit meine ich nicht die „FAQ“ http://code.google.com/android/kb/general.html), fehlende Beispiele und ein nicht öffentliches Issue/Bug-Tracking-System bemängelt. Interessant ist ebenfalls der Ansatz von Google, eine eigene JVM auszuliefern, um sich damit eventuell um Lizenzrechte rumzuwinden. Die Idee ist, den Java Quellcode zunächst über den Standard-Compiler in Java Bytecode zu übersetzen, aber dann über einen weiterer Präprozessor dx den JVM-Bytecode in das so genannte DEX-Format zu bringen, was die VM Dalvik dann ausführt. Dalvik ist etwas anders gebaut als die Standars-JVMs, denn es ist zum Beispiel eine Register-Maschine und keine Stack-Maschine. Ein weiteres Detail sind die Bibliotheken. Die Java Standard Library kommt vom Apache Harmony Projekt und ist somit Apache-Lizenz, genauso wie vieles von Android auch. (Das Betriebssystem unter der Haube ist Linux und somit GPL.)
Sehr große Anfrage an den JBuilder
In meiner Linksammlung sitzt http://www.borland.com/jbuilder, was mit der Browser nun beantwortet mit:
|
Server Error in ‚/‘ Application.
|
Entweder geht es dem Produkt wahnsinnig gut und jeder will den JBuilder kaufen/laden/… oder .NET ist so schlecht, dass es mit der Last nicht umgehen kann.
Warum catch ( Exception e ) schlecht ist, und was man dagegen tun kann
Eine ganze Reihe von Java-Methoden lösen eine ganze Reihe von unterschiedlichen Ausnahmen aus:
private void setLaf()
{
try
{
UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
}
catch ( ClassNotFoundException e )
{
handle();
}
catch ( InstantiationException e )
{
handle();
}
catch ( IllegalAccessException e )
{
handle();
}
catch ( UnsupportedLookAndFeelException e )
{
handle();
}
}
Oftmals befindet sich dann im Quellecode eine Anweisung wie catch ( Exception e ), die große Kaskaden von catch-Anweisungen verkleinern soll. (So kann man auch den gleichen Handler verwenden.) Das Problem dabei: Man fängt mehr, als man will, insbesondere wertvolle RuntimeExceptions, die man ungern als checked SQL- oder sonstwas-Exeption vernudelt haben möchte. Wenn ich mir moderne Frameworks, wie Spring oder Java EE 5 anschaue, wird dort ausschließlich mit RuntimeException gearbeitet, und die fängt eine catch ( Exception e ) ebenfalls brutal ab. Wenn zum Beispiel das Framework aufgrund einer unchecked Exception eine Transaktion abbricht, wir diesen Fehler aber schon „weggefangen“ haben, ist das ein echtes Problem.
Ich sehe für eine vernünftige Behandlung mehrere Möglichkeiten:
- Warten auf Java 3000, da dort sicherlich so etwas wie catch ( IOException, SQLException e ) definiert wird.
- Eine gemeinsame handle()-Funktion zu definieren, die man dann aus den catch-Handlern ansteuert.
- Ein catch ( Exception e ) und dann ein instanceof Test auf die erwarteten Exceptions mit einer re-thow, wenn der Typ nicht bekannt ist.
Schlechter Quellcode von NeuralBuild (NeuralLimits)
Über den Artikel http://entwickler.com/itr/news/psecom,neu,1,id,39010,nodeid,82.html bin ich auf einen Generator aufmerksam geworden, der automatisch DOAs und Transfer-Objekte erzeugt. Leider ist doch der generierte Quellcode wenig überzeugend. En Besipiel:
public Integer insertCompany(Company criteriaCompany)
throws NeuralBuildJavaSampleDAOInsertException {
Integer keyVal = new Integer(0);
con = connMgr.getConnection("neuralbuildjavasample");
int setindex = 1;
String vSQL = constructInsertPreparedStatement(criteriaCompany);
try {
PreparedStatement ps = con.prepareStatement(vSQL,
PreparedStatement.RETURN_GENERATED_KEYS);
if (criteriaCompany.CompanyID_isSet) {
ps.setInt(setindex, criteriaCompany.getCompanyID().intValue());
setindex++;
}
if (criteriaCompany.CompanyName_isSet) {
ps.setDate(setindex,
(java.sql.Date) criteriaCompany.getCompanyName());
setindex++;
}
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next()) {
keyVal = Integer.valueOf(rs.getObject(1).toString());
}
rs.close();
rs = null;
ps.close();
} catch (Exception e) {
connMgr.freeConnection("neuralbuildjavasample", con);
throw new NeuralBuildJavaSampleDAOInsertException("Insert Failed " +
e.getMessage(), e);
}
connMgr.freeConnection("neuralbuildjavasample", con);
return keyVal;
}
- new Integer(0) wird immer gebaut, auch wenn es später überschrieben wird.
- finally fehlt: So ist das close() nicht garantiert. (Nicht sooo schlimm, da bei Freigabe der Connection auch ResultSet und XXXStatement freigegeben werden.)
- Quellcode-Duplizierung bei connMgr.freeConnection(„neuralbuildjavasample“, con);. Das gehört auf jeden Fall in finally{}
- Was soll den rs = null; bewirken? Den GC hilt das bei lokalen Variablen nun wirklich nicht.
- catch (Exception e) muss wirklich sein? Ode doch catch (SQLException e)?
- Wenn die Rückgabe ein Integer-Objekt ist, warum dann „Integer.valueOf(rs.getObject(1).toString());“ schreiben? Das funktioniert zwar, aber wenn getObject() schon in Integer ist, muss man nicht erst in ein String und dann wieder zurück konvertieren.
- Sollte man wirklich einfach nur 0 zurückliefern, wenn man keinen Schlüssel bekam?
Die anderen Methoden habe auch so ihre Macken, so mit der Namensgebung.
- CachedRowSet Rs = null; Groß-/Kleinschreibung!
- Gemische Groß-/Kleinschreibung ist Standard, nicht so bei setindex.
- Unterstriche sind von Sun in der Namenskonvention nur bei Konstanten vorgesehen, aber nicht etwa bei CompanyID_isSet
- Ist die Namensgebung so gut, wenn man liest
ps.setDate(setindex, (java.sql.Date) criteriaCompany.getCompanyName() );
Also setDate() auf ein Company-Name? - Die API-Doku sollte nicht schreiben: „Delete an object from the database.“ sondern laut Suns-JavaDoc-Vorgaben: „Deletes an object from the database.“
"Whitespace cleanup on all sources" Java-Quellen endlich einheitlich
Nach mehr als 10 Jahren sind in Java 7 endlich die Quellen so, dass nicht mehr Tabs und Spaces gemischt sind. Endlich. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6616089.
Die übelste Java-Implementierung für einen Schaltjahrtest…
… gibt es bei Worse than failure im Forum unter http://forums.worsethanfailure.com/forums/thread/31448.aspx.
JAXB2-Annotationen an Beispielen
Schreiben der Felder statt Nutzen der Setter/Getter: Annotiere die Klasse mit
@XmlAccessorType( XmlAccessType.FIELD )
@XmlAttribute
|
class Person { String name;
@XmlAttribute int id; } |
<person id=“123″> <name>Christian</name> </person> |
@XmlValue
Gibt es nur ein Element kann @XmlValue dies in den Rumpf setzten.
|
class Person { int id; } |
<person> <id>123</id> </person> |
|
class Person { @XmlValue int id; } |
<person>123</person> |
@Transient
Nimmt Element aus der XML-Abbildung aus.
|
class Person { @XmlTransient int id;
String firstname; String lastname; } |
<person> <firstname>Christian</firstname> <lastname>Ullenboom</lastname> </person> |
@XmlList
Schreibt Elemente einer Sammlung nicht in einzelnen Elementen, sondern mit Leerzeichen getrennt.
|
class Person { List<String> emails; }
|
<person> <emails>muh@kuh.de</emails> <emails>zick@zack.com</emails> </person>
|
|
class Person { @XmlList List<String> emails; } |
<person> <emails>muh@kuh.de zick@zack.com</emails> </person> |
Elemente einpacken mit @XmlElementWrapper
|
class Person { List<String> emails; } |
<person> <emails>muh@kuh.de</emails> <emails>zick@zack.com</emails> </person> |
|
class Person { @XmlElementWrapper(name = „emails“) @XmlElement(name = „email“) List<String> emails; } |
<person> <emails> <email>muh@kuh.de</email> <email>zick@zack.com</email> </emails> </person> |
Reihenfolge ändern
|
class Person { String lastname, firstname; } |
<person> <lastname>Ullenboom</lastname> <firstname>Christian</firstname> </person> |
|
@XmlType( propOrder = { „firstname“, „lastname“ } ) class Person { String lastname, firstname; } |
<person> <firstname>Christian</firstname> <lastname>Ullenboom</lastname> </person> |
@XmlJavaTypeAdapter
Anpassen der XML-Abbildung, etwa für Datumswerte.
|
class Person { Date birthday; } |
<person> <birthday>1973-03-12T00:00:00+01:00</birthday> </person> |
|
class Person { @XmlJavaTypeAdapter( DateAdapter.class ) Date birthday; }
class DateAdapter extends XmlAdapter<String, Date> { private final static DateFormat formatter = new SimpleDateFormat( „dd/MM/yyyy“ );
public Date unmarshal( String date ) throws ParseException { return formatter.parse( date ); }
public String marshal( Date date ) { return formatter.format( date ); } } |
<person> <birthday>12/03/1973</birthday> </person> |
Der spezielle Datentyp XMLGregorianCalendar
Neben der Möglichkeit, Datumswerte mit einen XmlJavaTypeAdapter zu übersetzen, bietet JAXB den Datentype XMLGregorianCalendar.
Person p = new Person();
GregorianCalendar c = new GregorianCalendar( 1973, Calendar.MARCH, 12 );
p.birthday = DatatypeFactory.newInstance().newXMLGregorianCalendar( c );;
|
class Person { XMLGregorianCalendar birthday; } |
<person> <birthday>1973-03-12T00:00:00.000+01:00</birthday> </person> |
Die Abbildung enthält alle notwendigen Werte. Sollen Segmente, wie die Zeitzone herausgenommen werden, so markiert man sie aus:
Person p = new Person();
GregorianCalendar c = new GregorianCalendar( 1973, Calendar.MARCH, 12 );
XMLGregorianCalendar gc = DatatypeFactory.newInstance().newXMLGregorianCalendar( c );
gc.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
gc.setTime(DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
p.birthday = gc;
|
class Person { XMLGregorianCalendar birthday; } |
<person> <birthday>1973-03-12</birthday> </person> |
Elemente einbetten mit @XmlElements
Person p = new Person();
EmailContact c1 = new EmailContact();
c1.address = „hoho@weihnachtsmann.de“;
PhoneContact c2 = new PhoneContact();
c2.number = „0011-123456789“;
p.contacts = Arrays.asList( c1, c2 );
|
@XmlRootElement @XmlAccessorType( XmlAccessType.FIELD ) class Person { @XmlElements( { @XmlElement( name = „email“, type = EmailContact.class ), @XmlElement( name = „phone“, type = PhoneContact.class ) } ) List<Object> contacts = new ArrayList<Object>(); }
@XmlAccessorType( XmlAccessType.FIELD ) class EmailContact { @XmlValue String address; }
@XmlAccessorType( XmlAccessType.FIELD ) class PhoneContact { @XmlValue String number; } |
<person> <email>hoho@weihnachtsmann.de</email> <phone>0011-123456789</phone> </person> |
JNotify: Was tut sich im Dateisystem?
Die kleine (native) unter Linux und Windows arbeitende Bibliothek JNotify meldet Änderungen an Dateien. Ein Beispiel:
String path = "c:/";
int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED | JNotify.FILE_MODIFIED | JNotify.FILE_RENAMED;
boolean watchSubtree = true;
int watchID = JNotify.addWatch(path, mask, watchSubtree, new JNotifyListener()
{
@Override
public void fileCreated( int arg0, String arg1, String arg2 )
{
System.out.println( "created" );
}
@Override
public void fileDeleted( int arg0, String arg1, String arg2 )
{
System.out.println( "deleted" );
}
@Override
public void fileModified( int arg0, String arg1, String arg2 )
{
System.out.println( "modified" );
}
@Override
public void fileRenamed( int arg0, String arg1, String arg2, String arg3 )
{
System.out.println( "renamed" );
}
} );
Und am Ende:
JNotify.removeWatch(watchID);
Part 1
September 2007. by Paul Glezen and James Neethling