Skip to content
accelerando

Category Archives: Java

Creating a better PathMatcher for Spring 3

09-Mar-11

Spring 3 has excellent support for mapping URLs to @Controller methods through the @RequestMapping annotation. This works quite well and i especially like the fact having the mapping right next to the method and not in some other config file like routes.rb.

My goal was to have urls like http://foobar.com/resource, http://foobar.com/resource.html, http://foobar.com/resource.zip etc. This is no problem at all thanks to the ContentNegotiatingViewResolver.

The solution has only one draw back: The format is not known to the controller. Yes, this shouldn’t be a controller concern in most cases but what if you have a format that you don’t want to be available to all users? Maybe an nice zip download of your resources? Handling authentication in a view? I don’t think so.

So my first attempt looked like this

@RequestMapping("/resource.{format}")
public String resource(
		final @PathVariable String format,
		final HttpServletRequest request,
		final Model model
)

That didn’t work because it wouldn’t work for the default text/html resource http://foobar.com/resource so i added

@RequestMapping("/resource")
public String resource(
		final Model model
) {
  this.resource('html', model);
}

That worked for http://foobar.com/resource but not for http://foobar.com/resource.zip… “format” was always html. Hmmm…

After much googling and reading StackOverflow.com i found the “useDefaultSuffixPattern” option on org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping. If set to true (which is the default) the mapping “/resource/” will also map to “/resource/” and “/resource.*”. Although both useful i tried disabling it through my spring-cfg.xml like

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    	<property name="order" value="0" />
    	<property name="useDefaultSuffixPattern" value="false" />
</bean>

Enter the next problem: First, i didn’t work either. Second, all urls where mapped twice. Without the default suffix pattern and with. I spend 2 hours trying to locate the place where the spring config was loaded twice. In the end it was that one line that caused me trouble:

  <mvc:annotation-driven/>

That tag enables a lot of stuff in Spring 3, like the @Controller programming model and many other goodies. What it also does is establishing an AnnotationHandlerMapping that cannot be overwritten. So the next thing i did was browsing through the Spring sources to see what it does and redid with Spring beans in my config file (code follows later).

With that implemented, my urls still didn’t work, for all cases the URL without .{format} was called.

As i was already deep down in the Spring sources i had a look at the default path parser and matcher called AntPathMatcher. There is nothing wrong with the parsing code but the “getPatternComparator” method that “Given a full path, returns a Comparator suitable for sorting patterns in order of explicitness.” had some flaws, at least for my use case.

It sorts the patterns by explicitness and that explicitness is (among others) defined by how many placeholders for path variables are present. So my “/resource” is more explicit that “/resource.{format}”. With that in mind, i extend the path matcher like so:

This PathMatcher delegates most of his methods to the default AntPathMatcher but overwrites the getPatternComparator. If you have a look at the sources you’ll see that it is also partly copied. In the last else branch you’ll see that i sort both patterns by length, strip the default suffix (.*) and check wether the longer pattern starts with the other one. If it does i check wether the difference is just a .{format} (hardcoded). If that’s true, than the pattern with the format suffix is more explicit. Otherwise, i’ll use the default algorithm.

To get this to work, you cannot use the mvc:annotation-driven tag as the PathMatcher is a property of the AnnotationMappingHandler which in turn cannot be overwritten. So to get the same functionality like in Spring 3.0.5 with my PathMatcher use

As you can see i left the useDefaultSuffixPattern option enabled as it works very well with my PathMatcher and i didn’t want to care about mapping “/resource”, “/resource/” etc…

I really hope that the gists will save someone some time. I cannot imagine that i’m the only one having this kind of requirement. The solution is really simple but the way to it was not that easy.

All roads lead to Rome…

14-Feb-11

…or: Adding Atom links to an RSS feed generated by ROME.

I’m using ROME to create RSS and Atom feeds for a project.

While ROME has excellent support for creating either RSS or Atom feeds, there is no build-in immediate support for Atom elements inside an RSS feed like

