Posts tonen met het label JSP. Alle posts tonen
Posts tonen met het label JSP. Alle posts tonen

vrijdag 26 juni 2009

Frontcontrollers


Tijdens het volgen van een SCWCD (Sun Certified Web Component Developer) training kom je de coolste dingen tegen om een webapplicatie te ontwerpen en implementeren. Er wordt voortdurend op gehamerd dat je elk component in een webapplicatie (POJO, EJB, Servlet, JSP e.d.) moet gebruiken waar het voor dient, en ze niet misbruikt door bijvoorbeeld logica in een JSP te gaan stoppen omdat dat ook wel werkt. Neen! Men doet er verstandig aan de verschillende lagen van een applicatie te scheiden, het voornaamste voorbeeld hiervan is het MVC (Model-View-Controller) model. De details hiervan laat ik even achterwegen (Wikipedia is your friend) maar kort gezegd krijg je door dit model te implementeren een applicatie waarin de bussiness logic, het ophalen van data uit de bussiness logic en het tonen daarvan van elkaar gescheiden zijn.

Bovenstaande kan gerealiseerd worden door in bijvoorbeeld een servlet de bussiness logic (via EJB o.i.d.) aan te spreken en het resultaat te delegeren naar JSP's die gevuld worden met deze data. Echter is dit model op deze manier ook niet perfect. In een website met omvangrijke grootte kan het schrijven van dergelijke code redundant en onoverzichtelijk worden. Je voelt het misschien al aankomen, maar inderdaad, ze hebben ook hier iets op gevonden. Een techniek (eigenlijk een design-pattern) met een vrij algemene naam "frontcontroller". Frontcontrollers zijn kleine frameworkjes die je kunt gebruiken om de code die je in je controllerlaag gebruikt om de bussiness logic aan te spreken evenals de code die je gebruikt om de view-laag aan te spreken in herbruikbare objecten te stoppen. Op die manier hoef je code om requests af te handelen niet steeds opnieuw te schrijven voor elke servlet die je in je applicatie gebruikt. Dit leidt al gauw tot meer overzicht in de code die makkelijker onderhoudbaar is. Een belangrijke kenmerk van een frontcontroller is dat het een centraal punt vormt in een applicatie voor het ontvangen van requests en het delegeren daarvan.

Een keerpunt van een dergelijke techniek is dat je al je logica zult moeten implementeren in de frontcontroller, wat tot heel wat configuratie en omslachtigheid kan leiden. Bijvoorbeeld het delegeren van een bepaald request naar een bepaalde servlet kun je dan niet even snel met een RequestDispatcher doen, maar je zult een object moeten schrijven dat de configuratie en logica voor die delegatie bevat. Op die manier is het gebruik van een frontcontroller aan de ene kant een zegen en aan de andere kant een vloek. Zoals een bekende voetballer ooit zei (ja, Kruijff): elk noadeel heb een foordeel!

Een bekende Java implementatie van een frontcontroller is Jakarta Struts, wat niet bij iedereen geliefd is. Dit geldt echter ook voor Spring, wat minder bekend is maar ook gebruikt wordt in de webwereld om je controller en view netjes neer te zetten. Spring heeft echter ook roots in de modellaag, eigenlijk een frontcontroller++ :P. Beide technieken implementeren het frontcontroller pattern op hun eigen manier, en je wilt ermee werken of niet. Mij persoonlijk lijkt het gebruik van Struts wel interessant, en misschien zelfs wel nuttig. Echter denk ik niet dat je het moet gebruiken in websites van kleine omvang omdat je dan waarschijnlijk niet het potentieel eruit haalt.

woensdag 24 oktober 2007

Tutorial: Custom Taglib in JSP (Deel 3)


Welkom bij deel drie van de taglib tutorial. In dit deel nemen we een kijkje naar tags met een body.

Tot nu toe zijn alle tags in deze tutorial leeg geweest, dit is te herkennen aan het feit dat er maar één tag is die wordt afgesloten met een “/”. Kijken we echter naar HTML zijn de meeste tags niet leeg. Dit willen we met onze eigen taglib natuurlijk ook kunnen. De tag in dit deel van de tutorial gaat verder op de “Hello World” tags uit deel 1 en 2. Alleen printen we in dit deel de tekst “Hello World” in een stuk HTML code. De tag ziet er als volgt uit:

<tutorial:helloBody>
<p class=”cssClass” id=”helloWorld”>$_tekst</p>
</tutorial:helloBody>

Je ziet dat onze tag een begin-tag en een eind-tag, met daartussen HTML code. Ook is je misschien de tekst “$_tekst” gezien, op deze plaats wordt onze “Hello World” geplaatst. Aangezien dit gewoon via de replace() methode van String gaat had hier net zo goed iets anders kunnen staan, zolang we het maar netjes kunnen vervangen.

Om deze tag te kunnen verwerken zullen we hem eerst in onze taglib description moeten zetten. Dit gaat op dezelfde manier als onze allereerste tag, met een kleine wijziging.

<tag>
<name>helloBody</name>
<tag-class>nl.mysite.tags.HelloBodyTag</tag-class>
<body-content>JSP</body-content>
</tag>

In de bovenstaande code zie je de tag zoals deze wordt toegevoegd aan de taglib description. Zoals je ziet is deze inderdaad vrijwel identiek aan de code uit de eerste tutorial, echter waar eerder de waarde “empty” aan body-content werd meegegeven wordt nu de waarde “JSP” meegegeven. Dit betekend simpelweg dat de tag geen empty body heeft maar een body met daarin JSP code.

In onze tag handler zitten ook een aantal wijzigingen om de body van de tag te kunnen benaderen. Het eerste verschil is dat onze tag-handler geen subklasse is van javax.servlet.jsp.tagext.TagSupport maar van javax.servlet.jsp.tagext.BodyTagSupport. Ook hierin kun je dezelfde methoden overriden als normaal, maar je hebt er de methode getBodyContent() bij. Deze methode geeft een BodyContent object terug waarin de body staat.

In ons voorbeeld willen we de body ophalen een string (“$_tekst”) vervangen door “Hello World”. Dit doen we op de onderstaande manier:

BodyContent body = getBodyContent();
JspWriter out = body.getEnclosingWriter();
String data = body.getString();
data = data.replaceAll("\\$_tekst", "Hello World");
out.println(data);
body.clearBody();

In de eerste twee regels wordt de body en de JspWriter waarmee de body wordt geschreven opgehaald. De code in de body wordt in regel 3 in een string geplaats en in regel 4 gewijzigd. Daarna wordt de tekst geprint en de body wordt leeggemaakt.

donderdag 4 oktober 2007

Tutorial: Custom TagLib in JSP (Deel 2)


Het tweede deel van onze tutorial gaat over het maken van een custom tag met parameters. Wanneer je deel één van de tutorial hebt gemist en je afvraagt waar ik het over heb, klik dan hier om eerst het eerste deel te lezen voor je verder leest.

In het voorbeeld van deel één deden we niet meer dan de tekst “Hello World” afdrukken. Dit gaan we in dit deel uitbreiden met een parameter. Onze tag gaat er op de volgende manier uitzien:

<tutorial:helloworld name="Isaac Newton" />

En deze tag drukt de tekst “Hello [name]” af, in het bovenstaande voorbeeld wordt dus “Hello Isaac Newton” afgedrukt. Hiervoor moeten we de taglib description uitbreiden op de onderstaande manier.


<tag>
<name>helloworld</name>
<tag-class>nl.mysite.tags.HelloWorldTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>yes</required>
</attribute>
</tag>


De tag “attribute” wordt toegevoegd. Hieronder bevinden zich een aantal andere tags: “name” en “required”. Beide spreken voor zich, in “name” staat de naam van de parameter en in “required” staat of de parameter vereist is of niet. In dit laatste geval zal de tag handler een default waarde moeten bevatten. Daarnaast kunnen ook nog een tweetal tags voorkomen die we in dit voorbeeld niet nodig hebben: “rtexprvalue”, die aangeeft dat de return-type van expressies die de parameter doorgeven van een bepaald type moeten zijn of alles mag zijn (kan de waarden “true” of “false” bevatten) en de tag “type” wordt gebruikt om dit type aan te geven.