<atom:link href="http://example.com/example.rss" rel="self"/>

The first thing nowadays is to Google some keywords and finding someone who had the same problem. I found jettro and started with his solution but to me, the solution might work but is wrong.

Some points:

  • The copyFrom method means exactly the opposite
  • The generator doesn’t need to add the namespace
  • I want to add more than a link some time

I’ve implemented an AtomContent class that holds a list of com.sun.syndication.feed.atom.Link but is easy extensible.

This content is managed by an AtomModule like so

public interface AtomModule extends Module {
	/** The public namespace URI */
	public final static String ATOM_10_URI = "http://www.w3.org/2005/Atom";
	/** as used in the namespaced prefixed with "atom" */
	public final static Namespace ATOM_NS = Namespace.getNamespace("atom", ATOM_10_URI);
 
	/** Gets the included content */
	public AtomContent getContent();
 
	/** Sets the included content */
	public void setContent(final AtomContent content);
}

This interface is accompanied by an implementation AtomModuleImpl that is used to provide instances of AtomContent and especially an AtomModuleGenerator that is used to generate XML elements via JDOM.

The generator implements ModuleGenerator and if added through a rome.properties files automatically adds the appropriate namespace to the feeds. The rome.properties looks like this:

rss_2.0.feed.ModuleGenerator.classes=ac.simons.syndication.modules.atom.AtomModuleGenerator
rss_2.0.item.ModuleGenerator.classes=ac.simons.syndication.modules.atom.AtomModuleGenerator

As you see, i’ll only added the generator to RSS 2.0. Also a parser is not available at the moment as i didn’t need one.

The following snippet demonstrates the usage of the AtomModule:

final AtomContent atomContent = new AtomContent();
atomContent.addLink(new SyndicationLink().withRel("self").withHref("http://example.com/example.rss").getLink());
atomContent.addLink(new SyndicationLink().withRel("alternate").withType("text/html").withHref("http://example.com/example.html").getLink());
feed.getModules().add(new AtomModuleImpl(atomContent));

I published the code as java-syndication along with some other helper classes. If i need more elements, i’ll add them, but in the meantime, the code is usable and maybe of some value for people building RSS feeds with Java and ROME.

Disable jsessionid path parameter in Java web applications

28-Jan-11

Wow, this has driven me nuts…

Most J2EE developers will know the ugly-as-hell ;jsessionid=BLAHBLAHBLAH appended as a path parameter to all urls of an application on the first call of a page that creates a session.

Tomcat as of version 6 has the possibility to add the attribute ‘disableURLRewriting=”true”‘ to the context of the application but that didn’t work for me…

The problem was: I’m using Spring Security and Spring Security has it’s own mechanism and control for the session store.

It can be disabled through security-conf.xml (or wherever you’ve stored the Spring Security configuration) within the http element:

<http use-expressions="true" disable-url-rewriting="true" create-session="ifRequired">

And boom, the path parameter is gone.

For more information see The Security Namespace

The jsession parameter is used on the first page that requires a session as the server cannot now at this point in time whether the client supports cookies or not. If you disable it, you’re clients need to allow cookies, otherwise no session will be created.

#wjax 2010

16-Nov-10

Nachdem ich 2009 aus privaten Gründen weder auf der JAX noch auf der W-JAX war, zog es mich in diesem Herbst nach München, zur W-JAX.

Neu für mich im Vergleich zu den letzten Jahren war, dass ich mir mal ein Zimmer im Tagungshotel genommen habe und bereits am Ende des ersten Tages war mir ziemlich klar, dass es eine gute Entscheidung war. Ich bin einfach motivierter, wenn ich morgens früh nicht erst lange vom Hotel zum Tagungsort und abends wieder zurückkommen muss. Ergo hatte ich auch diesmal mehr von den Abendveranstaltungen.