Na het aanpassen van onze taglib description kunnen we onze class file erbij pakken. Hieronder zie je dezelfde code als in de vorige tutorial, maar dan met de aanpassingen erin.


package nl.directa.tags;
import java.io.IOException;
import javax.servlet.jsp.tagext.TagSupport;

public class HelloWorldTag extends TagSupport {
private String name;

public int doEndTag() {
try {
pageContext.getOut().println("Hello "+name);
} catch (IOException ignored) { }
return EVAL_PAGE;
}

public void setName(String name) {
this.name = name;
}
}


Zo simpel is het! Je voegt een globale variabele toe en een set methode (let op de naamgeving volgens JavaBean conventies met de naam van de parameter erin verwerkt). In onze doEndTag methode gebruiken we de parameter om “Hello [name]” te printen.

Daarmee komen we aan het einde van het tweede deel in de custom taglib tutorial. In het volgende deel maken we een tag met een body, dat wordt lachen.

maandag 1 oktober 2007

Tutorial: Custom TagLib in JSP (Deel 1)


Dit is het eerste deel in een serie tutorials over het maken van een eigen tag library (taglib) in JSP. In dit eerste deel zal ik de basis van custom taglibs bespreken en hoe je een “Hello World” tag maakt. Na dit deel volgen in de komende dagen / weken nog vier delen in deze serie zodat alles over taglibs aan bod kan komen. Hou het blog dus in de gaten.

JSP tags en custom tags zorgen ervoor dat je de scriplet code in je JSP bestanden weg kunt laten (de code tussen <% %>). In plaats daarvan plaats je een tag die verwijst naar een stuk JAVA code in je backend. Dit zorgt voor een overzichtelijker JSP bestand. Het verminderd, namelijk, het “Spaghetti code” probleem dat je vaak tegenkomt in webapplicaties en maakt je code stukken leesbaarder.

Een taglib bestaat uit een aantal onderdelen. Allereerst wordt de code van de tag geplaatst in een tag-handler, een java klasse die erft van javax.servlet.jsp.tagext.TagSupport. Daarnaast wordt een beschrijving van de tag in een .tld bestand geplaatst, de tag library descriptor. Dit is een XML bestand die in de WEB-INF map geplaatst wordt. Uiteindelijk wordt in de web.xml de taglib gekoppeld aan een URL zodat de tags benaderbaar zijn in je applicatie.

Een “Hello World” tag maken

Voor onze “Hello World” beginnen we met het beschrijven van de tag in de tag library descriptor. In de WEB-INF map maken we een submap “/tlds” met daarin onze descriptor file “helloworld.tld”. Hieronder zie je de code die we in “helloworld.tld” plaatsen.

Helloworld.tld


<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library
1.2/EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>helloworld</short-name>
<uri>http://www.mysite.com/taglibs/helloworld</uri>

<tag>
<name&rt;helloworld</name>
<tag-class>nl.mysite.tags.HelloWorldTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>



In de bovenstaande code zie je op de eerste twee regels wat standaard XML code staan die je waarschijnlijk wel gewend bent van andere XML bestanden, er wordt verwezen naar de taglibrary dtd van Sun. Daarna wordt een “taglib” element gemaakt met daarin een paar standaard gegevens “tlib-version” (de versie van deze taglib) en “jsp-version” (de versie van de jsp taglib beschrijving). Bedenk voor de “short-name” een logische naam voor de taglib en maak ook van de “uri” een logische url. Onder deze header worden de tags geplaatst. In dit voorbeeld wordt een heel eenvoudige tag aan gemaakt. Hierin staat een naam (“name”), de Java klasse waarin de code voor de tag te vinden is (“tag-class”) en of de tag een body heeft (“body-content”).

Hierna openen we de web.xml en voegen het onderstaande toe in <web-app>.

<taglib>
<taglib-uri>http://www.mysite.com/taglibs/helloworld</taglib-uri>
<taglib-location>/WEB-INF/tlds/helloworld.tld</taglib-location>
</taglib>