Als kleine Zusammenfassung mal für mich als auch für die werten Kollegen, hier mal eine Übersicht der Sessions, die ich besucht habe:

Dienstag

Einführung von Sebastian Meyen @smeyen

Die Einführung gab Sebastian Meyen vom Java Magazin. Als Einführung ist es natürlich keine Session zu einer konkreten Technologie. Sebastian betonte den Wandel in Javas Geschichte von 2005 bis 2010: Nach einer Zeit der Stagnation, einem “Aufschrei” bei der Übernahme von Sun durch Oracle, einer Zeit der Stille kommuniziert Oracle jetzt seine konkrete Pläne. Sebastian schätzt Oracle als Firma mit dem Willen zum Erfolg ein und wertet die aktuellen Vorgänge positiv.

Interessant fand ich die Aussagen zur Android Plattform und der Zukunft von J2ME.

Softwareentwicklung im Zeitalter der Globalisierung von Nicolai Josuttis

Abgesehen davon, dass Nicolais Slides ein kleines, kosmetisches Makeover benötigt hätten (Slides in Comic Sans MS, echt jetzt?), gefiel mir der Vortrag sehr gut, was unter anderem daran lag, dass Nicolai weitestgehend frei gesprochen hat und seine Ausführungen nur mit den Folien gestützt hat und nicht umgekehrt, halt so wie es sein soll.

Stichworte und Gedanken dieses Vortrags waren unter anderem, dass die IT ebenfalls globalisiert wird (nichts Neues) und die Teams immer verteilter werden, die Aufwendungen, dieser Verteilung mit immer mehr Technik her zu werden, immer größer.

Wo ich Nicolai absolut beipflichte, ist die Aussage, dass IT und Entwicklung nicht in der Hand von Experten liegt sondern mehr und mehr beim Marketing. Der Kampf, das zu ändern, ist verloren. In einer Zeit, in der immer höhere Margen immer wichtiger werden, wird lieber der billigere Programmierer eingestellt als der fähige.

Wirklich gut fand ich, dass Nicolai aussprach, was oft Realität ist: Module und Programme müssen released werden, es muss schnell gehen und oftmals kann ein Projekt nicht im Sinne des best practice, der reinen Lehre entwickelt werden. Dies ist ein Fakt, mit dem umgegangen werden muss: Die Releases werden von den Experten asynchron aufgeräumt. Er sprach dabei von der agilen Putzkolone der IT.

Aus Erfahrung weiß ich, dass es genauso ist. Copy & Paste ist in vielerlei Hinsicht beliebtes Werkzeug und man die saubere Lösung oft nur in einem Code-Review und nachgelagertem Refactoring erreicht.

Java EE für Einsteiger, Aufsteiger und Umsteiger von Lars Röwekamp

Der Vortrag über die Neuerungen in J2EE 5 und 6 ist mir nicht in guter Erinnerung geblieben. Viel zu lange wurde damit verbracht, darzustellen, was in der alten Spezifikation alles nicht funktioniert hat bzw. zu den bekannten XML Konfigurationsorgien führte.

Viel zu spät erst stellte Lars in meinen Augen die Neuerungen vor. Daher ändern auch die schön gestalteten Slides nichts daran, dass ich aus diesem Vortrag nur wenig mitnehmen konnte.

NoSQL oder das Ende der “One Size Fits All”-Ära von Monika Moser @momo13

Auf diesen Vortrag freute ich mich wirklich, zumal theoretische Grundlagen im Vorfeld versprochen wurden.

Monika tat mir ein bisschen leid, der Vortrag war sehr gut besucht und uns wurde angeboten, den Raum zu wechseln und prompt kam es dort zu einigen Problemen mit dem Beamer. Schade ist, dass keiner auf die Frage “Kennt sich jemand mit dem Projektionsmodus von Macs” reagiert, obwohl tatsächlich Macbooks in allen Varianten diese Veranstaltung dominieren.

Leider war Monika zu sehr auf ihre Folien angewiesen und konnte kaum frei sprechen. Leider kann in meinen Augen so ein Vortrag nur noch schwer interessant werden.

Was ich zu hören bekam war ein Namedropping bekannter Datenbankkonzepte, die NoSQL in der einen oder anderen Form implementieren.

Wenigstens wurde kurz darauf eingegangen, was der Unterschied zwischen einem Key-Value Store und einem Document Store ist.

Zwischendurch wurden Begriffe wie “vector clocks” eingeworfen, die wohl was mit Konsistenz zu tun habe, aber nie erklärt. Weitere Ungereimtheiten waren Folien mit Bildern aus der Wikipedia zum Thema consistent hashing, die eigentlich gar nicht in das aktuelle Thema passten.

Fragen zu Abfragemöglichkeiten, die sich fundamental zur SQL Theorie unterscheiden, konnten nicht bzw. nur mit “je nach System muss man dann ein get mit der ID des Datensatzes machen” beantwortet werden. Schade, Potential verschenkt. Unter theoretischen Grundlagen habe ich mir mehr vorgestellt und auch trotz der widrigen Umstände mehr erwartet.

Build and deploy RIAs and mobile Applications using Flex von Anne Katherine Petterøe @yojibee

Ich verstehe ja, dass einem der Gold Sponsors auch eine Keynote ermöglicht wird, aber diese Keynote war ein totaler Reinfall. Natürlich ist es schwierig, Java Entwicklern die Vorteile von Flex nahe zu bringen, aber ich bezweifle, dass es mit Sesamstraßen Videos gelingt.

Eigentlich hätte man aus dem Vortrag was machen können, zumindest ist die Idee, mit dem Flashökosystem eine universale Plattform auf vielen mobilen Devices zu haben, ja nicht grundsätzlich schlecht.

Wenn dann allerdings auf einem Vortrag alles schief geht, angefangen von den Beamern, den Demos und einigem mehr, dann kann es nicht mehr interessant werden.

Aber wo sind meine ganzen J2EE Patterns hin? von Adam Bien @AdamBien

Vor etlichen Jahren habe ich Adam Bien mal bei einem Workshop / 1-Day Schulung gesehen. Damals war unser Ziel, eine In-House Anwendung im J2EE Umfeld zu entwickeln. Mein damaliger Eindruck: Das ist alles Irrsinn. Irgendein Generator spuckt eine Batzillion XML Dateien aus und man darf sich an’s Konfigurieren machen. Und weil das gerade so schön ist und trotzdem nicht funktioniert, braucht man noch jede Menge “Enterprise” Pattern, damit das ganze fliegt.

Zum Glück brachten Frameworks wie Ruby on Rails und Grails auch einen frischen Wind in die Java Szene und es ist schön zu sehen, wie “Enterprise” Pattern obsolet werden.

Adam Bien hat einen ganz eigenen, agilen Vortragsstil. Seine Slides bestehen meist nur aus wenigen Schlagworten und er springt zwischen diesen Stichworten und Live-Coding hin- und her.

Mir hat sein Vortrag sehr gut gefallen. Sehr witzig fand ich, wie er seine damaligen Patterns vorführte und die modernen Alternativen darstellte.

Bereits in diesem Vortrag dachte ich, dass es Zeit wird, JPA und JSFs auch einmal für private Projekte einzusetzen.

Alles in allem sehr kurzweilig und informativ.

Canoo RIA Suite von Dierk König @mittie

Dierk habe ich vor Jahren auf einer iX Veranstaltung zum Thema Grails gesehen. Diese Schulung gefiel mir damals überhaupt nicht. Vielleicht war ich schlecht drauf, er oder das Thema passte einfach nicht.

Sicherlich war sein Vortrag eine Werbeveranstaltung für die Canoo RIA Suite, aber eine sehr interessante.

Ich fand es gut, wie souverän Dierk mit den Widrigkeiten des Konferenz WLANs, dem iPhone Thetering und schlussendlich der leeren Laptopbatterie umging.