Dit geeft aan waar de taglib te vinden is. Uiteindelijk moet er ook nog een implementatie komen. Hiervoor maken we een nieuwe klasse aan nl.mysite.tags.HelloWorldTag. Hieronder vind je de code van deze JAVA file.


package nl.directa.tags;
import java.io.IOException;
import javax.servlet.jsp.tagext.TagSupport;

public class HelloWorldTag extends TagSupport {
public int doEndTag() {
try {
pageContext.getOut().println("Hello World");
} catch (IOException ignored) { }
return EVAL_PAGE;
}
}



Zoals je kunt zien in onze HelloWorldTag klasse een subklasse van TagSupport. De methode doEndTag() wordt uitgevoerd op het moment dat de endtag van onze tag is bereikt en schrijft de tekst “Hello World” naar het scherm. Dit gebeurt via het object “pageContext”. Dit object kun je gebruiken om je JSP pagina te bereiken en kun je o.a. gebruiken om “out” te gebruiken, om het request object op te halen of om pagina’s te includen. In het voorbeeld wordt de JspWriter van de pagina opgehaald en hierin wordt een tekst geprint. De methode geeft een int terug, in dit geval “EVAL_PAGE”. Dit is een constante van TagSupport die aangeeft dat de rest van de pagina kan worden geëvalueerd. Natuurlijk zijn er nog meer mogelijke constante die teruggegeven kunnen worden, deze worden in de volgende delen belicht.

In je JSP bestand kun je de nieuwe tag pas gebruiken als je de taglib hebt toegevoegd aan de pagina met de onderstaande code.

<%@ taglib prefix="tutorial" uri="http://www.mysite.com/taglibs/helloworld" %>

Vervolgens kun je de tag op de onderstaande manier gebruiken.

<tutorial:helloworld />

Daarmee is het eerste deel van onze tutorial ten einde, in deel twee gaan we kijken hoe we ons "Hello World" voorbeeld interessanter kunnen maken.

woensdag 29 augustus 2007

UTF-8

Het is niet altijd vanzelfsprekend dat gegevens probleemloos van punt a naar punt b komen. Dit is iets dat me de afgelopen paar dagen maar al te duidelijk is geworden. Het idee is heel simpel, op een JSP pagina heb je een formulier die gegevens post naar een tweede JSP pagina. In eerste instantie lijkt alles goed te gaan, totdat je vreemde karakters gaat invoeren. Een "Ÿ" in het formulier kwam op de tweede jsp pagina aan als een "Ǻ¸". Misschien zijn het karakters die niet veel gebruikt worden, maar je wilt toch dat alle karakters goed aankomen.

Een zoektocht naar het antwoord op het internet leverde een aantal mogelijke oplossingen. Allereerst kun je met JSP aangeven dat de data in UTF-8 is. Dit kun je doen met de onderstaande code:

&amp;amp;amp;lt;%@ page pageEncoding="UTF-8" %&amp;amp;amp;gt;
Werkt ook dat niet, dan kun je zelfs aangeven dat je HttpServletRequest object (het object dat de ingevulde gegevens uit het formulier bevat) in UTF-8 is. Hieronder een voorbeeld hiervan:
request.setCharacterEncoding("UTF-8");
Bij mij werkte dit allemaal niet en dus waren harde maatregelen nodig. De code hieronder is bedoeld als de bovenstaande codes niet werken. Hierbij ga ik er even van uit dat je JSP pagina's in ISO_8859_1 encoding zijn, maar in principe werkt dit vanuit alle, door JAVA ondersteunde, encodings.
new String((MyString).getBytes("8859_1"), "UTF-8");
Wat gebeurt hier? Met de methode getBytes("8859_1") maak je van je String object een array van Bytes gecodeerd in de opgegeven encoding. Dit is in dit geval ISO_8859_1. Met deze array maak je een nieuw String object in de UTF-8 encoding.

Het resultaat is dat een "Ÿ" ook daadwerkelijk een "Ÿ" blijft.