Das Canoo Framework interessiert mich, weil wir in einem Projekttteil, dessen Aufgabe die Ablösung einer großen Oracle Forms 6 Anwendung ist, einen ähnlichen Ansatz verfolgen. Allerdings ist die explizite Programmierung der GUI in unserem Ansatz optional, es werden ausgehend von den Definitionen im Data Dictionary von Oracle Swing Views generiert, die auch komplexe Master/Detail Masken und Lookups abdecken.

Mich hat es gefreut zu sehen, dass auch andere Firmen nach wie vor auf J2SE Swing setzen und damit attraktive Oberflächen bauen.

Für mich einmal eine angenehme “Werbeveranstaltung”.

Android Programmiermodel von Michael Johann @malagant

Michael Johann sollte eine Selbsthilfegruppe für technikverrückte Entwickler gründen. Ich kenne das Problem: Mich interessiert, wie eine Technik, ein Gerät funktioniert und kaufe irgendwann so ein Gerät, nur um es zu programmieren.

Sein Einstieg bestand folgerichtig in der Aufzählung der mobilen Devices, die er benutzt und programmiert.

Während des Vortrags erstellte er eine funktionierende Twitter Suche für Android 2.2. Was mich begeistert ist die Tatsache, dass man nicht wie zum Beispiel bei Apple gezwungen ist, sich eine kostenpflichte Developer Mitgliedschaft zuzulegen, um die eigene Anwendung auf dem eigenen Device zu testen.

Ebenfalls gefällt mir der Ansatz von Android, da Java immer noch für mich die Sprache ist, in der ich mich am heimischsten fühle.

Interessant waren die Gedanken zur Zukunft der Entwicklung von mobilen Devices. Es wurde die Hypothese geäußert, dass in einigen Jahren HTML 5 zusammen mit Frameworks wie SproutCore und Sencha den Standard setzen werden und nur noch sehr spezielle Applikationen nativ auf den Geräten laufen werden. Mein erstern Gedanken dazu war: War das nicht das Model, dass Apple 2007/2008 mit dem ersten iPhone vorgeschlagen hatte?

Ein sehr gelungener Abschluss des Tages.

Mittwoch

The power of JSF 2.0 von Andy Bosch @andybosch

Wahrscheinlich ungewollt, aber dieser Vortrag hat mich nicht nur auf neue Funktionen in JSF 2.0 aufmerksam gemacht, sondern auch noch einmal motiviert, Netbeans eine Chance zu geben. Andy hielt einen entspannten Vortrag mit gut geplantem und funktionierendem Lifecoding im großen Saal ab.

Es gibt einige Sachen, die ich nicht verstehe: JSF 2.0 löst per default nach wie vor Aktionen nur per POST aus? URLs sehen immer noch wie im letzten Jahrtausend aus und sind nur eingeschränkt bookmarkable? Kann eigentlich nicht sein, ist aber so. Ansonsten begeisterte mich allerdings die Toolunterstützung von Netbeans bei der Entwicklung, sowohl für Javaklassen als auch für JSF XHTML Dateien.

Ein guter Vortrag, um den Tag zu beginnen.

Semantisch expressive Webentwicklungssprachen von Dr. Thomas Biskup

In meinen Augen klang der Titel spannend, auf abstrakterer Ebene über die Probleme aktueller Sprachen zu sprechen. Was allerdings vorgestellt wurde, war das Opensaga Framework in dem genau das umgesetzt wird, was anderswo kritisiert wird. Opensaga ist noch jung und die Firma hat auch damit Erfolg, aber ich konnte den Vorteil zwischen Inhouse Lösungen und diesem Framework auf Frameworks beim besten Willen nicht erkenne,

Ich kann die Wünsche von Thomas verstehen, es besser machen zu wollen, aber zum einen war mir der Vortrag zu unstrukturiert und zum anderen zu sehr Werbung für etwas, das alles besser machen will, aber wahrscheinlich so noch nicht kann.

Nebenläufigkeit 1: Konzepte und Paradigmen unter Java von Johannes Link

Von diesem Vortrag habe ich nicht viel mitgenommen, was wahrscheinlich auf meine wachsende Müdigkeit und dem schlechten Sitzplatz im Raum zurück zu führen ist. Es wurden einige neue Denkansätze wie Transactional Memory und ähnliches vorgestellt, aber bei mir ist es leider nicht angekommen. Ich war zu sehr damit beschäftigt, im vollbesetzten Raum unter dem Klimaschacht zu frieren.

Rewriting JSF URLs with PrettyFaces von Dan Allen @mojavelinux

Dan Allen von Red Hat hielt die einzigen beiden englischsprachigen Talks, die ich anhörte.

Prettyfaces geht das Problem der unbrauchbaren URLs von JSF Anwendungen an. Der Vortrag war sehr gut strukturiert und aufgebaut und die Codebeispiele sinnvoll.

Prettyfaces sieht nach einem sehr interessanten Action Framework für JSF aus, dass JSF auch im alltäglichen Webumfeld und nicht nur für Webapplikationen brauchbar macht.

Seam Faces 3 and RichFaces 4 von Dan Allen @mojavelinux

Eh ja. Beides sicherlich interessante Dinge, wenn man bereits Erfahrung mit JSF 2 hat, die ich nicht habe.

Donnerstag

Optimierung von JPA-Anwendungen von Dirk Weil @dirkweil

Ein sehr spannender, sehr gut gehaltener Vortrag über die Möglichkeiten, JPA 2 basierte Anwendungen zu optimieren. Dirk stellte zuerst die Möglichkeiten des JPA Standards vor und ging dann auf spezielle Parameter der Platzhirsche Hibernate und EclipseLink ein.

Einige Dinge, die er nannte, kannte ich bereits. Uns hatte zum Beispiel bereits das Lazy Loading für Attribute geholfen, die Zugriffszeit in einem sehr speziellen Fall von Minuten zu Sekunden zu drücken. Viele andere Sachen waren aber neu und ich freu mich auf den Download der Slides, so dass wir diese Informationen bei Zeiten griffbereit haben werden.

Java 7 – Überblick über die Erweiterungen im jüngsten Release von Java von Angelika Langer und Klaus Kreft

Als letzten Vortrag hörte ich mir die Zusammenfassungen bzw. die Entscheidungen für das JDK 7 an. Einige neue Sachen klingen interessant, einige nur nett, viele der wirklichen Neuerungen sind ins JDK 8 verschoben wurden.

Mittlerweile hat Oracle sich offiziell zum Fahrplan für das JDK commited. Eine Entscheidung, die ich sehr gut finde, genau wie die Ankündigung, dass Oracle zusammen mit Apple am OpenJDK für Mac OS X arbeiten wird.

15 Vorträge, die in der Summe einen guten Eindruck hinterlassen und meines Erachtens auch den einen oder anderen Impuls für unsere Zwecke gebracht haben. Java wird mittlerweile gerne tot oder schlecht geschrieben, aber ich denke, dass es noch weit davon entfernt ist. Es war sicherlich nicht immer alles gut, aber es ist gut zu sehen, dass Impulse von außen aufgenommen und umgesetzt werden.

Ich blättere jetzt mal das JSF 2 Buch auf, das der Postbote gerade gebracht hat…

How to get UIDefaults in Java

06-Sep-10

If you’re loocking for Javas UIDefaults, use the UIManager class. This snippet gives you all installed UIDefaults:

UIDefaults defaults = UIManager.getDefaults();		 
for(Enumeration e = defaults.keys(); e.hasMoreElements(); ){
    String key = e.nextElement().toString();
    System.out.println(key + " = " + defaults.get(key));	         
}
Close
E-mail It